diff options
Diffstat (limited to 'lib/isccfg/parser.c')
-rw-r--r-- | lib/isccfg/parser.c | 92 |
1 files changed, 71 insertions, 21 deletions
diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 2f64a09..87ad391 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: parser.c,v 1.129 2008-09-25 04:02:39 tbox Exp $ */ +/* $Id: parser.c,v 1.139 2011-01-04 23:47:14 tbox Exp $ */ /*! \file */ @@ -29,12 +29,12 @@ #include <isc/mem.h> #include <isc/net.h> #include <isc/netaddr.h> +#include <isc/netscope.h> #include <isc/print.h> #include <isc/string.h> #include <isc/sockaddr.h> -#include <isc/netscope.h> -#include <isc/util.h> #include <isc/symtab.h> +#include <isc/util.h> #include <isccfg/cfg.h> #include <isccfg/grammar.h> @@ -387,6 +387,12 @@ cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) { if (pctx == NULL) return (ISC_R_NOMEMORY); + result = isc_refcount_init(&pctx->references, 1); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, pctx, sizeof(*pctx)); + return (result); + } + pctx->mctx = mctx; pctx->lctx = lctx; pctx->lexer = NULL; @@ -400,6 +406,7 @@ cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) { pctx->callback = NULL; pctx->callbackarg = NULL; pctx->token.type = isc_tokentype_unknown; + pctx->flags = 0; memset(specials, 0, sizeof(specials)); specials['{'] = 1; @@ -526,17 +533,30 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, } void +cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest) { + REQUIRE(src != NULL); + REQUIRE(dest != NULL && *dest == NULL); + isc_refcount_increment(&src->references, NULL); + *dest = src; +} + +void cfg_parser_destroy(cfg_parser_t **pctxp) { cfg_parser_t *pctx = *pctxp; - isc_lex_destroy(&pctx->lexer); - /* - * Cleaning up open_files does not - * close the files; that was already done - * by closing the lexer. - */ - CLEANUP_OBJ(pctx->open_files); - CLEANUP_OBJ(pctx->closed_files); - isc_mem_put(pctx->mctx, pctx, sizeof(*pctx)); + unsigned int refs; + + isc_refcount_decrement(&pctx->references, &refs); + if (refs == 0) { + isc_lex_destroy(&pctx->lexer); + /* + * Cleaning up open_files does not + * close the files; that was already done + * by closing the lexer. + */ + CLEANUP_OBJ(pctx->open_files); + CLEANUP_OBJ(pctx->closed_files); + isc_mem_put(pctx->mctx, pctx, sizeof(*pctx)); + } *pctxp = NULL; } @@ -848,8 +868,8 @@ cfg_obj_asboolean(const cfg_obj_t *obj) { return (obj->value.boolean); } -static isc_result_t -parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) +isc_result_t +cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; isc_boolean_t value; @@ -888,8 +908,8 @@ parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) return (result); } -static void -print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj) { +void +cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj) { if (obj->value.boolean) cfg_print_chars(pctx, "yes", 3); else @@ -897,7 +917,7 @@ print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj) { } cfg_type_t cfg_type_boolean = { - "boolean", parse_boolean, print_boolean, cfg_doc_terminal, + "boolean", cfg_parse_boolean, cfg_print_boolean, cfg_doc_terminal, &cfg_rep_boolean, NULL }; @@ -1132,7 +1152,7 @@ cfg_list_length(const cfg_obj_t *obj, isc_boolean_t recurse) { return (count); } -const cfg_obj_t * +cfg_obj_t * cfg_listelt_value(const cfg_listelt_t *elt) { REQUIRE(elt != NULL); return (elt->obj); @@ -1237,6 +1257,14 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) if ((clause->flags & CFG_CLAUSEFLAG_NYI) != 0) cfg_parser_warning(pctx, 0, "option '%s' is " "not implemented", clause->name); + + if ((clause->flags & CFG_CLAUSEFLAG_NOTCONFIGURED) != 0) { + cfg_parser_warning(pctx, 0, "option '%s' is not " + "configured", clause->name); + result = ISC_R_FAILURE; + goto cleanup; + } + /* * Don't log options with CFG_CLAUSEFLAG_NEWDEFAULT * set here - we need to log the *lack* of such an option, @@ -1478,6 +1506,7 @@ static struct flagtext { { CFG_CLAUSEFLAG_OBSOLETE, "obsolete" }, { CFG_CLAUSEFLAG_NEWDEFAULT, "default changed" }, { CFG_CLAUSEFLAG_TESTONLY, "test only" }, + { CFG_CLAUSEFLAG_NOTCONFIGURED, "not configured" }, { 0, NULL } }; @@ -2305,6 +2334,7 @@ cfg_obj_line(const cfg_obj_t *obj) { isc_result_t cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { + isc_result_t result; cfg_obj_t *obj; obj = isc_mem_get(pctx->mctx, sizeof(cfg_obj_t)); @@ -2313,10 +2343,16 @@ cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { obj->type = type; obj->file = current_file(pctx); obj->line = pctx->line; + result = isc_refcount_init(&obj->references, 1); + if (result != ISC_R_SUCCESS) { + isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t)); + return (result); + } *ret = obj; return (ISC_R_SUCCESS); } + static void map_symtabitem_destroy(char *key, unsigned int type, isc_symvalue_t symval, void *userarg) @@ -2370,11 +2406,25 @@ cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type) { void cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) { cfg_obj_t *obj = *objp; - obj->type->rep->free(pctx, obj); - isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t)); + unsigned int refs; + + isc_refcount_decrement(&obj->references, &refs); + if (refs == 0) { + obj->type->rep->free(pctx, obj); + isc_refcount_destroy(&obj->references); + isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t)); + } *objp = NULL; } +void +cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest) { + REQUIRE(src != NULL); + REQUIRE(dest != NULL && *dest == NULL); + isc_refcount_increment(&src->references, NULL); + *dest = src; +} + static void free_noop(cfg_parser_t *pctx, cfg_obj_t *obj) { UNUSED(pctx); |