grammar.h 15.4 KB
Newer Older
1
/*
2
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3
 *
4 5 6
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 8 9
 *
 * See the COPYRIGHT file distributed with this work for additional
 * information regarding copyright ownership.
10 11 12 13 14
 */

#ifndef ISCCFG_GRAMMAR_H
#define ISCCFG_GRAMMAR_H 1

15
/*! \file isccfg/grammar.h */
16

Mark Andrews's avatar
Mark Andrews committed
17
#include <isc/lex.h>
18 19 20 21 22
#include <isc/netaddr.h>
#include <isc/sockaddr.h>
#include <isc/region.h>
#include <isc/types.h>

Mark Andrews's avatar
Mark Andrews committed
23 24
#include <isccfg/cfg.h>

25 26 27 28 29
/*
 * Definitions shared between the configuration parser
 * and the grammars; not visible to users of the parser.
 */

30
/*% Clause may occur multiple times (e.g., "zone") */
31
#define CFG_CLAUSEFLAG_MULTI 		0x00000001
32
/*% Clause is obsolete */
33
#define CFG_CLAUSEFLAG_OBSOLETE 	0x00000002
34
/*% Clause is not implemented, and may never be */
35
#define CFG_CLAUSEFLAG_NOTIMP	 	0x00000004
36
/*% Clause is not implemented yet */
37
#define CFG_CLAUSEFLAG_NYI 		0x00000008
38
/*% Default value has changed since earlier release */
39
#define CFG_CLAUSEFLAG_NEWDEFAULT	0x00000010
40
/*%
41 42 43 44 45
 * Clause needs to be interpreted during parsing
 * by calling a callback function, like the
 * "directory" option.
 */
#define CFG_CLAUSEFLAG_CALLBACK		0x00000020
46 47
/*% A option that is only used in testing. */
#define CFG_CLAUSEFLAG_TESTONLY		0x00000040
48 49
/*% A configuration option that was not configured at compile time. */
#define CFG_CLAUSEFLAG_NOTCONFIGURED	0x00000080
50 51
/*% A option for a experimental feature. */
#define CFG_CLAUSEFLAG_EXPERIMENTAL	0x00000100
52 53 54
/*% A configuration option that is ineffective due to
 * compile time options, but is harmless. */
#define CFG_CLAUSEFLAG_NOOP		0x00000200
55 56
/*% Clause is obsolete in a future release */
#define CFG_CLAUSEFLAG_DEPRECATED	0x00000400
57

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
/*%
 * Zone types for which a clause is valid:
 * These share space with CFG_CLAUSEFLAG values, but count
 * down from the top.
 */
#define CFG_ZONE_MASTER			0x80000000
#define CFG_ZONE_SLAVE			0x40000000
#define CFG_ZONE_STUB			0x20000000
#define CFG_ZONE_HINT			0x10000000
#define CFG_ZONE_FORWARD		0x08000000
#define CFG_ZONE_STATICSTUB		0x04000000
#define CFG_ZONE_REDIRECT		0x02000000
#define CFG_ZONE_DELEGATION		0x01000000
#define CFG_ZONE_INVIEW			0x00800000

73 74 75 76 77 78 79 80 81 82 83 84 85
typedef struct cfg_clausedef cfg_clausedef_t;
typedef struct cfg_tuplefielddef cfg_tuplefielddef_t;
typedef struct cfg_printer cfg_printer_t;
typedef ISC_LIST(cfg_listelt_t) cfg_list_t;
typedef struct cfg_map cfg_map_t;
typedef struct cfg_rep cfg_rep_t;

/*
 * Function types for configuration object methods
 */

typedef isc_result_t (*cfg_parsefunc_t)(cfg_parser_t *, const cfg_type_t *type,
					cfg_obj_t **);
86
typedef void	     (*cfg_printfunc_t)(cfg_printer_t *, const cfg_obj_t *);
87 88 89 90 91 92 93
typedef void	     (*cfg_docfunc_t)(cfg_printer_t *, const cfg_type_t *);
typedef void	     (*cfg_freefunc_t)(cfg_parser_t *, cfg_obj_t *);

