Browse Source

Fix command alias resolving

Serj Kalichev 9 years ago
parent
commit
9cacac2579
5 changed files with 49 additions and 50 deletions
  1. 3 3
      clish/command.h
  2. 13 12
      clish/command/command.c
  3. 1 1
      clish/command/private.h
  4. 26 4
      clish/shell/shell_startup.c
  5. 6 30
      clish/shell/shell_xml.c

+ 3 - 3
clish/command.h

@@ -24,7 +24,7 @@ typedef struct clish_command_s clish_command_t;
 clish_command_t *clish_command_new(const char *name, const char *help);
 clish_command_t *clish_command_new_link(const char *name,
 	const char *help, const clish_command_t * ref);
-clish_command_t * clish_command_alias_to_link(clish_command_t * instance);
+clish_command_t * clish_command_alias_to_link(clish_command_t *instance, clish_command_t *ref);
 
 int clish_command_bt_compare(const void *clientnode, const void *clientkey);
 void clish_command_bt_getkey(const void *clientnode, lub_bintree_key_t * key);
@@ -81,8 +81,8 @@ void clish_command__set_lock(clish_command_t * instance, bool_t lock);
 void clish_command__set_alias(clish_command_t * instance, const char * alias);
 const char * clish_command__get_alias(const clish_command_t * instance);
 void clish_command__set_alias_view(clish_command_t * instance,
-	clish_view_t * alias_view);
-clish_view_t * clish_command__get_alias_view(const clish_command_t * instance);
+	const char *alias_view);
+const char * clish_command__get_alias_view(const clish_command_t * instance);
 void clish_command__set_dynamic(clish_command_t * instance, bool_t dynamic);
 bool_t clish_command__get_dynamic(const clish_command_t * instance);
 bool_t clish_command__get_interrupt(const clish_command_t * instance);

+ 13 - 12
clish/command/command.c

@@ -62,6 +62,7 @@ static void clish_command_fini(clish_command_t * this)
 	clish_action_delete(this->action);
 	clish_config_delete(this->config);
 	lub_string_free(this->alias);
+	lub_string_free(this->alias_view);
 	lub_string_free(this->viewname);
 	lub_string_free(this->viewid);
 	lub_string_free(this->detail);
@@ -134,16 +135,13 @@ clish_command_t *clish_command_new_link(const char *name,
 }
 
 /*--------------------------------------------------------- */
-clish_command_t * clish_command_alias_to_link(clish_command_t * this)
+clish_command_t * clish_command_alias_to_link(clish_command_t *this, clish_command_t *ref)
 {
-	clish_command_t * ref;
 	clish_command_t tmp;
 
-	if (!this || !this->alias)
-		return this;
-	assert(this->alias_view);
-	ref = clish_view_find_command(this->alias_view, this->alias, BOOL_FALSE);
-	if (!ref)
+	if (!this || !ref)
+		return NULL;
+	if (ref->alias) /* The reference is a link too */
 		return NULL;
 	memcpy(&tmp, this, sizeof(tmp));
 	*this = *ref;
@@ -414,7 +412,8 @@ void clish_command__set_lock(clish_command_t * this, bool_t lock)
 /*--------------------------------------------------------- */
 void clish_command__set_alias(clish_command_t * this, const char * alias)
 {
-	assert(!this->alias);
+	if (this->alias)
+		lub_string_free(this->alias);
 	this->alias = lub_string_dup(alias);
 }
 
@@ -425,14 +424,16 @@ const char * clish_command__get_alias(const clish_command_t * this)
 }
 
 /*--------------------------------------------------------- */
-void clish_command__set_alias_view(clish_command_t * this,
-	clish_view_t * alias_view)
+void clish_command__set_alias_view(clish_command_t *this,
+	const char *alias_view)
 {
-	this->alias_view = alias_view;
+	if (this->alias_view)
+		lub_string_free(this->alias_view);
+	this->alias_view = lub_string_dup(alias_view);
 }
 
 /*--------------------------------------------------------- */
-clish_view_t * clish_command__get_alias_view(const clish_command_t * this)
+const char * clish_command__get_alias_view(const clish_command_t * this)
 {
 	return this->alias_view;
 }

+ 1 - 1
clish/command/private.h

@@ -22,7 +22,7 @@ struct clish_command_s {
 	char *access;
 	clish_param_t *args;
 	const struct clish_command_s *link;
-	clish_view_t *alias_view;
+	char *alias_view;
 	char *alias;
 	clish_view_t *pview;
 	bool_t lock;

+ 26 - 4
clish/shell/shell_startup.c

@@ -156,6 +156,7 @@ int clish_shell_prepare(clish_shell_t *this)
 				continue;
 			}
 			clish_nspace__set_view(nspace, ref_view);
