2 * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2002, 2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: grammar.h,v 1.17 2008/09/25 04:02:39 tbox Exp $ */
20 #ifndef ISCCFG_GRAMMAR_H
21 #define ISCCFG_GRAMMAR_H 1
23 /*! \file isccfg/grammar.h */
26 #include <isc/netaddr.h>
27 #include <isc/sockaddr.h>
28 #include <isc/region.h>
29 #include <isc/types.h>
31 #include <isccfg/cfg.h>
34 * Definitions shared between the configuration parser
35 * and the grammars; not visible to users of the parser.
38 /*% Clause may occur multiple times (e.g., "zone") */
39 #define CFG_CLAUSEFLAG_MULTI 0x00000001
40 /*% Clause is obsolete */
41 #define CFG_CLAUSEFLAG_OBSOLETE 0x00000002
42 /*% Clause is not implemented, and may never be */
43 #define CFG_CLAUSEFLAG_NOTIMP 0x00000004
44 /*% Clause is not implemented yet */
45 #define CFG_CLAUSEFLAG_NYI 0x00000008
46 /*% Default value has changed since earlier release */
47 #define CFG_CLAUSEFLAG_NEWDEFAULT 0x00000010
49 * Clause needs to be interpreted during parsing
50 * by calling a callback function, like the
53 #define CFG_CLAUSEFLAG_CALLBACK 0x00000020
54 /*% A option that is only used in testing. */
55 #define CFG_CLAUSEFLAG_TESTONLY 0x00000040
57 typedef struct cfg_clausedef cfg_clausedef_t;
58 typedef struct cfg_tuplefielddef cfg_tuplefielddef_t;
59 typedef struct cfg_printer cfg_printer_t;
60 typedef ISC_LIST(cfg_listelt_t) cfg_list_t;
61 typedef struct cfg_map cfg_map_t;
62 typedef struct cfg_rep cfg_rep_t;
65 * Function types for configuration object methods
68 typedef isc_result_t (*cfg_parsefunc_t)(cfg_parser_t *, const cfg_type_t *type,
70 typedef void (*cfg_printfunc_t)(cfg_printer_t *, const cfg_obj_t *);
71 typedef void (*cfg_docfunc_t)(cfg_printer_t *, const cfg_type_t *);
72 typedef void (*cfg_freefunc_t)(cfg_parser_t *, cfg_obj_t *);
75 * Structure definitions
79 * A configuration printer object. This is an abstract
80 * interface to a destination to which text can be printed
81 * by calling the function 'f'.
84 void (*f)(void *closure, const char *text, int textlen);
89 /*% A clause definition. */
90 struct cfg_clausedef {
96 /*% A tuple field definition. */
97 struct cfg_tuplefielddef {
103 /*% A configuration object type definition. */
105 const char *name; /*%< For debugging purposes only */
106 cfg_parsefunc_t parse;
107 cfg_printfunc_t print;
108 cfg_docfunc_t doc; /*%< Print grammar description */
109 cfg_rep_t * rep; /*%< Data representation */
110 const void * of; /*%< Additional data for meta-types */
113 /*% A keyword-type definition, for things like "port <integer>". */
116 const cfg_type_t *type;
120 cfg_obj_t *id; /*%< Used for 'named maps' like keys, zones, &c */
121 const cfg_clausedef_t * const *clausesets; /*%< The clauses that
122 can occur in this map;
124 isc_symtab_t *symtab;
127 typedef struct cfg_netprefix cfg_netprefix_t;
129 struct cfg_netprefix {
130 isc_netaddr_t address; /* IP4/IP6 */
131 unsigned int prefixlen;
135 * A configuration data representation.
138 const char * name; /*%< For debugging only */
139 cfg_freefunc_t free; /*%< How to free this kind of data. */
143 * A configuration object. This is the main building block
144 * of the configuration parse tree.
148 const cfg_type_t *type;
152 isc_textregion_t string; /*%< null terminated, too */
153 isc_boolean_t boolean;
157 isc_sockaddr_t sockaddr;
158 cfg_netprefix_t netprefix;
165 /*% A list element. */
168 ISC_LINK(cfg_listelt_t) link;
171 /*% The parser object. */
177 unsigned int warnings;
180 /*% We are at the end of all input. */
181 isc_boolean_t seen_eof;
183 /*% The current token has been pushed back. */
184 isc_boolean_t ungotten;
187 * The stack of currently active files, represented
188 * as a configuration list of configuration strings.
189 * The head is the top-level file, subsequent elements
190 * (if any) are the nested include files, and the
191 * last element is the file currently being parsed.
193 cfg_obj_t * open_files;
196 * Names of files that we have parsed and closed
197 * and were previously on the open_file list.
198 * We keep these objects around after closing
199 * the files because the file names may still be
200 * referenced from other configuration objects
201 * for use in reporting semantic errors after
202 * parsing is complete.
204 cfg_obj_t * closed_files;
207 * Current line number. We maintain our own
208 * copy of this so that it is available even
209 * when a file has just been closed.
213 cfg_parsecallback_t callback;
220 * Flags defining whether to accept certain types of network addresses.
222 #define CFG_ADDR_V4OK 0x00000001
223 #define CFG_ADDR_V4PREFIXOK 0x00000002
224 #define CFG_ADDR_V6OK 0x00000004
225 #define CFG_ADDR_WILDOK 0x00000008
226 #define CFG_ADDR_MASK (CFG_ADDR_V6OK|CFG_ADDR_V4OK)
231 * Predefined data representation types.
233 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint32;
234 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint64;
235 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_string;
236 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_boolean;
237 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_map;
238 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_list;
239 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_tuple;
240 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_sockaddr;
241 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix;
242 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void;
247 * Predefined configuration object types.
249 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_boolean;
250 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint32;
251 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint64;
252 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_qstring;
253 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring;
254 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring;
255 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr;
256 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr;
257 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4;
258 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4wild;
259 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6;
260 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6wild;
261 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netprefix;
262 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_void;
263 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token;
264 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported;
268 cfg_gettoken(cfg_parser_t *pctx, int options);
271 cfg_peektoken(cfg_parser_t *pctx, int options);
274 cfg_ungettoken(cfg_parser_t *pctx);
276 #define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE)
279 cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
282 cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u);
285 cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
288 cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj);
291 cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj);
294 cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
297 cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj);
300 cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
303 cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na);
306 cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na);
309 cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags);
312 cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port);
315 cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
318 cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj);
321 cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type);
324 cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
327 cfg_parse_special(cfg_parser_t *pctx, int special);
328 /*%< Parse a required special character 'special'. */
331 cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
334 cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
337 cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj);
340 cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type);
343 cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
346 cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype,
347 cfg_listelt_t **ret);
350 cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
353 cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj);
356 cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type);
359 cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
362 cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj);
365 cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
368 cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type);
371 cfg_print_chars(cfg_printer_t *pctx, const char *text, int len);
372 /*%< Print 'len' characters at 'text' */
375 cfg_print_cstr(cfg_printer_t *pctx, const char *s);
376 /*%< Print the null-terminated string 's' */
379 cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
382 cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
385 cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
388 cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **
392 cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj);
395 cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type);
398 cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
401 cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj);
404 cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type);
407 cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
410 cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj);
413 cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type);
416 cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
419 cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj);
422 cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type);
424 * Print a description of the grammar of an arbitrary configuration
429 cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type);
431 * Document the type 'type' as a terminal by printing its
432 * name in angle brackets, e.g., <uint32>.
436 cfg_parser_error(cfg_parser_t *pctx, unsigned int flags,
437 const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);
439 * Pass one of these flags to cfg_parser_error() to include the
440 * token text in log message.
442 #define CFG_LOG_NEAR 0x00000001 /*%< Say "near <token>" */
443 #define CFG_LOG_BEFORE 0x00000002 /*%< Say "before <token>" */
444 #define CFG_LOG_NOPREP 0x00000004 /*%< Say just "<token>" */
447 cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags,
448 const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);
451 cfg_is_enum(const char *s, const char *const *enums);
452 /*%< Return true iff the string 's' is one of the strings in 'enums' */
454 #endif /* ISCCFG_GRAMMAR_H */