Browse Source

Resolve PTYPEs in clish_shell_prepare

Serj Kalichev 9 years ago
parent
commit
dab0504e8d
6 changed files with 58 additions and 24 deletions
  1. 4 1
      clish/param.h
  2. 27 6
      clish/param/param.c
  3. 1 0
      clish/param/private.h
  4. 1 1
      clish/shell/shell_new.c
  5. 19 1
      clish/shell/shell_startup.c
  6. 6 15
      clish/shell/shell_xml.c

+ 4 - 1
clish/param.h

@@ -50,7 +50,7 @@ typedef enum {
  * meta functions
  *----------------- */
 clish_param_t *clish_param_new(const char *name,
-	const char *text, clish_ptype_t *ptype);
+	const char *text, const char *ptype_name);
 /*-----------------
  * methods
  *----------------- */
@@ -63,11 +63,14 @@ void clish_param_insert_param(clish_param_t * instance, clish_param_t * param);
 /*-----------------
  * attributes
  *----------------- */
+void clish_param__set_ptype_name(clish_param_t *instance, const char *ptype_name);
+const char * clish_param__get_ptype_name(const clish_param_t *instance);
 const char *clish_param__get_name(const clish_param_t * instance);
 const char *clish_param__get_text(const clish_param_t * instance);
 const char *clish_param__get_range(const clish_param_t * instance);
 const char *clish_param__get_default(const clish_param_t * instance);
 clish_ptype_t *clish_param__get_ptype(const clish_param_t * instance);
+void clish_param__set_ptype(clish_param_t *instance, clish_ptype_t *ptype);
 void clish_param__set_default(clish_param_t * instance, const char *defval);
 void clish_param__set_mode(clish_param_t * instance, clish_param_mode_e mode);
 clish_param_mode_e clish_param__get_mode(const clish_param_t * instance);

+ 27 - 6
clish/param/param.c

@@ -16,14 +16,14 @@
  * PRIVATE METHODS
  *--------------------------------------------------------- */
 static void clish_param_init(clish_param_t *this, const char *name,
-	const char *text, clish_ptype_t *ptype)
+	const char *text, const char *ptype_name)
 {
-	/* initialise the help part */
 	this->name = lub_string_dup(name);
 	this->text = lub_string_dup(text);
-	this->ptype = ptype;
+	this->ptype_name = lub_string_dup(ptype_name);
 
-	/* set up defaults */
+	/* Set up defaults */
+	this->ptype = NULL;
 	this->defval = NULL;
 	this->mode = CLISH_PARAM_COMMON;
 	this->optional = BOOL_FALSE;
@@ -44,6 +44,7 @@ static void clish_param_fini(clish_param_t * this)
 	lub_string_free(this->defval);
 	lub_string_free(this->name);
 	lub_string_free(this->text);
+	lub_string_free(this->ptype_name);
 	lub_string_free(this->value);
 	lub_string_free(this->test);
 	lub_string_free(this->completion);
@@ -56,12 +57,12 @@ static void clish_param_fini(clish_param_t * this)
  * PUBLIC META FUNCTIONS
  *--------------------------------------------------------- */
 clish_param_t *clish_param_new(const char *name, const char *text,
-	clish_ptype_t *ptype)
+	const char *ptype_name)
 {
 	clish_param_t *this = malloc(sizeof(clish_param_t));
 
 	if (this)
-		clish_param_init(this, name, text, ptype);
+		clish_param_init(this, name, text, ptype_name);
 	return this;
 }
 
@@ -83,6 +84,20 @@ void clish_param_insert_param(clish_param_t * this, clish_param_t * param)
 /*---------------------------------------------------------
  * PUBLIC ATTRIBUTES
  *--------------------------------------------------------- */
+void clish_param__set_ptype_name(clish_param_t *this, const char *ptype_name)
+{
+	if (this->ptype_name)
+		lub_string_free(this->ptype_name);
+	this->ptype_name = lub_string_dup(ptype_name);
+}
+
+/*--------------------------------------------------------- */
+const char * clish_param__get_ptype_name(const clish_param_t *this)
+{
+	return this->ptype_name;
+}
+
+/*--------------------------------------------------------- */
 const char *clish_param__get_name(const clish_param_t * this)
 {
 	if (!this)
@@ -108,6 +123,12 @@ clish_ptype_t *clish_param__get_ptype(const clish_param_t * this)
 	return this->ptype;
 }
 
