Browse Source

Technological revision. Don't use.

git-svn-id: https://klish.googlecode.com/svn/trunk@180 0eaa4687-2ee9-07dd-09d9-bcdd2d2dd5fb
Serj Kalichev 13 years ago
parent
commit
7e5db77e6d

+ 58 - 30
clish/nspace/nspace.c

@@ -28,20 +28,30 @@ static void clish_nspace_init(clish_nspace_t * this, clish_view_t * view)
 	this->context_help = BOOL_FALSE;
 	this->inherit = BOOL_TRUE;
 	this->prefix_cmd = NULL;
-	this->proxy_cmd = NULL;
+
+	/* initialise the tree of commands links for this nspace */
+	lub_bintree_init(&this->tree,
+		 clish_command_bt_offset(),
+		 clish_command_bt_compare, clish_command_bt_getkey);
 }
 
 /*--------------------------------------------------------- */
 static void clish_nspace_fini(clish_nspace_t * this)
 {
+	clish_command_t *cmd;
+
 	/* deallocate the memory for this instance */
 	lub_string_free(this->prefix);
 	this->prefix = NULL;
+	/* delete each command link held by this nspace */
+	while ((cmd = lub_bintree_findfirst(&this->tree))) {
+		/* remove the command from the tree */
+		lub_bintree_remove(&this->tree, cmd);
 
-	if (this->proxy_cmd) {
-		clish_command_delete(this->proxy_cmd);
-		this->proxy_cmd = NULL;
+		/* release the instance */
+		clish_command_delete(cmd);
 	}
+	/* Delete prefix pseudo-command */
 	if (this->prefix_cmd) {
 		clish_command_delete(this->prefix_cmd);
 		this->prefix_cmd = NULL;
@@ -64,29 +74,37 @@ clish_command_t * clish_nspace_create_prefix_cmd(clish_nspace_t * this,
 static clish_command_t *clish_nspace_find_create_command(clish_nspace_t * this,
 	const char *prefix, const clish_command_t * ref)
 {
+	clish_command_t *cmd;
 	char *name = NULL;
 
-	if (this->proxy_cmd) {
-		clish_command_delete(this->proxy_cmd);
-		this->proxy_cmd = NULL;
-	}
-
 	assert(prefix);
 	if (!ref) {
 		assert(this->prefix_cmd);
-		this->proxy_cmd = clish_command_new_link(prefix, this->prefix_cmd);
-		return this->proxy_cmd;
+		name = lub_string_dup(prefix);
+		ref = this->prefix_cmd;
+	} else {
+		lub_string_catn(&name, prefix, strlen(prefix));
+		lub_string_catn(&name, " ", 1);
+		lub_string_catn(&name, clish_command__get_name(ref),
+				strlen(clish_command__get_name(ref)));
 	}
 
-	lub_string_catn(&name, prefix, strlen(prefix));
-	lub_string_catn(&name, " ", 1);
-	lub_string_catn(&name, clish_command__get_name(ref),
-			strlen(clish_command__get_name(ref)));
-
-	this->proxy_cmd = clish_command_new_link(name, ref);
+	/* The command is cached already */
+	if (cmd = lub_bintree_find(&this->tree, name)) {
+		free(name);
+		return cmd;
+	}
+	cmd = clish_command_new_link(name, ref);
 	free(name);
+	assert(cmd);
+
+	/* Insert command link into the tree */
+	if (-1 == lub_bintree_insert(&this->tree, cmd)) {
+		clish_command_delete(cmd);
+		cmd = NULL;
+	}
 
-	return this->proxy_cmd;
+	return cmd;
 }
 
 /*---------------------------------------------------------
@@ -113,7 +131,7 @@ void clish_nspace_delete(clish_nspace_t * this)
 
 /*--------------------------------------------------------- */
 static const char *clish_nspace_after_prefix(const char *prefix,
-	const char *line)
+					     const char *line)
 {
 	const char *in_line = NULL;
 	regex_t regexp;
@@ -131,15 +149,7 @@ static const char *clish_nspace_after_prefix(const char *prefix,
 		return NULL;
 	in_line = line + pmatch[0].rm_eo;
 
-	/* If entered line contain only the prefix */
-	if (in_line[0] == '\0')
-		return NULL;
-
-	/* If prefix is not followed by space */
-	if (in_line[0] != ' ')
-		return NULL;
-
-	return (in_line + 1);
+	return in_line;
 }
 
 /*--------------------------------------------------------- */
@@ -153,10 +163,19 @@ clish_command_t *clish_nspace_find_command(clish_nspace_t * this, const char *na
 	if (!prefix)
 		return clish_view_find_command(view, name, this->inherit);
 
+//printf("FIND: %s\n", name);
 	if (!(in_line = clish_nspace_after_prefix(prefix, name)))
 		return NULL;
 
-	cmd = clish_view_find_command(view, in_line, this->inherit);
+	/* If prefix is followed by space */
+	if (in_line[0] == ' ')
+		in_line++;
+
+	if (in_line[0] != '\0') {
+		cmd = clish_view_find_command(view, in_line, this->inherit);
+		if (!cmd)
+			return NULL;
+	}
 
 	return clish_nspace_find_create_command(this, prefix, cmd);
 }
@@ -174,9 +193,14 @@ const clish_command_t *clish_nspace_find_next_completion(clish_nspace_t * this,
 	if (!prefix)
 		return clish_view_find_next_completion(view, iter_cmd, line, field, this->inherit);
 
+//printf("COMPLETION: %s, %s\n", line, iter_cmd);
 	if (!(in_line = clish_nspace_after_prefix(prefix, line)))
 		return NULL;
 
+	if (in_line[0] != '\0') {
+	/* If prefix is followed by space */
+	if (in_line[0] == ' ')
+		in_line++;
 	if (iter_cmd &&
 	    (lub_string_nocasestr(iter_cmd, prefix) == iter_cmd) &&
 	    (lub_string_nocasecmp(iter_cmd, prefix)))
@@ -184,6 +208,10 @@ const clish_command_t *clish_nspace_find_next_completion(clish_nspace_t * this,
 	cmd = clish_view_find_next_completion(view, in_iter, in_line, field, this->inherit);
 	if (!cmd)
 		return NULL;
+	}
+
+	if (!cmd && iter_cmd && !lub_string_nocasecmp(iter_cmd, prefix))
+		return NULL;
 
 	return clish_nspace_find_create_command(this, prefix, cmd);
 }
@@ -260,7 +288,7 @@ bool_t clish_nspace__get_inherit(const clish_nspace_t * this)
 /*--------------------------------------------------------- */
 bool_t
 clish_nspace__get_visibility(const clish_nspace_t * instance,
-	clish_nspace_visibility_t field)
+			     clish_nspace_visibility_t field)
 {
 	bool_t result = BOOL_FALSE;
 

+ 2 - 2
clish/nspace/private.h

@@ -7,12 +7,12 @@
  * PRIVATE TYPES
  *--------------------------------------------------------- */
 struct clish_nspace_s {
+	lub_bintree_t tree;	/* Tree of command links */
 	clish_view_t *view;	/* The view to import commands from */
 	char *prefix;		/* if non NULL the prefix for imported commands */
-	clish_command_t * prefix_cmd;
-	clish_command_t * proxy_cmd;
 	bool_t help;
 	bool_t completion;
 	bool_t context_help;
 	bool_t inherit;
+	clish_command_t * prefix_cmd;
 };

+ 4 - 5
clish/shell/private.h

@@ -39,7 +39,7 @@ typedef enum {
  * iterate around commands
  */
 typedef struct {
-	char *last_cmd;
+	const char *last_cmd;
 	clish_nspace_visibility_t field;
 } clish_shell_iterator_t;
 
@@ -82,10 +82,9 @@ struct clish_shell_s {
 /**
  * Initialise a command iterator structure
  */
-void clish_shell_iterator_init(clish_shell_iterator_t * iter,
-	clish_nspace_visibility_t field);
-void clish_shell_iterator_fini(clish_shell_iterator_t * iter);
-
+void
+clish_shell_iterator_init(clish_shell_iterator_t * iter,
+			  clish_nspace_visibility_t field);
 
 /**
  * get the next command which is an extension of the specified line 

+ 2 - 14
clish/shell/shell_command_generator.c

@@ -9,20 +9,12 @@
 /*-------------------------------------------------------- */
 void
 clish_shell_iterator_init(clish_shell_iterator_t * iter,
-	clish_nspace_visibility_t field)
+			  clish_nspace_visibility_t field)
 {
 	iter->last_cmd = NULL;
 	iter->field = field;
 }
 
-/*-------------------------------------------------------- */
-void
-clish_shell_iterator_fini(clish_shell_iterator_t * iter)
-{
-	lub_string_free(iter->last_cmd);
-	iter->last_cmd = NULL;
-}
-
 /*-------------------------------------------------------- */
 const clish_command_t *clish_shell_find_next_completion(const clish_shell_t *
 							this, const char *line,
@@ -35,7 +27,6 @@ const clish_command_t *clish_shell_find_next_completion(const clish_shell_t *
 	unsigned view_cnt = clish_view__get_nspace_count(this->view);
 	int i;
 
-
 	/* ask the local view for next command */
 	result = clish_view_find_next_completion(this->view,
 		iter->last_cmd, line, iter->field, BOOL_TRUE);
@@ -46,12 +37,10 @@ const clish_command_t *clish_shell_find_next_completion(const clish_shell_t *
 	if (clish_command_diff(result, cmd) > 0)
 		result = cmd;
 
-	lub_string_free(iter->last_cmd);
 	if (!result)
 		iter->last_cmd = NULL;
 	else
-		iter->last_cmd = lub_string_dup(
-			clish_command__get_name(result));
+		iter->last_cmd = clish_command__get_name(result);
 
 	return result;
 }
@@ -187,7 +176,6 @@ char *clish_shell_word_generator(clish_shell_t * this,
 		/* see whether there is an extended extension */
 		clish_shell_iterator_init(&iter, CLISH_NSPACE_COMPLETION);
 		next = clish_shell_find_next_completion(this, line, &iter);
-		clish_shell_iterator_fini(&iter);
 	}
 	if ((NULL != cmd) && (NULL == next)) {
 		/* this needs to be completed as a parameter */

+ 0 - 3
clish/shell/shell_delete.c

@@ -59,9 +59,6 @@ static void clish_shell_fini(clish_shell_t * this)
 		clish_pargv_delete(this->completion_pargv);
 		this->completion_pargv = NULL;
 	}
-
-	/* free iterator */
-	clish_shell_iterator_fini(&this->iter);
 }
 
 /*--------------------------------------------------------- */

+ 0 - 1
clish/shell/shell_help.c

@@ -92,7 +92,6 @@ void clish_shell_help(clish_shell_t * this, const char *line)
 
 		first_cmd = clish_shell_find_next_completion(this, line, &iter);
 		next_cmd = clish_shell_find_next_completion(this, line, &iter);
-		clish_shell_iterator_fini(&iter);
 	} else {
 		first_cmd = next_cmd = NULL;
 	}

+ 0 - 1
clish/shell/shell_tinyrl.c

@@ -162,7 +162,6 @@ static bool_t clish_shell_tinyrl_key_space(tinyrl_t * this, int key)
 	} else {
 		/* perform word completion */
 		status = clish_shell_tinyrl_complete(this);
-
 		switch (status) {
 		case TINYRL_NO_MATCH:
 		case TINYRL_AMBIGUOUS: