From 95bcf47ff9b8073faea99ea9bd65a7119ea4ee41 Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Sat, 19 Dec 1998 00:13:59 +0000 Subject: [PATCH] exists policy --- bin/tests/sym_test.c | 18 ++++++++++++++---- lib/isc/symtab.c | 28 ++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/bin/tests/sym_test.c b/bin/tests/sym_test.c index 36f039c114..fca2a2258e 100644 --- a/bin/tests/sym_test.c +++ b/bin/tests/sym_test.c @@ -15,6 +15,8 @@ * SOFTWARE. */ +#include + #include #include #include @@ -41,7 +43,7 @@ mem_strdup(isc_mem_t *mctx, const char *s) { static void undefine_action(char *key, unsigned int type, isc_symvalue_t value) { - INSIST(type == 0); + INSIST(type == 1); isc_mem_free(mctx, key); isc_mem_free(mctx, value.as_pointer); } @@ -54,16 +56,23 @@ main(int argc, char *argv[]) { isc_symvalue_t value; int trace = 0; int c; + isc_symexists_t exists_policy = isc_symexists_reject; 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, "t")) != -1) { + while ((c = getopt(argc, argv, "tar")) != -1) { switch (c) { case 't': trace = 1; break; + case 'a': + exists_policy = isc_symexists_add; + break; + case 'r': + exists_policy = isc_symexists_replace; + break; } } @@ -74,7 +83,7 @@ main(int argc, char *argv[]) { if (cp[0] == '!') { cp++; - result = isc_symtab_undefine(st, cp, 0); + result = isc_symtab_undefine(st, cp, 1); if (trace || result != ISC_R_SUCCESS) printf("undefine('%s'): %s\n", cp, isc_result_totext(result)); @@ -97,7 +106,8 @@ main(int argc, char *argv[]) { *cp++ = '\0'; key = mem_strdup(mctx, key); value.as_pointer = mem_strdup(mctx, cp); - result = isc_symtab_define(st, key, 0, value); + result = isc_symtab_define(st, key, 1, value, + exists_policy); if (trace || result != ISC_R_SUCCESS) printf("define('%s', '%s'): %s\n", key, cp, diff --git a/lib/isc/symtab.c b/lib/isc/symtab.c index 6c6188cbba..45297411c5 100644 --- a/lib/isc/symtab.c +++ b/lib/isc/symtab.c @@ -168,7 +168,7 @@ isc_symtab_lookup(isc_symtab_t *symtab, const char *key, unsigned int type, isc_result_t isc_symtab_define(isc_symtab_t *symtab, char *key, unsigned int type, - isc_symvalue_t value) + isc_symvalue_t value, isc_symexists_t exists_policy) { unsigned int bucket; elt_t *elt; @@ -178,17 +178,29 @@ isc_symtab_define(isc_symtab_t *symtab, char *key, unsigned int type, FIND(symtab, key, type, bucket, elt); - if (elt != NULL) - return (ISC_R_EXISTS); - - elt = (elt_t *)isc_mem_get(symtab->mctx, sizeof *elt); - if (elt == NULL) - return (ISC_R_NOMEMORY); + if (exists_policy != isc_symexists_add && elt != NULL) { + if (exists_policy == isc_symexists_reject) + return (ISC_R_EXISTS); + INSIST(exists_policy == isc_symexists_replace); + UNLINK(symtab->table[bucket], elt, link); + if (symtab->undefine_action != NULL) + (symtab->undefine_action)(elt->key, elt->type, + elt->value); + } else { + elt = (elt_t *)isc_mem_get(symtab->mctx, sizeof *elt); + if (elt == NULL) + return (ISC_R_NOMEMORY); + } elt->key = key; elt->type = type; elt->value = value; - APPEND(symtab->table[bucket], elt, link); + /* + * We prepend so that a 'type 0' lookup will return the most + * recent definition, and a 'type 0' undefine will undefine the + * most recent definition. + */ + PREPEND(symtab->table[bucket], elt, link); return (ISC_R_SUCCESS); }