summaryrefslogtreecommitdiffstats
path: root/lib/isccfg/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/isccfg/parser.c')
-rw-r--r--lib/isccfg/parser.c92
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);
OpenPOWER on IntegriCloud