/*
 * Structure definitions
 */

94
/*%
95 96 97 98 99 100 101 102
 * A configuration printer object.  This is an abstract
 * interface to a destination to which text can be printed
 * by calling the function 'f'.
 */
struct cfg_printer {
	void (*f)(void *closure, const char *text, int textlen);
	void *closure;
	int indent;
103
	int flags;
104 105
};

106
/*% A clause definition. */
107 108 109 110 111 112
struct cfg_clausedef {
	const char      *name;
	cfg_type_t      *type;
	unsigned int	flags;
};

113
/*% A tuple field definition. */
114 115 116 117 118 119
struct cfg_tuplefielddef {
	const char      *name;
	cfg_type_t      *type;
	unsigned int	flags;
};

120
/*% A configuration object type definition. */
121
struct cfg_type {
122
	const char *name;	/*%< For debugging purposes only */
123 124
	cfg_parsefunc_t	parse;
	cfg_printfunc_t print;
125 126 127
	cfg_docfunc_t	doc;	/*%< Print grammar description */
	cfg_rep_t *	rep;	/*%< Data representation */
	const void *	of;	/*%< Additional data for meta-types */
128 129
};

130
/*% A keyword-type definition, for things like "port <integer>". */
131 132 133 134 135 136
typedef struct {
	const char *name;
	const cfg_type_t *type;
} keyword_type_t;

struct cfg_map {
137 138
	cfg_obj_t	 *id; /*%< Used for 'named maps' like keys, zones, &c */
	const cfg_clausedef_t * const *clausesets; /*%< The clauses that
139 140 141 142 143 144 145 146 147 148 149 150
						      can occur in this map;
						      used for printing */
	isc_symtab_t     *symtab;
};

typedef struct cfg_netprefix cfg_netprefix_t;

struct cfg_netprefix {
	isc_netaddr_t address; /* IP4/IP6 */
	unsigned int prefixlen;
};

151
/*%
152 153 154
 * A configuration data representation.
 */
struct cfg_rep {
155 156
	const char *	name;	/*%< For debugging only */
	cfg_freefunc_t 	free;	/*%< How to free this kind of data. */
157 158
};

159
/*%
160 161 162 163 164 165 166 167 168
 * A configuration object.  This is the main building block
 * of the configuration parse tree.
 */

struct cfg_obj {
	const cfg_type_t *type;
	union {
		isc_uint32_t  	uint32;
		isc_uint64_t  	uint64;
169
		isc_textregion_t string; /*%< null terminated, too */
170 171 172 173 174
		isc_boolean_t 	boolean;
		cfg_map_t	map;
		cfg_list_t	list;
		cfg_obj_t **	tuple;
		isc_sockaddr_t	sockaddr;
Evan Hunt's avatar
Evan Hunt committed
175 176 177 178
		struct {
			isc_sockaddr_t	sockaddr;
			isc_dscp_t	dscp;
		} sockaddrdscp;
179 180
		cfg_netprefix_t netprefix;
	}               value;
181
	isc_refcount_t  references;     /*%< reference counter */
182
	const char *	file;
183
	unsigned int    line;
184
	cfg_parser_t *	pctx;
185 186 187
};


188
/*% A list element. */
189 190 191 192 193
struct cfg_listelt {
	cfg_obj_t               *obj;
	ISC_LINK(cfg_listelt_t)  link;
};