+			clish_nspace__set_view_name(nspace, NULL); /* Free some memory */
 			/* Check access rights for the NAMESPACE */
 			if (access_fn && clish_nspace__get_access(nspace) &&
 				access_fn(this, clish_nspace__get_access(nspace))) {
@@ -174,10 +175,31 @@ int clish_shell_prepare(clish_shell_t *this)
 		for (lub_bintree_iterator_init(&cmd_iter, cmd_tree, cmd);
 			cmd; cmd = lub_bintree_iterator_next(&cmd_iter)) {
 			/* Resolve command aliases */
-			if (!clish_command_alias_to_link(cmd)) {
-				fprintf(stderr, CLISH_XML_ERROR_STR"Broken alias %s\n",
-					clish_command__get_name(cmd));
-				return -1;
+			if (clish_command__get_alias(cmd)) {
+				clish_view_t *aview;
+				clish_command_t *cmdref;
+				const char *alias_view = clish_command__get_alias_view(cmd);
+				if (!alias_view)
+					aview = clish_command__get_pview(cmd);
+				else
+					aview = clish_shell_find_view(this, alias_view);
+				if (!aview) {
+					fprintf(stderr, CLISH_XML_ERROR_STR"Broken VIEW for alias %s\n",
+						clish_command__get_name(cmd));
+					return -1;
+				}
+				cmdref = clish_view_find_command(aview,
+					clish_command__get_alias(cmd), BOOL_FALSE);
+				if (!cmdref) {
+					fprintf(stderr, CLISH_XML_ERROR_STR"Broken alias %s\n",
+						clish_command__get_name(cmd));
+					return -1;
+				}
+				if (!clish_command_alias_to_link(cmd, cmdref)) {
+					fprintf(stderr, CLISH_XML_ERROR_STR"Something wrong with alias %s\n",
+						clish_command__get_name(cmd));
+					return -1;
+				}
 			}
 			/* Check access rights for the COMMAND */
 			if (access_fn && clish_command__get_access(cmd) &&

+ 6 - 30
clish/shell/shell_xml.c

@@ -415,8 +415,6 @@ static int process_command(clish_shell_t *shell, clish_xmlnode_t *element,
 	clish_view_t *v = (clish_view_t *) parent;
 	clish_command_t *cmd = NULL;
 	clish_command_t *old;
-	char *alias_name = NULL;
-	clish_view_t *alias_view = NULL;
 	int res = -1;
 
 	char *access = clish_xmlnode_fetch_attr(element, "access");
@@ -448,6 +446,10 @@ static int process_command(clish_shell_t *shell, clish_xmlnode_t *element,
 		goto error;
 	}
 
+	/* create a command */
+	cmd = clish_view_new_command(v, name, help);
+	clish_command__set_pview(cmd, v);
+
 	/* Reference 'ref' field */
 	if (ref) {
 		char *saveptr = NULL;
@@ -462,20 +464,12 @@ static int process_command(clish_shell_t *shell, clish_xmlnode_t *element,
 			lub_string_free(str);
 			goto error;
 		}
-		alias_name = lub_string_dup(cmdn);
+		clish_command__set_alias(cmd, cmdn); /* alias name */
 		view_name = strtok_r(NULL, delim, &saveptr);
-		if (!view_name)
-			alias_view = v;
-		else
-			alias_view = clish_shell_find_create_view(shell,
-				view_name, NULL);
+		clish_command__set_alias_view(cmd, view_name);
 		lub_string_free(str);
 	}
 
-	/* create a command */
-	cmd = clish_view_new_command(v, name, help);
-	clish_command__set_pview(cmd, v);
-
 	/* define some specialist escape characters */
 	if (escape_chars)
 		clish_command__set_escape_chars(cmd, escape_chars);
@@ -521,24 +515,6 @@ static int process_command(clish_shell_t *shell, clish_xmlnode_t *element,
 	if (access)
 		clish_command__set_access(cmd, access);
 
-	/* Set alias */
-	if (alias_name) {
-		/* Check syntax */
-		if (!alias_view) {
-			fprintf(stderr, CLISH_XML_ERROR_STR"Can't find reference VIEW.\n");
-			lub_string_free(alias_name);
-			goto error;
-		}
-		if ((alias_view == v) && (!strcmp(alias_name, name))) {
-			fprintf(stderr, CLISH_XML_ERROR_STR"The COMMAND with reference to itself.\n");
-			lub_string_free(alias_name);
-			goto error;
-		}
-		clish_command__set_alias(cmd, alias_name);
-		clish_command__set_alias_view(cmd, alias_view);
-		lub_string_free(alias_name);
-	}
-
 //process_command_end:
 	res = process_children(shell, element, cmd);
 error: