diff --git a/bin/tests/sym_test.c b/bin/tests/sym_test.c index d8912feb34..0a39cb1973 100644 --- a/bin/tests/sym_test.c +++ b/bin/tests/sym_test.c @@ -45,12 +45,9 @@ main(int argc, char *argv[]) { int trace = 0; int c; isc_symexists_t exists_policy = isc_symexists_reject; + isc_boolean_t case_sensitive = ISC_FALSE; - INSIST(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); - INSIST(isc_symtab_create(mctx, 691, undefine_action, &st) == - ISC_R_SUCCESS); - - while ((c = getopt(argc, argv, "tar")) != -1) { + while ((c = getopt(argc, argv, "tarc")) != -1) { switch (c) { case 't': trace = 1; @@ -61,9 +58,16 @@ main(int argc, char *argv[]) { case 'r': exists_policy = isc_symexists_replace; break; + case 'c': + case_sensitive = ISC_TRUE; + break; } } + INSIST(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); + INSIST(isc_symtab_create(mctx, 691, undefine_action, case_sensitive, + &st) == ISC_R_SUCCESS); + while (gets(s) != NULL) { len = strlen(s); diff --git a/lib/isc/include/isc/symtab.h b/lib/isc/include/isc/symtab.h index 3d86099c80..c4c8cd71cc 100644 --- a/lib/isc/include/isc/symtab.h +++ b/lib/isc/include/isc/symtab.h @@ -104,6 +104,7 @@ typedef struct isc_symtab isc_symtab_t; isc_result_t isc_symtab_create(isc_mem_t *mctx, unsigned int size, isc_symtabaction_t undefine_action, + isc_boolean_t case_sensitive, isc_symtab_t **symtabp); void diff --git a/lib/isc/symtab.c b/lib/isc/symtab.c index 0559eb8ea2..4b7319ae2d 100644 --- a/lib/isc/symtab.c +++ b/lib/isc/symtab.c @@ -47,11 +47,13 @@ struct isc_symtab { unsigned int size; eltlist_t * table; isc_symtabaction_t undefine_action; + isc_boolean_t case_sensitive; }; isc_result_t isc_symtab_create(isc_mem_t *mctx, unsigned int size, isc_symtabaction_t undefine_action, + isc_boolean_t case_sensitive, isc_symtab_t **symtabp) { isc_symtab_t *symtab; @@ -75,6 +77,7 @@ isc_symtab_create(isc_mem_t *mctx, unsigned int size, symtab->mctx = mctx; symtab->size = size; symtab->undefine_action = undefine_action; + symtab->case_sensitive = case_sensitive; symtab->magic = SYMTAB_MAGIC; *symtabp = symtab; @@ -111,7 +114,7 @@ isc_symtab_destroy(isc_symtab_t **symtabp) { } static inline unsigned int -hash(const char *key) { +hash(const char *key, isc_boolean_t case_sensitive) { const char *s; unsigned int h = 0; unsigned int g; @@ -123,14 +126,24 @@ hash(const char *key) { * and Ullman, Addison-Wesley, 1986, ISBN 0-201-10088-6. */ - for (s = key; *s != '\0'; s++) { - c = *s; - if (isascii(c) && isupper(c)) - c = tolower(c); - h = ( h << 4 ) + c; - if ((g = ( h & 0xf0000000 )) != 0) { - h = h ^ (g >> 24); - h = h ^ g; + if (case_sensitive) { + for (s = key; *s != '\0'; s++) { + h = ( h << 4 ) + *s; + if ((g = ( h & 0xf0000000 )) != 0) { + h = h ^ (g >> 24); + h = h ^ g; + } + } + } else { + for (s = key; *s != '\0'; s++) { + c = *s; + if (isascii(c) && isupper(c)) + c = tolower(c); + h = ( h << 4 ) + c; + if ((g = ( h & 0xf0000000 )) != 0) { + h = h ^ (g >> 24); + h = h ^ g; + } } } @@ -138,11 +151,19 @@ hash(const char *key) { } #define FIND(s, k, t, b, e) \ - b = hash((k)) % (s)->size; \ - for (e = HEAD((s)->table[b]); e != NULL; e = NEXT(e, link)) { \ - if (((t) == 0 || e->type == (t)) && \ - strcasecmp(e->key, (k)) == 0) \ - break; \ + b = hash((k), (s)->case_sensitive) % (s)->size; \ + if ((s)->case_sensitive) { \ + for (e = HEAD((s)->table[b]); e != NULL; e = NEXT(e, link)) { \ + if (((t) == 0 || e->type == (t)) && \ + strcmp(e->key, (k)) == 0) \ + break; \ + } \ + } else { \ + for (e = HEAD((s)->table[b]); e != NULL; e = NEXT(e, link)) { \ + if (((t) == 0 || e->type == (t)) && \ + strcasecmp(e->key, (k)) == 0) \ + break; \ + } \ } isc_result_t