194
/*% The parser object. */
195 196 197 198 199 200 201 202
struct cfg_parser {
	isc_mem_t *	mctx;
	isc_log_t *	lctx;
	isc_lex_t *	lexer;
	unsigned int    errors;
	unsigned int    warnings;
	isc_token_t     token;

203
	/*% We are at the end of all input. */
204 205
	isc_boolean_t	seen_eof;

206
	/*% The current token has been pushed back. */
207 208
	isc_boolean_t	ungotten;

209
	/*%
210 211
	 * The stack of currently active files, represented
	 * as a configuration list of configuration strings.
Automatic Updater's avatar
Automatic Updater committed
212 213
	 * The head is the top-level file, subsequent elements
	 * (if any) are the nested include files, and the
214 215 216 217
	 * last element is the file currently being parsed.
	 */
	cfg_obj_t *	open_files;

218
	/*%
219 220 221 222 223 224 225 226 227 228
	 * Names of files that we have parsed and closed
	 * and were previously on the open_file list.
	 * We keep these objects around after closing
	 * the files because the file names may still be
	 * referenced from other configuration objects
	 * for use in reporting semantic errors after
	 * parsing is complete.
	 */
	cfg_obj_t *	closed_files;

229 230 231 232 233 234
	/*%
	 * Name of a buffer being parsed; used only for
	 * logging.
	 */
	char const *	buf_name;

235
	/*%
236 237 238 239 240 241
	 * Current line number.  We maintain our own
	 * copy of this so that it is available even
	 * when a file has just been closed.
	 */
	unsigned int	line;

242 243 244 245 246 247
	/*%
	 * Parser context flags, used for maintaining state
	 * from one token to the next.
	 */
	unsigned int flags;

248 249 250
	/*%< Reference counter */
	isc_refcount_t  references;

251 252 253 254
	cfg_parsecallback_t callback;
	void *callbackarg;
};

255 256
/* Parser context flags */
#define CFG_PCTX_SKIP		0x1
257
#define CFG_PCTX_NODEPRECATED	0x2
258

259 260
/*@{*/
/*%
261 262 263 264 265 266
 * Flags defining whether to accept certain types of network addresses.
 */
#define CFG_ADDR_V4OK 		0x00000001
#define CFG_ADDR_V4PREFIXOK 	0x00000002
#define CFG_ADDR_V6OK 		0x00000004
#define CFG_ADDR_WILDOK		0x00000008
Evan Hunt's avatar
Evan Hunt committed
267
#define CFG_ADDR_DSCPOK		0x00000010
268
#define CFG_ADDR_MASK		(CFG_ADDR_V6OK|CFG_ADDR_V4OK)
269
/*@}*/
270

271 272
/*@{*/
/*%
273 274
 * Predefined data representation types.
 */
275 276 277 278 279 280 281 282 283 284
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint32;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint64;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_string;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_boolean;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_map;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_list;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_tuple;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_sockaddr;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void;
Evan Hunt's avatar
Evan Hunt committed
285
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_fixedpoint;
286
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_percentage;
287
/*@}*/
288

289 290
/*@{*/
/*%
291 292 293 294 295 296 297 298
 * Predefined configuration object types.
 */
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_boolean;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint32;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint64;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_qstring;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring;
299
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sstring;
Evan Hunt's avatar
Evan Hunt committed
300
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_bracketed_text;
301
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr;
Evan Hunt's avatar
Evan Hunt committed
302
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddrdscp;
303
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr;
304 305 306 307
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4wild;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6wild;
308 309 310 311
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netprefix;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_void;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported;
Evan Hunt's avatar
Evan Hunt committed
312
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_fixedpoint;
313
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_percentage;
314
/*@}*/
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336

isc_result_t
cfg_gettoken(cfg_parser_t *pctx, int options);

isc_result_t
cfg_peektoken(cfg_parser_t *pctx, int options);

void
cfg_ungettoken(cfg_parser_t *pctx);

#define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE)

isc_result_t
cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);

void
cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u);

isc_result_t
cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

void
337
cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj);
338 339

void
340
cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj);
341 342 343 344 345

isc_result_t
cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

void
346
cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj);
347 348 349 350

isc_result_t
cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

351 352 353
isc_result_t
cfg_parse_sstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

354 355 356 357
isc_result_t
cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na);

void
358
cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na);
359 360 361 362 363 364 365

isc_boolean_t
cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags);

isc_result_t
cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port);

Evan Hunt's avatar
Evan Hunt committed
366 367 368
isc_result_t
cfg_parse_dscp(cfg_parser_t *pctx, isc_dscp_t *dscp);

369 370 371
isc_result_t
cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

372 373 374
isc_result_t
cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

375
void
376
cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj);
377

378 379 380
void
cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj);

381 382 383 384 385 386 387 388
void
cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type);

