---
 software/libfpvm/unique.c |  108 ++++++++++++++------------------------------
 1 files changed, 35 insertions(+), 73 deletions(-)

diff --git a/software/libfpvm/unique.c b/software/libfpvm/unique.c
index 28365a5..c571f6d 100644
--- a/software/libfpvm/unique.c
+++ b/software/libfpvm/unique.c
@@ -19,6 +19,11 @@
 #define        INITIAL_ALLOC   64
 
 
+struct key_n {
+       const char *s;
+       int n;
+};
+
 const char *well_known[] = {
 #include "fnp.inc"
 };
@@ -44,123 +49,80 @@ static int strcmp_n(const char *a, const char *b, int n)
 }
 
 
-/* We don't have bsearch, so here's our own version. */
-
-static const char *search(const char *s)
+static char *strdup_n(const char *s, int n)
 {
-       int low = 0;
-       int high = sizeof(well_known)/sizeof(*well_known)-1;
-       int mid, res;
-
-       while(low <= high) {
-               mid = (low+high)/2;
-               res = strcmp(s, well_known[mid]);
-               if(!res)
-                       return well_known[mid];
-               if(res < 0)
-                       high = mid-1;
-               else
-                       low = mid+1;
-       }
-       return NULL;
-}
-
+       char *new;
 
-static const char *search_n(const char *s, int n)
-{
-       int low = 0;
-       int high = sizeof(well_known)/sizeof(*well_known)-1;
-       int mid, res;
-
-       while(low <= high) {
-               mid = (low+high)/2;
-               res = strcmp_n(s, well_known[mid], n);
-               if(!res)
-                       return well_known[mid];
-               if(res < 0)
-                       high = mid-1;
-               else
-                       low = mid+1;
-       }
-       return NULL;
+       new = malloc(n+1);
+       memcpy(new, s, n);
+       new[n] = 0;
+       return new;
 }
 
 
-/* We don't have strdup either. */
-
-static char *my_strdup(const char *s)
+static void grow_table(void)
 {
-       size_t len;
-       char *new;
+       if(num_vars != allocated)
+               return;
 
-       len = strlen(s)+1;
-       new = malloc(len);
-       memcpy(new, s, len);
-       return new;
+       allocated = allocated ? allocated*2 : INITIAL_ALLOC;
+       vars = realloc(vars, allocated*sizeof(*vars));
 }
 
 
-static char *my_strdup_n(const char *s, int n)
+static int cmp(const void *a, const void *b)
 {
-       char *new;
-
-       new = malloc(n+1);
-       memcpy(new, s, n);
-       new[n] = 0;
-       return new;
+       return strcmp(a, *(const char **) b);
 }
 
 
-static void grow_table(void)
+static int cmp_n(const void *a, const void *b)
 {
-       int allocate;
-       const char **new;
-
-       if(num_vars != allocated)
-               return;
+       const struct key_n *key = a;
 
-       /* There's no realloc, so we roll our own.  */
-       allocate = allocated ? allocated*2 : INITIAL_ALLOC;
-       new = malloc(allocate*sizeof(*vars));
-       memcpy(new, vars, allocated*sizeof(*vars));
-       vars = new;
-       allocated = allocate;
+       return strcmp_n(key->s, *(const char **) b, key->n);
 }
 
 
 const char *unique(const char *s)
 {
-       const char *res;
+       const char **res;
        const char **walk;
 
        if(!isalnum(*s) && *s != '_')
                return s;
-       res = search(s);
+       res = bsearch(s, well_known, sizeof(well_known)/sizeof(*well_known),
+           sizeof(s), cmp);
        if(res)
-               return res;
+               return *res;
        for(walk = vars; walk != vars+num_vars; walk++)
                if(!strcmp(*walk, s))
                        return *walk;
        grow_table();
-       return vars[num_vars++] = my_strdup(s);
+       return vars[num_vars++] = strdup(s);
 }
 
 
 const char *unique_n(const char *s, int n)
 {
-       const char *res;
+       struct key_n key = {
+               .s = s,
+               .n = n,
+       };
+       const char **res;
        const char **walk;
 
        if(!isalnum(*s) && *s != '_')
                return s;
-       res = search_n(s, n);
+       res = bsearch(&key, well_known, sizeof(well_known)/sizeof(*well_known),
+           sizeof(s), cmp_n);
        if(res)
-               return res;
+               return *res;
        for(walk = vars; walk != vars+num_vars; walk++)
                if(!strcmp_n(s, *walk, n))
                        return *walk;
        grow_table();
-       return vars[num_vars++] = my_strdup_n(s, n);
+       return vars[num_vars++] = strdup_n(s, n);
 }
 
 
-- 
1.7.1

_______________________________________________
http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org
IRC: #milkymist@Freenode

Reply via email to