[PATCH] Con_ShowTree

Introduce a new function Con_ShowTree. This behaves like Con_ShowList,
only it takes an string tree instead of an array as it's input. The
implementation actually makes use of ShowList, with a little
re-factoring.

diff -urN b/common/console.c head/common/console.c
--- b/common/console.c	2005-12-27 15:17:35.000000000 +1030
+++ head/common/console.c	2006-02-08 17:24:49.000000000 +1030
@@ -19,6 +19,8 @@
 */
 // console.c
 
+#include <string.h>
+
 #include "client.h"
 #include "cmd.h"
 #include "console.h"
@@ -698,22 +700,15 @@
 }
 
 void
-Con_ShowList(const char **list, int cnt)
+Con_ShowList(const char **list, int cnt, int maxlen)
 {
     const char *s;
-    unsigned i, j, max_len, len, cols, rows;
+    unsigned i, j, len, cols, rows;
     char *line;
 
     /* Lay them out in columns */
-    max_len = 0;
-    for (i = 0; i < cnt; ++i) {
-	len = strlen(list[i]);
-	if (len > max_len)
-	    max_len = len;
-    }
-
     line = Z_Malloc(Con_GetWidth() + 1);
-    cols = Con_GetWidth() / (max_len + 2);
+    cols = Con_GetWidth() / (maxlen + 2);
     rows = cnt / cols + 1;
 
     /* Looks better if we have a few rows before spreading out */
@@ -732,7 +727,7 @@
 
 	    strcat(line, s);
 	    if (j < cols - 1) {
-		while (len < max_len) {
+		while (len < maxlen) {
 		    strcat(line, " ");
 		    len++;
 		}
@@ -743,3 +738,33 @@
     }
     Z_Free(line);
 }
+
+static const char **showtree_list;
+static unsigned showtree_idx;
+
+static void
+Con_ShowTree_Populate(struct rb_node *n)
+{
+    if (n) {
+	struct rb_string_node *sn;
+
+	Con_ShowTree_Populate(n->rb_left);
+
+	sn = rb_entry(n, struct rb_string_node, node);
+	showtree_list[showtree_idx++] = sn->string;
+
+	Con_ShowTree_Populate(n->rb_right);
+    }
+}
+
+void Con_ShowTree(struct rb_string_root *root)
+{
+    /* FIXME - cheating with malloc */
+    showtree_list = malloc(root->entries * sizeof(char *));
+    if (showtree_list) {
+	showtree_idx = 0;
+	Con_ShowTree_Populate(root->root.rb_node);
+	Con_ShowList(showtree_list, root->entries, root->maxlen);
+	free(showtree_list);
+    }
+}
diff -urN b/common/keys.c head/common/keys.c
--- b/common/keys.c	2005-12-27 15:17:35.000000000 +1030
+++ head/common/keys.c	2006-01-21 22:02:20.000000000 +1030
@@ -212,7 +212,7 @@
 ShowCompletions(void)
 {
     const char *s;
-    unsigned cnt;
+    unsigned int cnt, i, len, maxlen;
 
     s = key_lines[edit_line] + 1;
     if (*s == '\\' || *s == '/')
@@ -221,7 +221,13 @@
     cnt = find_completions(s);
     if (cnt) {
 	Con_Printf("%u possible completions:\n", cnt);
-	Con_ShowList(completions_list, 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);
     }
 }
 
diff -urN b/include/console.h head/include/console.h
--- b/include/console.h	2004-07-25 16:00:01.000000000 +0930
+++ head/include/console.h	2006-01-21 22:00:29.000000000 +1030
@@ -54,6 +54,7 @@
 void Con_DrawNotify(void);
 void Con_ClearNotify(void);
 void Con_ToggleConsole_f(void);
+void Con_ShowList(const char **list, int cnt, int maxlen);
 
 // during startup for sound / cd warnings
 void Con_NotifyBox(char *text);
