Home | History | Annotate | Line # | Download | only in isccfg
      1 /*	$NetBSD: grammar.h,v 1.1 2024/02/18 20:57:59 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #ifndef ISCCFG_GRAMMAR_H
     17 #define ISCCFG_GRAMMAR_H 1
     18 
     19 /*! \file isccfg/grammar.h */
     20 
     21 #include <inttypes.h>
     22 #include <stdbool.h>
     23 
     24 #include <isc/lex.h>
     25 #include <isc/netaddr.h>
     26 #include <isc/region.h>
     27 #include <isc/sockaddr.h>
     28 #include <isc/types.h>
     29 
     30 #include <isccfg/cfg.h>
     31 
     32 /*
     33  * Definitions shared between the configuration parser
     34  * and the grammars; not visible to users of the parser.
     35  */
     36 
     37 /*% Clause may occur multiple times (e.g., "zone") */
     38 #define CFG_CLAUSEFLAG_MULTI 0x00000001
     39 /*% Clause is obsolete (logs a warning, but is not a fatal error) */
     40 #define CFG_CLAUSEFLAG_OBSOLETE 0x00000002
     41 /*% Clause is not implemented, and may never be */
     42 #define CFG_CLAUSEFLAG_NOTIMP 0x00000004
     43 /*% Clause is not implemented yet */
     44 #define CFG_CLAUSEFLAG_NYI 0x00000008
     45 /*% Default value has changed since earlier release */
     46 #define CFG_CLAUSEFLAG_NEWDEFAULT 0x00000010
     47 /*%
     48  * Clause needs to be interpreted during parsing
     49  * by calling a callback function, like the
     50  * "directory" option.
     51  */
     52 #define CFG_CLAUSEFLAG_CALLBACK 0x00000020
     53 /*% A option that is only used in testing. */
     54 #define CFG_CLAUSEFLAG_TESTONLY 0x00000040
     55 /*% A configuration option that was not configured at compile time. */
     56 #define CFG_CLAUSEFLAG_NOTCONFIGURED 0x00000080
     57 /*% A option for a experimental feature. */
     58 #define CFG_CLAUSEFLAG_EXPERIMENTAL 0x00000100
     59 /*% A configuration option that is ineffective due to
     60  * compile time options, but is harmless. */
     61 #define CFG_CLAUSEFLAG_NOOP 0x00000200
     62 /*% Clause will be obsolete in a future release (logs a warning) */
     63 #define CFG_CLAUSEFLAG_DEPRECATED 0x00000400
     64 /*% Clause has been obsolete so long that it's now a fatal error */
     65 #define CFG_CLAUSEFLAG_ANCIENT 0x00000800
     66 
     67 /*%
     68  * Zone types for which a clause is valid:
     69  * These share space with CFG_CLAUSEFLAG values, but count
     70  * down from the top.
     71  */
     72 #define CFG_ZONE_PRIMARY    0x80000000
     73 #define CFG_ZONE_SECONDARY  0x40000000
     74 #define CFG_ZONE_STUB	    0x20000000
     75 #define CFG_ZONE_HINT	    0x10000000
     76 #define CFG_ZONE_FORWARD    0x08000000
     77 #define CFG_ZONE_STATICSTUB 0x04000000
     78 #define CFG_ZONE_REDIRECT   0x02000000
     79 #define CFG_ZONE_DELEGATION 0x01000000
     80 #define CFG_ZONE_INVIEW	    0x00800000
     81 #define CFG_ZONE_MIRROR	    0x00400000
     82 
     83 typedef struct cfg_clausedef	 cfg_clausedef_t;
     84 typedef struct cfg_tuplefielddef cfg_tuplefielddef_t;
     85 typedef struct cfg_printer	 cfg_printer_t;
     86 typedef ISC_LIST(cfg_listelt_t) cfg_list_t;
     87 typedef struct cfg_map	    cfg_map_t;
     88 typedef struct cfg_rep	    cfg_rep_t;
     89 typedef struct cfg_duration cfg_duration_t;
     90 
     91 #define CFG_DURATION_MAXLEN 80
     92 
     93 /*
     94  * Function types for configuration object methods
     95  */
     96 
     97 typedef isc_result_t (*cfg_parsefunc_t)(cfg_parser_t *, const cfg_type_t *type,
     98 					cfg_obj_t **);
     99 typedef void (*cfg_printfunc_t)(cfg_printer_t *, const cfg_obj_t *);
    100 typedef void (*cfg_docfunc_t)(cfg_printer_t *, const cfg_type_t *);
    101 typedef void (*cfg_freefunc_t)(cfg_parser_t *, cfg_obj_t *);
    102 
    103 /*
    104  * Structure definitions
    105  */
    106 
    107 /*%
    108  * A configuration printer object.  This is an abstract
    109  * interface to a destination to which text can be printed
    110  * by calling the function 'f'.
    111  */
    112 struct cfg_printer {
    113 	void (*f)(void *closure, const char *text, int textlen);
    114 	void *closure;
    115 	int   indent;
    116 	int   flags;
    117 };
    118 
    119 /*% A clause definition. */
    120 struct cfg_clausedef {
    121 	const char  *name;
    122 	cfg_type_t  *type;
    123 	unsigned int flags;
    124 };
    125 
    126 /*% A tuple field definition. */
    127 struct cfg_tuplefielddef {
    128 	const char  *name;
    129 	cfg_type_t  *type;
    130 	unsigned int flags;
    131 };
    132 
    133 /*% A configuration object type definition. */
    134 struct cfg_type {
    135 	const char     *name; /*%< For debugging purposes only */
    136 	cfg_parsefunc_t parse;
    137 	cfg_printfunc_t print;
    138 	cfg_docfunc_t	doc; /*%< Print grammar description */
    139 	cfg_rep_t      *rep; /*%< Data representation */
    140 	const void     *of;  /*%< Additional data for meta-types */
    141 };
    142 
    143 /*% A keyword-type definition, for things like "port <integer>". */
    144 typedef struct {
    145 	const char	 *name;
    146 	const cfg_type_t *type;
    147 } keyword_type_t;
    148 
    149 struct cfg_map {
    150 	cfg_obj_t *id; /*%< Used for 'named maps' like
    151 			* keys, zones, &c */
    152 	const cfg_clausedef_t *const *clausesets; /*%< The clauses that
    153 						   * can occur in this map;
    154 						   * used for printing */
    155 	isc_symtab_t *symtab;
    156 };
    157 
    158 typedef struct cfg_netprefix cfg_netprefix_t;
    159 
    160 struct cfg_netprefix {
    161 	isc_netaddr_t address; /* IP4/IP6 */
    162 	unsigned int  prefixlen;
    163 };
    164 
    165 /*%
    166  * A configuration object to store ISO 8601 durations.
    167  */
    168 struct cfg_duration {
    169 	/*
    170 	 * The duration is stored in multiple parts:
    171 	 * [0] Years
    172 	 * [1] Months
    173 	 * [2] Weeks
    174 	 * [3] Days
    175 	 * [4] Hours
    176 	 * [5] Minutes
    177 	 * [6] Seconds
    178 	 */
    179 	uint32_t parts[7];
    180 	bool	 iso8601;
    181 	bool	 unlimited;
    182 };
    183 
    184 /*%
    185  * A configuration data representation.
    186  */
    187 struct cfg_rep {
    188 	const char    *name; /*%< For debugging only */
    189 	cfg_freefunc_t free; /*%< How to free this kind of data. */
    190 };
    191 
    192 /*%
    193  * A configuration object.  This is the main building block
    194  * of the configuration parse tree.
    195  */
    196 
    197 struct cfg_obj {
    198 	const cfg_type_t *type;
    199 	union {
    200 		uint32_t	 uint32;
    201 		uint64_t	 uint64;
    202 		isc_textregion_t string; /*%< null terminated, too */
    203 		bool		 boolean;
    204 		cfg_map_t	 map;
    205 		cfg_list_t	 list;
    206 		cfg_obj_t      **tuple;
    207 		isc_sockaddr_t	 sockaddr;
    208 		struct {
    209 			isc_sockaddr_t sockaddr;
    210 			isc_dscp_t     dscp;
    211 		} sockaddrdscp;
    212 		cfg_netprefix_t netprefix;
    213 		cfg_duration_t	duration;
    214 	} value;
    215 	isc_refcount_t references; /*%< reference counter */
    216 	const char    *file;
    217 	unsigned int   line;
    218 	cfg_parser_t  *pctx;
    219 };
    220 
    221 /*% A list element. */
    222 struct cfg_listelt {
    223 	cfg_obj_t *obj;
    224 	ISC_LINK(cfg_listelt_t) link;
    225 };
    226 
    227 /*% The parser object. */
    228 struct cfg_parser {
    229 	isc_mem_t   *mctx;
    230 	isc_log_t   *lctx;
    231 	isc_lex_t   *lexer;
    232 	unsigned int errors;
    233 	unsigned int warnings;
    234 	isc_token_t  token;
    235 
    236 	/*% We are at the end of all input. */
    237 	bool seen_eof;
    238 
    239 	/*% The current token has been pushed back. */
    240 	bool ungotten;
    241 
    242 	/*%
    243 	 * The stack of currently active files, represented
    244 	 * as a configuration list of configuration strings.
    245 	 * The head is the top-level file, subsequent elements
    246 	 * (if any) are the nested include files, and the
    247 	 * last element is the file currently being parsed.
    248 	 */
    249 	cfg_obj_t *open_files;
    250 
    251 	/*%
    252 	 * Names of files that we have parsed and closed
    253 	 * and were previously on the open_file list.
    254 	 * We keep these objects around after closing
    255 	 * the files because the file names may still be
    256 	 * referenced from other configuration objects
    257 	 * for use in reporting semantic errors after
    258 	 * parsing is complete.
    259 	 */
    260 	cfg_obj_t *closed_files;
    261 
    262 	/*%
    263 	 * Name of a buffer being parsed; used only for
    264 	 * logging.
    265 	 */
    266 	char const *buf_name;
    267 
    268 	/*%
    269 	 * Current line number.  We maintain our own
    270 	 * copy of this so that it is available even
    271 	 * when a file has just been closed.
    272 	 */
    273 	unsigned int line;
    274 
    275 	/*%
    276 	 * Parser context flags, used for maintaining state
    277 	 * from one token to the next.
    278 	 */
    279 	unsigned int flags;
    280 
    281 	/*%< Reference counter */
    282 	isc_refcount_t references;
    283 
    284 	cfg_parsecallback_t callback;
    285 	void		   *callbackarg;
    286 };
    287 
    288 /* Parser context flags */
    289 #define CFG_PCTX_SKIP	      0x1
    290 #define CFG_PCTX_NODEPRECATED 0x2
    291 
    292 /*@{*/
    293 /*%
    294  * Flags defining whether to accept certain types of network addresses.
    295  */
    296 #define CFG_ADDR_V4OK	    0x00000001
    297 #define CFG_ADDR_V4PREFIXOK 0x00000002
    298 #define CFG_ADDR_V6OK	    0x00000004
    299 #define CFG_ADDR_WILDOK	    0x00000008
    300 #define CFG_ADDR_DSCPOK	    0x00000010
    301 #define CFG_ADDR_MASK	    (CFG_ADDR_V6OK | CFG_ADDR_V4OK)
    302 /*@}*/
    303 
    304 /*@{*/
    305 /*%
    306  * Predefined data representation types.
    307  */
    308 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint32;
    309 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint64;
    310 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_string;
    311 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_boolean;
    312 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_map;
    313 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_list;
    314 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_tuple;
    315 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_sockaddr;
    316 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix;
    317 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void;
    318 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_fixedpoint;
    319 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_percentage;
    320 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_duration;
    321 /*@}*/
    322 
    323 /*@{*/
    324 /*%
    325  * Predefined configuration object types.
    326  */
    327 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_boolean;
    328 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint32;
    329 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint64;
    330 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_qstring;
    331 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring;
    332 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring;
    333 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sstring;
    334 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_bracketed_aml;
    335 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_bracketed_text;
    336 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_optional_bracketed_text;
    337 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_keyref;
    338 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr;
    339 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddrdscp;
    340 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr;
    341 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4;
    342 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4wild;
    343 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6;
    344 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6wild;
    345 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netprefix;
    346 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_void;
    347 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token;
    348 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported;
    349 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_fixedpoint;
    350 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_percentage;
    351 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_duration;
    352 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_duration_or_unlimited;
    353 /*@}*/
    354 
    355 isc_result_t
    356 cfg_gettoken(cfg_parser_t *pctx, int options);
    357 
    358 isc_result_t
    359 cfg_peektoken(cfg_parser_t *pctx, int options);
    360 
    361 void
    362 cfg_ungettoken(cfg_parser_t *pctx);
    363 
    364 #define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE)
    365 
    366 isc_result_t
    367 cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
    368 
    369 void
    370 cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u);
    371 
    372 isc_result_t
    373 cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    374 
    375 void
    376 cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj);
    377 
    378 void
    379 cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj);
    380 
    381 isc_result_t
    382 cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    383 
    384 void
    385 cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj);
    386 
    387 isc_result_t
    388 cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    389 
    390 isc_result_t
    391 cfg_parse_sstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    392 
    393 isc_result_t
    394 cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na);
    395 
    396 void
    397 cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na);
    398 
    399 bool
    400 cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags);
    401 
    402 isc_result_t
    403 cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port);
    404 
    405 isc_result_t
    406 cfg_parse_dscp(cfg_parser_t *pctx, isc_dscp_t *dscp);
    407 
    408 isc_result_t
    409 cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    410 
    411 isc_result_t
    412 cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    413 
    414 void
    415 cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj);
    416 
    417 void
    418 cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj);
    419 
    420 void
    421 cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type);
    422 
    423 isc_result_t
    424 cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type,
    425 		    cfg_obj_t **ret);
    426 
    427 isc_result_t
    428 cfg_parse_special(cfg_parser_t *pctx, int special);
    429 /*%< Parse a required special character 'special'. */
    430 
    431 isc_result_t
    432 cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
    433 
    434 isc_result_t
    435 cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    436 
    437 void
    438 cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj);
    439 
    440 void
    441 cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type);
    442 
    443 isc_result_t
    444 cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
    445 
    446 isc_result_t
    447 cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype,
    448 		  cfg_listelt_t **ret);
    449 
    450 isc_result_t
    451 cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type,
    452 			 cfg_obj_t **ret);
    453 
    454 void
    455 cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj);
    456 
    457 void
    458 cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type);
    459 
    460 isc_result_t
    461 cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *type,
    462 		    cfg_obj_t **ret);
    463 
    464 void
    465 cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj);
    466 
    467 isc_result_t
    468 cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    469 
    470 void
    471 cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type);
    472 
    473 isc_result_t
    474 cfg_parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype,
    475 			const cfg_type_t *othertype, cfg_obj_t **ret);
    476 
    477 void
    478 cfg_doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *enumtype,
    479 		      const cfg_type_t *othertype);
    480 
    481 void
    482 cfg_print_chars(cfg_printer_t *pctx, const char *text, int len);
    483 /*%< Print 'len' characters at 'text' */
    484 
    485 void
    486 cfg_print_cstr(cfg_printer_t *pctx, const char *s);
    487 /*%< Print the null-terminated string 's' */
    488 
    489 isc_result_t
    490 cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    491 
    492 isc_result_t
    493 cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type,
    494 		    cfg_obj_t **ret);
    495 
    496 isc_result_t
    497 cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type,
    498 			cfg_obj_t **ret);
    499 
    500 isc_result_t
    501 cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type,
    502 			cfg_obj_t **ret);
    503 
    504 void
    505 cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj);
    506 
    507 void
    508 cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type);
    509 
    510 isc_result_t
    511 cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    512 
    513 void
    514 cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj);
    515 
    516 void
    517 cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type);
    518 
    519 isc_result_t
    520 cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    521 
    522 void
    523 cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj);
    524 
    525 void
    526 cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type);
    527 
    528 isc_result_t
    529 cfg_parse_fixedpoint(cfg_parser_t *pctx, const cfg_type_t *type,
    530 		     cfg_obj_t **ret);
    531 
    532 void
    533 cfg_print_fixedpoint(cfg_printer_t *pctx, const cfg_obj_t *obj);
    534 
    535 isc_result_t
    536 cfg_parse_percentage(cfg_parser_t *pctx, const cfg_type_t *type,
    537 		     cfg_obj_t **ret);
    538 
    539 void
    540 cfg_print_percentage(cfg_printer_t *pctx, const cfg_obj_t *obj);
    541 
    542 isc_result_t
    543 cfg_parse_duration(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    544 
    545 void
    546 cfg_print_duration(cfg_printer_t *pctx, const cfg_obj_t *obj);
    547 
    548 isc_result_t
    549 cfg_parse_duration_or_unlimited(cfg_parser_t *pctx, const cfg_type_t *type,
    550 				cfg_obj_t **ret);
    551 
    552 void
    553 cfg_print_duration_or_unlimited(cfg_printer_t *pctx, const cfg_obj_t *obj);
    554 
    555 isc_result_t
    556 cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
    557 
    558 void
    559 cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj);
    560 
    561 void
    562 cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type);
    563 /*%<
    564  * Print a description of the grammar of an arbitrary configuration
    565  * type 'type'
    566  */
    567 
    568 void
    569 cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type);
    570 /*%<
    571  * Document the type 'type' as a terminal by printing its
    572  * name in angle brackets, e.g., &lt;uint32>.
    573  */
    574 
    575 void
    576 cfg_parser_error(cfg_parser_t *pctx, unsigned int flags, const char *fmt, ...)
    577 	ISC_FORMAT_PRINTF(3, 4);
    578 /*!
    579  * Pass one of these flags to cfg_parser_error() to include the
    580  * token text in log message.
    581  */
    582 #define CFG_LOG_NEAR   0x00000001 /*%< Say "near <token>" */
    583 #define CFG_LOG_BEFORE 0x00000002 /*%< Say "before <token>" */
    584 #define CFG_LOG_NOPREP 0x00000004 /*%< Say just "<token>" */
    585 
    586 void
    587 cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags, const char *fmt, ...)
    588 	ISC_FORMAT_PRINTF(3, 4);
    589 
    590 bool
    591 cfg_is_enum(const char *s, const char *const *enums);
    592 /*%< Return true iff the string 's' is one of the strings in 'enums' */
    593 
    594 bool
    595 cfg_clause_validforzone(const char *name, unsigned int ztype);
    596 /*%<
    597  * Check whether an option is legal for the specified zone type.
    598  */
    599 
    600 void
    601 cfg_print_zonegrammar(const unsigned int zonetype, unsigned int flags,
    602 		      void (*f)(void *closure, const char *text, int textlen),
    603 		      void *closure);
    604 /*%<
    605  * Print a summary of the grammar of the zone type represented by
    606  * 'zonetype'.
    607  */
    608 
    609 void
    610 cfg_print_clauseflags(cfg_printer_t *pctx, unsigned int flags);
    611 /*%<
    612  * Print clause flags (e.g. "obsolete", "not implemented", etc) in
    613  * human readable form
    614  */
    615 
    616 void
    617 cfg_print_indent(cfg_printer_t *pctx);
    618 /*%<
    619  * Print the necessary indent required by the current settings of 'pctx'.
    620  */
    621 
    622 #endif /* ISCCFG_GRAMMAR_H */
    623