+/*--------------------------------------------------------- */
+void clish_param__set_ptype(clish_param_t *this, clish_ptype_t *ptype)
+{
+	this->ptype = ptype;
+}
+
 /*--------------------------------------------------------- */
 void clish_param__set_default(clish_param_t * this, const char *defval)
 {

+ 1 - 0
clish/param/private.h

@@ -16,6 +16,7 @@ struct clish_param_s {
 	char *name;
 	char *text;
 	char *value;
+	char *ptype_name;	/* Name of PTYPE */
 	clish_ptype_t *ptype;	/* The type of this parameter */
 	char *defval;		/* default value to use for this parameter */
 	clish_paramv_t *paramv;

+ 1 - 1
clish/shell/shell_new.c

@@ -80,7 +80,7 @@ static void clish_shell_init(clish_shell_t * this,
 	/* Create internal ptypes and params */
 	/* Args */
 	tmp_ptype = clish_shell_find_create_ptype(this,
-		"internal_ARGS",
+		"__ptype_ARGS",
 		"Arguments", "[^\\\\]+",
 		CLISH_PTYPE_REGEXP,
 		CLISH_PTYPE_NONE);

+ 19 - 1
clish/shell/shell_startup.c

@@ -88,7 +88,20 @@ static int iterate_paramv(clish_shell_t *this, clish_paramv_t *paramv,
 
 	while((param = clish_paramv__get_param(paramv, i))) {
 		clish_paramv_t *nested_paramv;
+		clish_ptype_t *ptype = NULL;
 
+		/* Resolve PARAM's PTYPE */
+		ptype = clish_shell_find_ptype(this, clish_param__get_ptype_name(param));
+		if (!ptype) {
+			fprintf(stderr, "Error: Unresolved PTYPE \"%s\" in PARAM \"%s\"\n",
+				clish_param__get_ptype_name(param),
+				clish_param__get_name(param));
+				return -1;
+		}
+		clish_param__set_ptype(param, ptype);
+		clish_param__set_ptype_name(param, NULL); /* Free some memory */
+
+		/* Check access for PARAM */
 		if (access_fn && clish_param__get_access(param) &&
 			access_fn(this, clish_param__get_access(param))) {
 #ifdef DEBUG
@@ -102,6 +115,7 @@ static int iterate_paramv(clish_shell_t *this, clish_paramv_t *paramv,
 			clish_param_delete(param);
 			continue; /* Don't increment index */
 		}
+		/* Recursive iterate nested PARAMs */
 		nested_paramv = clish_param__get_paramv(param);
 		if (iterate_paramv(this, nested_paramv, access_fn) < 0)
 			return -1;
@@ -213,8 +227,10 @@ int clish_shell_prepare(clish_shell_t *this)
 		cmd = lub_bintree_findfirst(cmd_tree);
 		for (lub_bintree_iterator_init(&cmd_iter, cmd_tree, cmd);
 			cmd; cmd = lub_bintree_iterator_next(&cmd_iter)) {
+			int cmd_is_alias = clish_command__get_alias(cmd)?1:0;
+
 			/* Resolve command aliases */
-			if (clish_command__get_alias(cmd)) {
+			if (cmd_is_alias) {
 				clish_view_t *aview;
 				clish_command_t *cmdref;
 				const char *alias_view = clish_command__get_alias_view(cmd);
@@ -251,6 +267,8 @@ int clish_shell_prepare(clish_shell_t *this)
 				clish_command_delete(cmd);
 				continue;
 			}
+			if (cmd_is_alias) /* Don't duplicate paramv processing for aliases */
+				continue;
 			paramv = clish_command__get_paramv(cmd);
 			if (iterate_paramv(this, paramv, access_fn) < 0)
 				return -1;

+ 6 - 15
clish/shell/shell_xml.c

@@ -263,7 +263,7 @@ static int process_clish_module(clish_shell_t *shell, clish_xmlnode_t *element,
 	/* Create the global view */
 	if (!shell->global)
 		shell->global = clish_shell_find_create_view(shell,
-			"__global", "");
+			"__view_global", "");
 
 	parent = parent; /* Happy compiler */
 
@@ -477,16 +477,13 @@ static int process_command(clish_shell_t *shell, clish_xmlnode_t *element,
 	if (args_name) {
 		/* define a "rest of line" argument */
 		clish_param_t *param;
-		clish_ptype_t *tmp = NULL;
 
 		/* Check syntax */
 		if (!args_help) {
 			fprintf(stderr, CLISH_XML_ERROR_ATTR("args_help"));
 			goto error;
 		}
-		tmp = clish_shell_find_ptype(shell, "internal_ARGS");
-		assert(tmp);
-		param = clish_param_new(args_name, args_help, tmp);
+		param = clish_param_new(args_name, args_help, "__ptype_ARGS");
 		clish_command__set_args(cmd, param);
 	}
 
@@ -645,7 +642,6 @@ static int process_param(clish_shell_t *shell, clish_xmlnode_t *element,
 		char *completion = clish_xmlnode_fetch_attr(element, "completion");
 		char *access = clish_xmlnode_fetch_attr(element, "access");
 		clish_param_t *param;
-		clish_ptype_t *tmp = NULL;
 
 		/* Check syntax */
 		if (cmd && (cmd == shell->startup)) {
@@ -665,22 +661,17 @@ static int process_param(clish_shell_t *shell, clish_xmlnode_t *element,
 			goto error;
 		}
 
-		if (*ptype) {
-			tmp = clish_shell_find_create_ptype(shell, ptype,
-				NULL, NULL,
-				CLISH_PTYPE_REGEXP,
-				CLISH_PTYPE_NONE);
-		}
-		param = clish_param_new(name, help, tmp);
+		param = clish_param_new(name, help, ptype);
 
 		/* If prefix is set clish will emulate old optional
 		 * command syntax over newer optional command mechanism.
 		 * It will create nested PARAM.
 		 */
 		if (prefix) {
-			const char *ptype_name = "__SUBCOMMAND";
+			const char *ptype_name = "__ptype_SUBCOMMAND";
 			clish_param_t *opt_param = NULL;
 			char *str = NULL;
+			clish_ptype_t *tmp;
 
 			/* Create a ptype for prefix-named subcommand that
 			 * will contain the nested optional parameter. The
@@ -696,7 +687,7 @@ static int process_param(clish_shell_t *shell, clish_xmlnode_t *element,
 			assert(tmp);
 			lub_string_cat(&str, "_prefix_");
 			lub_string_cat(&str, name);
-			opt_param = clish_param_new(str, help, tmp);
+			opt_param = clish_param_new(str, help, ptype_name);
 			lub_string_free(str);
 			clish_param__set_mode(opt_param,
 				CLISH_PARAM_SUBCOMMAND);