Author: bdonlan
Date: 2005-01-01 01:16:31 -0500 (Sat, 01 Jan 2005)
New Revision: 500

Added:
   trunk/clients/havercurs/trie.c
   trunk/clients/havercurs/trie.h
Modified:
   trunk/
   trunk/clients/havercurs/Makefile.am
   trunk/clients/havercurs/TODO
   trunk/clients/havercurs/cmdline.c
   trunk/clients/havercurs/cmdline.h
Log:
 [EMAIL PROTECTED]:  bdonlan | 2005-01-01T06:16:20.997097Z
 Refactored cmdline into a generic trie structure
 



Property changes on: trunk
___________________________________________________________________
Name: svk:merge
   - 1f59643a-e6e5-0310-bc24-f7d4c744f460:/haver/local/trunk:10267
27e50396-46e3-0310-8b22-ae223a1f35ce:/local:212
edfcd8bd-4ce7-0310-a97e-bb1efd40edf3:/local:238
   + 1f59643a-e6e5-0310-bc24-f7d4c744f460:/haver/local/trunk:10269
27e50396-46e3-0310-8b22-ae223a1f35ce:/local:212
edfcd8bd-4ce7-0310-a97e-bb1efd40edf3:/local:238

Modified: trunk/clients/havercurs/Makefile.am
===================================================================
--- trunk/clients/havercurs/Makefile.am 2005-01-01 05:50:18 UTC (rev 499)
+++ trunk/clients/havercurs/Makefile.am 2005-01-01 06:16:31 UTC (rev 500)
@@ -10,4 +10,5 @@
                                        net.c net.h \
                                        lineio.c lineio.h \
                                        hashtable.c hashtable.h \
-                                       cmdline.c cmdline.h
+                                       cmdline.c cmdline.h \
+                                       trie.c trie.h

Modified: trunk/clients/havercurs/TODO
===================================================================
--- trunk/clients/havercurs/TODO        2005-01-01 05:50:18 UTC (rev 499)
+++ trunk/clients/havercurs/TODO        2005-01-01 06:16:31 UTC (rev 500)
@@ -7,6 +7,7 @@
 * Hash table
 
 Debugging:
+* Generic trie
 * /-command parser
 
 TODO:

Modified: trunk/clients/havercurs/cmdline.c
===================================================================
--- trunk/clients/havercurs/cmdline.c   2005-01-01 05:50:18 UTC (rev 499)
+++ trunk/clients/havercurs/cmdline.c   2005-01-01 06:16:31 UTC (rev 500)
@@ -22,119 +22,21 @@
 #include <string.h>
 #include "cmdline.h"
 #include "mymalloc.h"
+#include "trie.h"
 
-/* These are the only characters recognized in a command.
- * TODO: report illegal characters to higher level code
- */
-static const char trie_chars[] =
-    "[EMAIL PROTECTED]&*()_+\\|/.,<>";
+static trie *root;
 
-#define TRIE_CHARS (sizeof trie_chars - 1)
-    
-typedef struct trie {
-    struct trie *ptrs[TRIE_CHARS];
+typedef struct cmdentry {
     cmdline_handler *handler;
     void *baton;
-    int children; /* number of commands under here - sum of ptrs[]->children,
-                   * plus one if handler is non-null
-                   */
-    struct trie *parent;
-    int depth;
-    char c;
-} trie;
+} cmdentry;
 
