From 7fa020a6e6a7807bbc810576cbf4fcea56c98d44 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 20 Dec 2003 00:25:23 +0000 Subject: [PATCH] Fri Dec 19 15:54:45 2003 Ben Pfaff * 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 | 9 +++++++++ src/algorithm.c | 39 +++++++++++++++++++++++++++++++++++++++ src/algorithm.h | 7 +++++++ src/expr-prs.c | 17 ++++++++++++----- 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 59746a79..c6e60018 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +Fri Dec 19 15:54:45 2003 Ben Pfaff + + * 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 * descript.q: (display) Use sort() algorithm instead of qsort(). diff --git a/src/algorithm.c b/src/algorithm.c index fed221e1..ac7f28df 100644 --- a/src/algorithm.c +++ b/src/algorithm.c @@ -71,6 +71,8 @@ */ #include +#include +#include #include #include #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); } +/* 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; +} + /* 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). diff --git a/src/algorithm.h b/src/algorithm.h index d6d098b7..2c897bda 100644 --- a/src/algorithm.h +++ b/src/algorithm.h @@ -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 */ diff --git a/src/expr-prs.c b/src/expr-prs.c index 1a040202..3d597395 100644 --- a/src/expr-prs.c +++ b/src/expr-prs.c @@ -22,6 +22,7 @@ #include #include #include +#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); } /* Debug output. */ -- 2.30.2