[PATCH] Old completions cleanup, part 1

Replace all instances of find_completion(s) with the appropriate stree based
commands. This allows me to remove lots of the old completion code in
shell.c. The rest to be cleaned up in part 2...

diff -urN a/common/keys.c head/common/keys.c
--- a/common/keys.c	2006-02-25 12:53:02.000000000 +1030
+++ head/common/keys.c	2006-02-25 13:18:05.000000000 +1030
@@ -215,7 +215,7 @@
     int len;
 
     s = GetCommandPos(key_lines[edit_line] + 1);
-    cmd = find_completion(s);
+    cmd = Cmd_CommandComplete(s);
     if (cmd) {
 	key_linepos = s - key_lines[edit_line];
 	if (s == key_lines[edit_line] + 1) {
@@ -224,11 +224,6 @@
 	}
 	strcpy(s, cmd);
 	key_linepos += strlen(cmd);
-
-	/* Inefficient, but it'll do for now */
-	if (find_completions(cmd) == 1)
-	    key_lines[edit_line][key_linepos++] = ' ';
-
 	key_lines[edit_line][key_linepos] = 0;
 	Z_Free(cmd);
     } else {
@@ -261,19 +256,16 @@
 ShowCompletions(void)
 {
     const char *s;
-    unsigned int cnt, i, len, maxlen;
+    struct stree_root *root;
+    unsigned int len;
 
     s = GetCommandPos(key_lines[edit_line] + 1);
-    cnt = find_completions(s);
-    if (cnt) {
-	Con_Printf("%u possible completions:\n", cnt);
-	maxlen = 0;
-	for (i = 0; i < cnt; i++) {
-	    len = strlen(completions_list[i]);
-	    if (len > maxlen)
-		maxlen = len;
-	}
-	Con_ShowList(completions_list, cnt, maxlen);
+
+    root = Cmd_CommandCompletions(s);
+    if (root && root->entries) {
+	Con_Printf("%u possible completions:\n", root->entries);
+	Con_ShowTree(root);
+	Z_Free(root);
     } else {
 	char *cmd = strchr(s, ' ');
 	if (cmd) {
diff -urN a/common/shell.c head/common/shell.c
--- a/common/shell.c	2006-02-25 12:53:02.000000000 +1030
+++ head/common/shell.c	2006-02-25 13:50:13.000000000 +1030
@@ -464,8 +464,6 @@
     STree_ForEach_Cleanup__(in);
 }
 
-const char **completions_list = NULL;
-static int num_completions = 0;
 
 static struct rb_root completions = RB_ROOT;
 
@@ -523,216 +521,20 @@
     }
 }
 
-/*
- * FIXME: when I'm not so tired, I'll make this more efficient...
- */
-static unsigned
-rb_count_completions_r(struct rb_node *n, const char *str, unsigned long type)
-{
-    unsigned cnt = 0;
-
-    if (n) {
-	struct completion *c = completion_entry(n);
-	int cmp = strncasecmp(str, c->string, strlen(str));
-	if (cmp <= 0)
-	    cnt += rb_count_completions_r(n->rb_left, str, type);
-	if (!cmp && (c->cmd_type & type))
-	    cnt++;
-	if (cmp >= 0)
-	    cnt += rb_count_completions_r(n->rb_right, str, type);
-    }
-    return cnt;
-}
-
-static unsigned
-rb_count_completions(struct rb_node *n, const char *str, unsigned long type)
-{
-    /* do the first part iteratively */
-    while (n) {
-	struct completion *c = completion_entry(n);
-	int cmp = strncasecmp(str, c->string, strlen(str));
-	if (cmp < 0)
-	    n = n->rb_left;
-	else if (cmp > 0)
-	    n = n->rb_right;
-	else
-	    break;
-    }
-    return rb_count_completions_r(n, str, type);
-}
-
-static void
-rb_find_completions_r(struct rb_node *n, const char *str, unsigned long type)
-{
-    if (n) {
-	struct completion *c = completion_entry(n);
-	int cmp = strncasecmp(str, c->string, strlen(str));
-	if (cmp <= 0)
-	    rb_find_completions_r(n->rb_left, str, type);
-	if (!cmp && (c->cmd_type & type))
-	    completions_list[num_completions++] = c->string;
-	if (cmp >= 0)
-	    rb_find_completions_r(n->rb_right, str, type);
-    }
-}
-
-static unsigned
-rb_find_completions(const char *str, unsigned long type, struct rb_root *root)
-{
-    struct rb_node *n;
-    unsigned cnt;
-
-    n = root->rb_node;
-    cnt = rb_count_completions(n, str, type);
-
-    if (cnt) {
-	if (completions_list)
-	    free(completions_list);
-
-	completions_list = malloc(cnt * sizeof(char *));
-	num_completions = 0;
-	rb_find_completions_r(n, str, type);
-
-	if (num_completions != cnt)
-	    Con_DPrintf("**** WARNING: rb completions counts don't match!\n");
-    }
-    return cnt;
-}
-
-/*
- * Given the partial string 'str', find all strings in the tree that have
- * this prefix. Return the common prefix of all those strings, which may
- * be longer that the original str.
- *
- * Returned str is allocated on the zone, so caller to Z_Free it after use.
- * If no matches found, return null;
- */
-static char *
-rb_find_completion(const char *str, unsigned long type, struct rb_root *root)
-{
-    int n, i, max_match, len;
-    char *ret;
-
-    n = rb_find_completions(str, type, root);
-    if (!n)
-	return NULL;
-
-    /*
-     * What is the most that could possibly match?
-     * i.e. shortest string in the list
-     */
-    max_match = strlen(completions_list[0]);
-    for (i = 1; i < n; ++i) {
-	len = strlen(completions_list[i]);
-	if (len < max_match)
-	    max_match = len;
-    }
-
-    /*
-     * Check if we can match max_match chars. If not, reduce by one and
-     * try again.
-     */
-    while (max_match > strlen(str)) {
-	for (i = 1; i < n; ++i) {
-	    if (strncasecmp(completions_list[0], completions_list[i],
-			    max_match)) {
-		max_match--;
-		break;
-	    }
-	}
-	if (i == n)
-	    break;
-    }
-
-    ret = Z_Malloc(max_match + 1);
-    strncpy(ret, completions_list[0], max_match);
-    ret[max_match] = '\0';
-
-    return ret;
-}
-
-
-
-
-/* Command completions */
-
 void
 insert_command_completion(const char *str)
 {
     rb_insert_completion(str, CMD_COMMAND, &completions);
 }
 
-unsigned
-find_command_completions(const char *str)
-{
-    return rb_find_completions(str, CMD_COMMAND, &completions);
-}
-
-char *
-find_command_completion(const char *str)
-{
-    return rb_find_completion(str, CMD_COMMAND, &completions);
-}
-
-/* Alias completions */
-
 void
 insert_alias_completion(const char *str)
 {
     rb_insert_completion(str, CMD_ALIAS, &completions);
 }
 
-unsigned
-find_alias_completions(const char *str)
-{
-    return rb_find_completions(str, CMD_ALIAS, &completions);
-}
-
-char *
-find_alias_completion(const char *str)
-{
-    return rb_find_completion(str, CMD_ALIAS, &completions);
-}
-
-/* Cvar completions */
-
 void
 insert_cvar_completion(const char *str)
 {
     rb_insert_completion(str, CMD_CVAR, &completions);
 }
-
-unsigned
-find_cvar_completions(const char *str)
-{
-    return rb_find_completions(str, CMD_CVAR, &completions);
-}
-
-char *
-find_cvar_completion(const char *str)
-{
-    return rb_find_completion(str, CMD_CVAR, &completions);
-}
-
-/* ------------------------------------------------------------------------ */
-
-/*
- * Find all the completions for a string, looking at commands, cvars and
- * aliases.
- */
-unsigned
-find_completions(const char *str)
-{
-    return rb_find_completions(str, CMD_COMMAND | CMD_CVAR | CMD_ALIAS,
-			       &completions);
-}
-
-
-/*
- * For tab completion. Checks cmds, cvars and aliases
- */
-char *find_completion(const char *str)
-{
-    return rb_find_completion(str, CMD_COMMAND | CMD_CVAR | CMD_ALIAS,
-			      &completions);
-}
diff -urN a/include/shell.h head/include/shell.h
--- a/include/shell.h	2006-02-25 12:53:02.000000000 +1030
+++ head/include/shell.h	2006-02-25 13:50:05.000000000 +1030
@@ -142,23 +142,8 @@
 #define CMD_ALIAS	(1UL << 1)
 #define CMD_CVAR	(1UL << 2)
 
-/* search results end up here... FIXME - pretty ugly... */
-extern const char** completions_list;
-
 void insert_alias_completion(const char *str);
-unsigned find_alias_completions(const char *str);
-char *find_alias_completion(const char *str);
-
 void insert_command_completion(const char *str);
-unsigned find_command_completions(const char *str);
-char *find_command_completion(const char *str);
-
 void insert_cvar_completion(const char *str);
-unsigned find_cvar_completions(const char *str);
-char *find_cvar_completion(const char *str);
-
-/* Search all three completion caches combined */
-unsigned find_completions(const char *str);
-char *find_completion(const char *str);
 
 #endif /* SHELL_H */