-static trie root;
-
-/** trie_trans_char
- *
- * Find the index of a character in trie_chars[]
- *
- * Arguments:
- * char c - chatacter to translate
- *
- * Return value:
- * Index of character, or -1 if not found
- */
-static inline char trie_find_char(char c) {
-    char *p = strchr(trie_chars, c);
-    if (!p)
-        return -1;
-    return p - trie_chars;
-}
-
-/** trie_find_level()
- *
- * Locate the node in the trie corresponding to the specified prefix.
- *
- * Arguments:
- * const char *prefix - prefix to locate
- * int create - nonzero if the node and its parents should be created if
- *              nonexistent
- *
- * Return value:
- * Pointer to trie node if found
- * NULL if not found and create is 0
- * NULL if illegal characters detected
- */
-static trie *trie_find_level(
-        const char *prefix,
-        int create
-        )
-{
-    trie *cur = &root;
-    while (*prefix && cur) {
-        trie *next;
-        int idx = trie_find_char(*prefix);
-        if (idx == -1)
-            return NULL;
-        next = cur->ptrs[idx];
-        if (!next) {
-            int i;
-            if (!create)
-                return NULL;
-            next = mymalloc(sizeof *next);
-            next->handler = NULL;
-            next->baton = NULL;
-            next->parent = cur;
-            next->c = idx;
-            next->depth = cur->depth + 1;
-            for (i = 0; i < TRIE_CHARS; i++)
-                next->ptrs[i] = NULL;
-            cur->ptrs[idx] = next;
-        }
-        cur = next;
-    }
-    return cur;
-}
-
-/** trie_purge
- *
- * Remove and free all children of this node.
- *
- * Arguments:
- * node - the node to act upon
- */
-static void trie_purge(trie *node) {
-    int i;
-    for (i = 0; i < TRIE_CHARS; i++) {
-        if (node->ptrs[i]) {
-            trie_purge(node->ptrs[i]);
-            free(node->ptrs[i]);
-            node->ptrs[i] = NULL;
-        }
-    }
-    if (node->handler)
-        node->children = 1;
-    else
-        node->children = 0;
-}
-
 /** cmdline_init()
  *
  * Initializes the module. Must be called before any other functions in this 
header.
  */
 void cmdline_init(void) {
-    /* NO-OP */
+    root = trie_create();
 }
 
 /** cmdline_free()
@@ -143,9 +45,8 @@
  * before any other functions from this header are called
  */
 void cmdline_free(void) {
-    trie_purge(root);
-    root->handler = NULL;
-    root->children = 0;
+    trie_free(root);
+    root = NULL;
 }
 
 /** cmdline_register()
@@ -167,16 +68,15 @@
                )
 {
     cmdline_handler *old;
-    trie *node = trie_find_level(command, 1);
-    old = node->handler;
-    node->handler = cb;
-    node->baton = baton;
-    if (!old) {
-        while (node) {
-            node->children++;
-            node = node->parent;
-        }
+    struct cmdentry *e = trie_get(root, command);
+    if (e) {
+        old = e->handler;
+    } else {
+        e = mymalloc(sizeof *e);
+        old = NULL;
     }
+    e->handler = cb;
+    e->baton = baton;
     return old;
 }
 
@@ -191,54 +91,17 @@
  * Previous handler or NULL if none
  */
 cmdline_handler *cmdline_unregister(const char *command) {
-    trie *prev = NULL;
-    cmdline_handler *old;
-    trie *targ = trie_lookup(command, 0);
-    if (!targ)
-        return NULL;
-    old = targ->handler;
-    targ->handler = NULL;
-    
-    /* Update children counts up the trie. We keep track of the last node,
-     * and when we transition from zero to nonzero, purge the last node and
-     * free it.
-     */
-    while (targ) {
-        targ->children--;
-        if (last && !last->children && targ->children) {
-            trie_purge(last);
-            targ->ptrs[last->c] = NULL;
-            free(last);
-        }
-        last = targ;
-        targ = targ->parent;
-    }
-    
-    return old;
+    cmdentry *old = trie_delete(root, command);
+    if (old)
+        return old->handler;
+    return NULL;
 }
 