isc_result_t
cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

isc_result_t
cfg_parse_special(cfg_parser_t *pctx, int special);
389
/*%< Parse a required special character 'special'. */
390 391 392 393 394 395 396 397

isc_result_t
cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);

isc_result_t
cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

void
398
cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj);
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413

void
cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type);

isc_result_t
cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);

isc_result_t
cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype,
		  cfg_listelt_t **ret);

isc_result_t
cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

void
414
cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj);
415 416 417 418 419 420 421 422

void
cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type);

isc_result_t
cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

void
423
cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj);
424 425 426 427 428 429 430 431 432

isc_result_t
cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

void
cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type);

void
cfg_print_chars(cfg_printer_t *pctx, const char *text, int len);
433
/*%< Print 'len' characters at 'text' */
434 435 436

void
cfg_print_cstr(cfg_printer_t *pctx, const char *s);
437
/*%< Print the null-terminated string 's' */
438 439 440 441 442 443 444 445 446 447

isc_result_t
cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

isc_result_t
cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

isc_result_t
cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

448 449 450 451
isc_result_t
cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **
ret);

452
void
453
cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj);
454 455 456 457 458 459 460 461

void
cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type);

isc_result_t
cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

void
462
cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj);
463 464 465 466 467 468 469 470

void
cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type);

isc_result_t
cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

void
471
cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj);
472 473 474 475

void
cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type);

Evan Hunt's avatar
Evan Hunt committed
476
isc_result_t
477 478
cfg_parse_fixedpoint(cfg_parser_t *pctx, const cfg_type_t *type,
		     cfg_obj_t **ret);
Evan Hunt's avatar
Evan Hunt committed
479 480 481 482

void
cfg_print_fixedpoint(cfg_printer_t *pctx, const cfg_obj_t *obj);

483 484 485 486 487 488 489
isc_result_t
cfg_parse_percentage(cfg_parser_t *pctx, const cfg_type_t *type,
		     cfg_obj_t **ret);

void
cfg_print_percentage(cfg_printer_t *pctx, const cfg_obj_t *obj);

490 491 492 493
isc_result_t
cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);

void
494
cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj);
495 496 497

void
cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type);
498
/*%<
499 500 501 502 503 504
 * Print a description of the grammar of an arbitrary configuration
 * type 'type'
 */

void
cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type);
505
/*%<
506
 * Document the type 'type' as a terminal by printing its
507
 * name in angle brackets, e.g., &lt;uint32>.
508 509 510 511 512
 */

void
cfg_parser_error(cfg_parser_t *pctx, unsigned int flags,
		 const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);
Automatic Updater's avatar
Automatic Updater committed
513
/*!
514 515 516
 * Pass one of these flags to cfg_parser_error() to include the
 * token text in log message.
 */
517 518 519
#define CFG_LOG_NEAR    0x00000001	/*%< Say "near <token>" */
#define CFG_LOG_BEFORE  0x00000002	/*%< Say "before <token>" */
#define CFG_LOG_NOPREP  0x00000004	/*%< Say just "<token>" */
520 521 522 523 524 525 526

void
cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags,
		   const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);

isc_boolean_t
cfg_is_enum(const char *s, const char *const *enums);
527
/*%< Return true iff the string 's' is one of the strings in 'enums' */
528

529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
isc_boolean_t
cfg_clause_validforzone(const char *name, unsigned int ztype);
/*%<
 * Check whether an option is legal for the specified zone type.
 */

void
cfg_print_zonegrammar(const unsigned int zonetype,
		      void (*f)(void *closure, const char *text, int textlen),
		      void *closure);
/*%<
 * Print a summary of the grammar of the zone type represented by
 * 'zonetype'.
 */

void
cfg_print_clauseflags(cfg_printer_t *pctx, unsigned int flags);
/*%<
 * Print clause flags (e.g. "obsolete", "not implemented", etc) in
 * human readable form
 */

void
cfg_print_indent(cfg_printer_t *pctx);
/*%<
 * Print the necessary indent required by the current settings of 'pctx'.
 */

557
#endif /* ISCCFG_GRAMMAR_H */