Fri Dec 19 15:54:45 2003 Ben Pfaff <blp@gnu.org>
authorBen Pfaff <blp@gnu.org>
Sat, 20 Dec 2003 00:25:23 +0000 (00:25 +0000)
committerBen Pfaff <blp@gnu.org>
Sat, 20 Dec 2003 00:25:23 +0000 (00:25 +0000)
* expr-prs.c: (cmp_func) Removed.
(parse_function) Use binary_search() algorithm.
(compare_functions) New function.
(init_func_tab) Use sort() algorithm.

* algorithm.c: (binary_search) New algorithm.

src/ChangeLog
src/algorithm.c
src/algorithm.h
src/expr-prs.c

index 59746a79abe558c47613121582b2fa031215e4ae..c6e600181c6d69da88e1c989b44f3080f57ed557 100644 (file)
@@ -1,3 +1,12 @@
+Fri Dec 19 15:54:45 2003  Ben Pfaff  <blp@gnu.org>
+
+       * expr-prs.c: (cmp_func) Removed.
+       (parse_function) Use binary_search() algorithm.
+       (compare_functions) New function.
+       (init_func_tab) Use sort() algorithm.
+
+       * algorithm.c: (binary_search) New algorithm.
+
 Fri Dec 19 15:50:45 2003  Ben Pfaff  <blp@gnu.org>
 
        * descript.q: (display) Use sort() algorithm instead of qsort().
index fed221e1adce9f0767c1fd73d0e4ebb9944b7ea1..ac7f28dfea850da9c092d0b2e50be1e8af3d2b70 100644 (file)
@@ -71,6 +71,8 @@
  */
 
 #include <config.h>
+#include <assert.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 #include "alloc.h"
@@ -324,6 +326,43 @@ remove_copy_if (const void *array, size_t count, size_t size,
   return copy_if (array, count, size, result, not, &pred_aux);
 }
 \f
+/* Searches ARRAY, which contains COUNT of SIZE bytes each, using
+   a binary search.  Returns any element that equals VALUE, if
+   one exists, or a null pointer otherwise.  ARRAY must ordered
+   according to COMPARE.  AUX is passed to COMPARE as auxiliary
+   data. */
+void *
+binary_search (const void *array, size_t count, size_t size,
+               void *value,
+               algo_compare_func *compare, void *aux) 
+{
+  assert (array != NULL);
+  assert (count <= INT_MAX);
+  assert (aux != NULL);
+
+  if (count != 0) 
+    {
+      const unsigned char *first = array;
+      int low = 0;
+      int high = count - 1;
+
+      while (low < high) 
+        {
+          int middle = (low + high) / 2;
+          const unsigned char *element = first + middle * size;
+          int cmp = compare (value, element, aux);
+
+          if (cmp > 0) 
+            low = middle + 1;
+          else if (cmp < 0)
+            high = middle - 1;
+          else
+            return (void *) element;
+        }
+    }
+  return NULL;
+}
+\f
 /* Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
index d6d098b7595ddf8e088ab797e9bff91d67e1e592..2c897bda5d3cb5d8780bdf5429f7b16b59746aa8 100644 (file)
@@ -65,4 +65,11 @@ size_t remove_copy_if (const void *array, size_t count, size_t size,
                        void *result,
                        algo_predicate_func *predicate, void *aux);
 
+/* Searches ARRAY, which contains COUNT of SIZE bytes each, for
+   VALUE, using a binary search.  ARRAY must ordered according to
+   COMPARE.  AUX is passed to COMPARE as auxiliary data. */
+void *binary_search (const void *array, size_t count, size_t size,
+                     void *value,
+                     algo_compare_func *compare, void *aux);
+
 #endif /* sort-algo.h */
index 1a0402026266a6996095530c8569c78630227c9c..3d5973950695d22aa553442ee4396988b09d9f7f 100644 (file)
@@ -22,6 +22,7 @@
 #include <ctype.h>
 #include <float.h>
 #include <stdlib.h>
+#include "algorithm.h"
 #include "alloc.h"
 #include "error.h"
 #include "expr.h"
@@ -57,8 +58,8 @@ static union any_node *append_nonterminal_arg (union any_node *,
                                               union any_node *);
 static int type_check (union any_node **n, int type, int flags);
 
+static algo_compare_func compare_functions;
 static void init_func_tab (void);
-static int cmp_func (const void *a, const void *b);
 
 #if DEBUGGING
 static void debug_print_tree (union any_node *, int);
@@ -1275,7 +1276,8 @@ parse_function (union any_node ** n)
     struct function f;
     f.s = fname;
     
-    fp = bsearch (&f, func_tab, func_count, sizeof *func_tab, cmp_func);
+    fp = binary_search (func_tab, func_count, sizeof *func_tab, &f,
+                        compare_functions, NULL);
   }
   
   if (!fp)
@@ -1618,10 +1620,15 @@ static struct function func_tab[] =
   {"SUBSTR", OP_SUBSTR, generic_str_func, "ssn/n"},
 };
 
+/* An algo_compare_func that compares functions A and B based on
+   their names. */
 static int
-cmp_func (const void *a, const void *b)
+compare_functions (const void *a_, const void *b_, void *aux unused)
 {
-  return strcmp (*(char **) a, *(char **) b);
+  const struct function *a = a_;
+  const struct function *b = b_;
+
+  return strcmp (a->s, b->s);
 }
 
 static void
@@ -1636,7 +1643,7 @@ init_func_tab (void)
   }
 
   func_count = sizeof func_tab / sizeof *func_tab;
-  qsort (func_tab, func_count, sizeof *func_tab, cmp_func);
+  sort (func_tab, func_count, sizeof *func_tab, compare_functions, NULL);
 }
 \f
 /* Debug output. */