xref: /netbsd-src/external/mpl/dhcp/bind/dist/lib/isccfg/include/isccfg/grammar.h (revision 4afad4b7fa6d4a0d3dedf41d1587a7250710ae54)
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