-struct lookup_baton {
+struct process_baton {
     void *baton;
     cmdline_handler *handler;
 };
 
-/** lookup_cb()
- *
- * Callback used by cmdline_lookup() with cmdline_enum()
- */
-static int lookup_cb(
-        void *baton,
-        const char *command,
-        cmdline_handler *handler,
-        void *h_baton
-        )
-{
-    struct lookup_baton *lb = baton;
-    lb->baton = h_baton;
-    lb->handler = handler;
-    return 0;
-}
-
 /** cmdline_lookup()
  *
  * Obtains the handler for a given command
@@ -247,33 +110,43 @@
  * const char *command - name of the command
  * void **baton - pointer to location to place the baton value, or NULL
  *                               to discard
- * int partial  - 1 if partial matching should be attempted
  *
  * Return value:
  * Handler callback, or NULL if none or ambiguous
  */
 cmdline_handler *cmdline_lookup(
                const char *command,
-               void **baton,
-        int partial
+               void **baton
                )
 {
-    struct lookup_baton lb;
-    trie *targ = trie_lookup(command, 0);
-    if (targ) {
+    struct process_baton lb;
+    struct cmdentry *e = trie_get(root, command);
+    if (e) {
         if (baton)
-            *baton = targ->baton;
-        return targ->handler;
+            *baton = e->baton;
+        return e->handler;
     }
-    if (!partial)
-        return NULL;
-    if (1 != cmdline_enum(command, lookup_cb, &lb))
-        return NULL;
-    if (baton)
-        *baton = lb.baton;
-    return lb.handler;
+    return NULL;
 }
 
+/** process_cb()
+ *
+ * Callback used by cmdline_process() with trie_enum()
+ */
+static int process_cb(
+        void *baton,
+        const char *key,
+        void *value
+        )
+{
+    struct cmdentry *e = value;
+    struct process_baton *lb = baton;
+    lb->baton = e->baton;
+    lb->handler = e->handler;
+    return 0;
+}
+
+
 /** cmdline_process()
  *
  * Dispatches a command to its handler, if any.
@@ -290,11 +163,8 @@
  */
 int cmdline_process(const char *cmdline, int partial) {
     char *cmdstr;
-    char *endcmd = cmdline;
-    cmdline_handler *h;
-    void *baton;
-    struct lookup_baton lb;
-    size_t ret;
+    const char *endcmd = cmdline;
+    int ret;
 
     while (*endcmd && strchr(trie_chars, *endcmd))
         endcmd++;
@@ -302,64 +172,43 @@
     memcpy(cmdstr, cmdline, endcmd - cmdline);
     cmdstr[endcmd - cmdline] = '\0';
 
-    h = cmdline_lookup(cmdstr, &baton);
-    if (h) {
+    if (partial) {
+        struct process_baton lb;
+        size_t r;
+        r = trie_enum(root, cmdstr, process_cb, &lb);
+        if (r == 1) {
+            lb.handler(lb.baton, cmdline);
+            ret = 2;
+        } else if (r == 0) {
+            ret = 0;
+        } else {
+            ret = -1;
+        }
+    } else {
+        void *baton;
+        cmdline_handler *h;
+        h = cmdline_lookup(cmdstr, &baton);
         h(baton, cmdline);
-        return 1;
+        ret = 1;
     }
-    if (!partial)
-        return 0;
-    
-    ret = cmdline_enum(cmdstr, lookup_cb, &lb);
-    if (ret == 0)
-        return 0;
-    if (ret != 1)
-        return -1;
-    lb.handler(lb.baton, cmdline);
-    return 2;
+    free(cmdstr);
+    return ret;
 }
 
-/** enum_recurs()
- *
- * Recursively scan the trie node given, returning the count of non-NULL
- * handlers found. Call cb() on each handler found, as long as *cont is
- * nonzero. Sets *cont to the return of cb().
- *
- * Arguments:
- * trie *node - node to start from
- * cmdline_enum_callback *cb - callback to call once a handler is found
- * void *baton - baton to pass to *cb
- * int *cont - flag to terminate searching
- */
-void enum_recurs(
-        trie *node,
-        cmdline_enum_callback *cb,
+struct cmdline_enum_baton {
+    void *baton;
+    cmdline_enum_callback *cb;
+};
+
+static int cmdline_enum_cb(
         void *baton,
-        int *cont
+        const char *key,
+        void *value
         )
 {
-    int i;
-    if (node->handler && *cont) {
-        /* figure out what our name is
-         * XXX: we malloc and free far too often - should use a single buffer
-         */
-        trie *cur = node;
-        char *cmdname = mymalloc(node->depth + 1);
-        cmdname[node->depth] = '\0';
-        while (cur->parent) {
-            cmdname[cur->depth - 1] = trie_chars[cur->c];
-            cur = cur->parent;
-        }
-
-        *cont = cb(baton, cmdname, node->handler, node->baton);
-        free(cmdname);
-    }
-    for (i = 0; i < TRIE_CHARS; i++) {
-        if (!*cont)
-            return;
-        if (node->ptrs[i])
-            enum_recurs(node->ptrs[i], cb, baton, cont);
-    }
+    struct cmdline_enum_baton *b = baton;
+    cmdentry *e = value;
+    return b->cb(b->baton, key, e->handler, e->baton);
 }
 
 /** cmdline_enum()
@@ -380,10 +229,8 @@
         void *baton
         )
 {
-    trie *node = trie_find_level(prefix, 0);
-    int cont = 1;
-    if (!node)
-        return 0;
-    enum_recurs(node, cb, baton, &cont);
-    return node->children;
+    struct cmdline_enum_baton b;
+    b.cb = cb;
+    b.baton = baton;
+    trie_enum(root, prefix, cmdline_enum_cb, &b);
 }

Modified: trunk/clients/havercurs/cmdline.h
===================================================================
--- trunk/clients/havercurs/cmdline.h   2005-01-01 05:50:18 UTC (rev 499)
+++ trunk/clients/havercurs/cmdline.h   2005-01-01 06:16:31 UTC (rev 500)
@@ -105,15 +105,13 @@
  * const char *command - name of the command
  * void **baton - pointer to location to place the baton value, or NULL
  *                               to discard
- * int partial  - 1 if partial matching should be attempted
  *
  * Return value:
  * Handler callback, or NULL if none or ambiguous
  */
 cmdline_handler *cmdline_lookup(
                const char *command,
-               void **baton,
-        int partial
+               void **baton
                );
 
 /** cmdline_process()
@@ -122,7 +120,7 @@
  *
  * Arguments:
  * const char *cmdline - full command line to process
- * int particl         - 1 if partial matching should be attempted
+ * int partial         - 1 if partial matching should be attempted
  *
  * Return value:
  * 2 if command was processed with a partial match
@@ -130,7 +128,7 @@
  * 0 if no handler was found
  * -1 if multiple partial matches were found; no action will be taken
  */
-int cmdline_process(const char *cmdline);
+int cmdline_process(const char *cmdline, int partial);
 
 /** cmdline_enum()
  *

Added: trunk/clients/havercurs/trie.c
===================================================================
--- trunk/clients/havercurs/trie.c      2005-01-01 05:50:18 UTC (rev 499)
+++ trunk/clients/havercurs/trie.c      2005-01-01 06:16:31 UTC (rev 500)
@@ -0,0 +1,335 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104:
+ * trie.c - Functions for manipulating tries
+ * 
+ * Copyright (C) 2004 Bryan Donlan
+ * 
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this module; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "trie.h"
+#include "mymalloc.h"
+
+/** trie_chars
+ *
+ * String containing all allowable characters in trie keys
+ */ 
+/* XXX: do we really need this?
+ * TODO: report illegal characters to higher level code
+ */
+const char trie_chars[] =
+    "[EMAIL PROTECTED]&*()_+\\|/.,<>";
+
+#define TRIE_CHARS (sizeof trie_chars - 1)
+    
+struct trie {
+    struct trie *ptrs[TRIE_CHARS];
+    void *value;
+    int children; /* number of commands under here - sum of ptrs[]->children,
+                   * plus one if present is nonzero
+                   */
+    struct trie *parent;
+    int depth;
+    unsigned char c;
+    char present; /* if this node is used... */
+};
+
+/** trie_trans_char
+ *
+ * Find the index of a character in trie_chars[]
+ *
+ * Arguments:
+ * char c - chatacter to translate
+ *
+ * Return value:
+ * Index of character, or -1 if not found
+ */
+static inline char trie_find_char(char c) {
+    char *p = strchr(trie_chars, c);
+    if (!p)
+        return -1;
+    return p - trie_chars;
+}
+
+/** trie_find_level()
+ *
+ * Locate the node in the trie corresponding to the specified prefix.
+ *
+ * Arguments:
+ * trie *root - root to search from
+ * const char *prefix - prefix to locate
+ * int create - nonzero if the node and its parents should be created if
+ *              nonexistent
+ *
+ * Return value:
+ * Pointer to trie node if found
+ * NULL if not found and create is 0
+ * NULL if illegal characters detected
+ */
+static trie *trie_find_level(
+        trie *root,
+        const char *prefix,
+        int create
+        )
+{
+    trie *cur = root;
+    while (*prefix && cur) {
+        trie *next;
+        int idx = trie_find_char(*prefix);
+        if (idx == -1)
+            return NULL;
+        next = cur->ptrs[idx];
+        if (!next) {
+            int i;
+            if (!create)
+                return NULL;
+            next = mymalloc(sizeof *next);
+            next->parent = cur;
+            next->c = idx;
+            next->present = 0;
+            next->depth = cur->depth + 1;
+            for (i = 0; i < TRIE_CHARS; i++)
+                next->ptrs[i] = NULL;
+            cur->ptrs[idx] = next;
+        }
+        cur = next;
+    }
+    return cur;
+}
+
+/** trie_purge
+ *
+ * Remove and free all children of this node.
+ *
+ * Arguments:
+ * node - the node to act upon
+ */
+static void trie_purge(trie *node) {
+    int i, cdelta;
+    for (i = 0; i < TRIE_CHARS; i++) {
+        if (node->ptrs[i]) {
+            trie_purge(node->ptrs[i]);
+            free(node->ptrs[i]);
+            node->ptrs[i] = NULL;
+        }
+    }
+    cdelta = node->children;
+    if (node->present)
+        node->children = 1;
+    else
+        node->children = 0;
+    cdelta -= node->children;
+    node = node->parent;
+    while (node) {
+        node->children -= cdelta;
+        node = node->parent;
+    }   
+}
+
+/** trie_init()
+ *
+ * Creates a trie.
+ *
+ * Return value:
+ * The newly created trie.
+ */
+trie *trie_create(void) {
+    int i;
+    trie *t = mymalloc(sizeof *t);
+    t->parent = NULL;
+    t->present = 0;
+    for (i = 0; i < TRIE_CHARS; i++)
+        t->ptrs[i] = NULL;
+    t->depth = 0;
+    return t;
+}
+
+/** trie_free()
+ *
+ * Destroys a trie.
+ *
+ * Arguments:
+ * t - the trie to destroy
+ */
+void trie_free(trie *t) {
+    trie_purge(t);
+    free(t);
+}
+
+/** trie_put()
+ *
+ * Adds an item to the trie
+ *
+ * Arguments:
+ * trie *t - the trie to insert under
+ * const char *key - key to add under
+ * void *value - value to insert
+ *
+ * Return value:
+ * Previous value or NULL if none
+ */
+void *trie_put(
+        trie *t,
+               const char *key,
+        void *value
+               )
+{
+    void *old;
+    trie *node = trie_find_level(t, key, 1);
+    old = node->value;
+    node->value = value;
+    if (!node->present) {
+        trie *cur = node;
+        while (cur) {
+            cur->children++;
+            cur = cur->parent;
+        }
+        node->present = 1;
+        return NULL;
+    }
+    return old;
+}
+
+/** trie_get()
+ *
+ * Gets the value corresponding to a given key
+ *
+ * Arguments:
+ * trie *t - trie to search
+ * const char *key - key to get
+ * 
+ * Return value:
+ * Value, or NULL if not found
+ */
+void *trie_get(
+        trie *t,
+        const char *key
+               )
+{
+    trie *node = trie_find_level(t, key, 0);
+    if (!node || !node->present)
+        return NULL;
+    return node->value;
+}
+
+/** trie_delete()
+ *
+ * Deletes a key from the trie
+ *
+ * Arguments:
+ * trie *t - the trie to delete from
+ * const char *key - key to delete
+ *
+ * Return value:
+ * Previous value or NULL if none
+ */
+void *trie_delete(trie *t, const char *key) {
+    trie *last = NULL;
+    void *old;
+    trie *targ = trie_find_level(t, key, 0);
+    if (!targ || !targ->present)
+        return NULL;
+    old = targ->value;
+    targ->present = 0;
+    
+    /* Update children counts up the trie. We keep track of the last node,
+     * and when we transition from zero to nonzero, purge the last node and
+     * free it.
+     */
+    while (targ) {
+        targ->children--;
+        if (last && !last->children && targ->children) {
+            trie_purge(last);
+            targ->ptrs[last->c] = NULL;
+            free(last);
+        }
+        last = targ;
+        targ = targ->parent;
+    }
+    
+    return old;
+}
+
+/** enum_recurs()
+ *
+ * Recursively scan the trie node given, returning the count of non-NULL
+ * handlers found. Call cb() on each handler found, as long as *cont is
+ * nonzero. Sets *cont to the return of cb().
+ *
+ * Arguments:
+ * trie *node - node to start from
+ * trie_enum_callback *cb - callback to call once a handler is found
+ * void *baton - baton to pass to *cb
+ * int *cont - flag to terminate searching
+ */
+void enum_recurs(
+        trie *node,
+        trie_enum_callback *cb,
+        void *baton,
+        int *cont
+        )
+{
+    int i;
+    if (node->present && *cont) {
+        /* figure out what our key is
+         * XXX: we malloc and free far too often - should use a single buffer
+         */
+        trie *cur = node;
+        char *key = mymalloc(node->depth + 1);
+        key[node->depth] = '\0';
+        while (cur->parent) {
+            key[cur->depth - 1] = trie_chars[cur->c];
+            cur = cur->parent;
+        }
+
+        *cont = cb(baton, key, node->value);
+        free(key);
+    }
+    for (i = 0; i < TRIE_CHARS; i++) {
+        if (!*cont)
+            return;
+        if (node->ptrs[i])
+            enum_recurs(node->ptrs[i], cb, baton, cont);
+    }
+}
+
+/** trie_enum()
+ *
+ * Obtain a complete listing of partial matches for a key prefix
+ *
+ * Arguments:
+ * trie *t - trie to search
+ * const char *prefix - the prefix to search for
+ * trie_enum_callback *cb - callback to call on each match
+ * void *baton - baton to pass to callback
+ *
+ * Return value:
+ * Total number of matches (regardless of whether cb() returns 0)
+ */
+size_t trie_enum(
+        trie *t,
+        const char *prefix,
+        trie_enum_callback *cb,
+        void *baton
+        )
+{
+    trie *node = trie_find_level(t, prefix, 0);
+    int cont = 1;
+    if (!node)
+        return 0;
+    enum_recurs(node, cb, baton, &cont);
+    return node->children;
+}


Property changes on: trunk/clients/havercurs/trie.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/clients/havercurs/trie.h
===================================================================
--- trunk/clients/havercurs/trie.h      2005-01-01 05:50:18 UTC (rev 499)
+++ trunk/clients/havercurs/trie.h      2005-01-01 06:16:31 UTC (rev 500)
@@ -0,0 +1,138 @@
+/* vim: set ts=4 sw=4 expandtab si ai sta tw=104:
+ * trie.h - Functions for manipulating tries
+ * 
+ * Copyright (C) 2004 Bryan Donlan
+ * 
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this module; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef TRIE_H
+#define TRIE_H 1
+
+#include <stdlib.h>
+
+/** trie_enum_callback
+ *
+ * Callback for trie_enum().
+ *
+ * Arguments:
+ * void *baton - baton passed to trie_enum()
+ * const char *key - key of item found
+ * void *value - value of item found
+ * 
+ * Return value:
+ * 0 to terminate search
+ * Any other value to continue
+ */
+typedef int trie_enum_callback(
+        void *baton,
+        const char *key,
+        void *value
+        );
+
+typedef struct trie trie;
+
+/** trie_chars
+ *
+ * String containing all allowable characters in trie keys
+ */
+extern const char trie_chars[];
+
+/** trie_init()
+ *
+ * Creates a trie.
+ *
+ * Return value:
+ * The newly created trie.
+ */
+trie *trie_create(void);
+
+/** trie_free()
+ *
+ * Destroys a trie.
+ *
+ * Arguments:
+ * t - the trie to destroy
+ */
+void trie_free(trie *t);
+
+/** trie_put()
+ *
+ * Adds an item to the trie
+ *
+ * Arguments:
+ * trie *t - the trie to insert under
+ * const char *key - key to add under
+ * void *value - value to insert
+ *
+ * Return value:
+ * Previous value or NULL if none
+ */
+void *trie_put(
+        trie *t,
+               const char *command,
+               void *value
+               );
+
+/** trie_delete()
+ *
+ * Deletes a key from the trie
+ *
+ * Arguments:
+ * trie *t - the trie to delete from
+ * const char *key - key to delete
+ *
+ * Return value:
+ * Previous value or NULL if none
+ */
+void *trie_delete(trie *t, const char *key);
+
+/** trie_get()
+ *
+ * Gets the value corresponding to a given key
+ *
+ * Arguments:
+ * trie *t - trie to search
+ * const char *key - key to get
+ * 
+ * Return value:
+ * Value, or NULL if not found
+ */
+void *trie_get(
+        trie *t,
+        const char *key
+               );
+
+/** trie_enum()
+ *
+ * Obtain a complete listing of partial matches for a key prefix
+ *
+ * Arguments:
+ * trie *t - trie to search
+ * const char *prefix - the prefix to search for
+ * trie_enum_callback *cb - callback to call on each match
+ * void *baton - baton to pass to callback
+ *
+ * Return value:
+ * Total number of matches (regardless of whether cb() returns 0)
+ */
+size_t trie_enum(
+        trie *t,
+        const char *prefix,
+        trie_enum_callback *cb,
+        void *baton
+        );
+
+#endif


Property changes on: trunk/clients/havercurs/trie.h
___________________________________________________________________
Name: svn:eol-style
   + native


Reply via email to