grammar.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004-2011, 2013, 2014  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 2002, 2003  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id: grammar.h,v 1.24 2011/01/04 23:47:14 tbox Exp $ */
00019 
00020 #ifndef ISCCFG_GRAMMAR_H
00021 #define ISCCFG_GRAMMAR_H 1
00022 
00023 /*! \file isccfg/grammar.h */
00024 
00025 #include <isc/lex.h>
00026 #include <isc/netaddr.h>
00027 #include <isc/sockaddr.h>
00028 #include <isc/region.h>
00029 #include <isc/types.h>
00030 
00031 #include <isccfg/cfg.h>
00032 
00033 /*
00034  * Definitions shared between the configuration parser
00035  * and the grammars; not visible to users of the parser.
00036  */
00037 
00038 /*% Clause may occur multiple times (e.g., "zone") */
00039 #define CFG_CLAUSEFLAG_MULTI            0x00000001
00040 /*% Clause is obsolete */
00041 #define CFG_CLAUSEFLAG_OBSOLETE         0x00000002
00042 /*% Clause is not implemented, and may never be */
00043 #define CFG_CLAUSEFLAG_NOTIMP           0x00000004
00044 /*% Clause is not implemented yet */
00045 #define CFG_CLAUSEFLAG_NYI              0x00000008
00046 /*% Default value has changed since earlier release */
00047 #define CFG_CLAUSEFLAG_NEWDEFAULT       0x00000010
00048 /*%
00049  * Clause needs to be interpreted during parsing
00050  * by calling a callback function, like the
00051  * "directory" option.
00052  */
00053 #define CFG_CLAUSEFLAG_CALLBACK         0x00000020
00054 /*% A option that is only used in testing. */
00055 #define CFG_CLAUSEFLAG_TESTONLY         0x00000040
00056 /*% A configuration option that was not configured at compile time. */
00057 #define CFG_CLAUSEFLAG_NOTCONFIGURED    0x00000080
00058 
00059 typedef struct cfg_clausedef cfg_clausedef_t;
00060 typedef struct cfg_tuplefielddef cfg_tuplefielddef_t;
00061 typedef struct cfg_printer cfg_printer_t;
00062 typedef ISC_LIST(cfg_listelt_t) cfg_list_t;
00063 typedef struct cfg_map cfg_map_t;
00064 typedef struct cfg_rep cfg_rep_t;
00065 
00066 /*
00067  * Function types for configuration object methods
00068  */
00069 
00070 typedef isc_result_t (*cfg_parsefunc_t)(cfg_parser_t *, const cfg_type_t *type,
00071                                         cfg_obj_t **);
00072 typedef void         (*cfg_printfunc_t)(cfg_printer_t *, const cfg_obj_t *);
00073 typedef void         (*cfg_docfunc_t)(cfg_printer_t *, const cfg_type_t *);
00074 typedef void         (*cfg_freefunc_t)(cfg_parser_t *, cfg_obj_t *);
00075 
00076 /*
00077  * Structure definitions
00078  */
00079 
00080 /*%
00081  * A configuration printer object.  This is an abstract
00082  * interface to a destination to which text can be printed
00083  * by calling the function 'f'.
00084  */
00085 struct cfg_printer {
00086         void (*f)(void *closure, const char *text, int textlen);
00087         void *closure;
00088         int indent;
00089         int flags;
00090 };
00091 
00092 /*% A clause definition. */
00093 struct cfg_clausedef {
00094         const char      *name;
00095         cfg_type_t      *type;
00096         unsigned int    flags;
00097 };
00098 
00099 /*% A tuple field definition. */
00100 struct cfg_tuplefielddef {
00101         const char      *name;
00102         cfg_type_t      *type;
00103         unsigned int    flags;
00104 };
00105 
00106 /*% A configuration object type definition. */
00107 struct cfg_type {
00108         const char *name;       /*%< For debugging purposes only */
00109         cfg_parsefunc_t parse;
00110         cfg_printfunc_t print;
00111         cfg_docfunc_t   doc;    /*%< Print grammar description */
00112         cfg_rep_t *     rep;    /*%< Data representation */
00113         const void *    of;     /*%< Additional data for meta-types */
00114 };
00115 
00116 /*% A keyword-type definition, for things like "port <integer>". */
00117 typedef struct {
00118         const char *name;
00119         const cfg_type_t *type;
00120 } keyword_type_t;
00121 
00122 struct cfg_map {
00123         cfg_obj_t        *id; /*%< Used for 'named maps' like keys, zones, &c */
00124         const cfg_clausedef_t * const *clausesets; /*%< The clauses that
00125                                                       can occur in this map;
00126                                                       used for printing */
00127         isc_symtab_t     *symtab;
00128 };
00129 
00130 typedef struct cfg_netprefix cfg_netprefix_t;
00131 
00132 struct cfg_netprefix {
00133         isc_netaddr_t address; /* IP4/IP6 */
00134         unsigned int prefixlen;
00135 };
00136 
00137 /*%
00138  * A configuration data representation.
00139  */
00140 struct cfg_rep {
00141         const char *    name;   /*%< For debugging only */
00142         cfg_freefunc_t  free;   /*%< How to free this kind of data. */
00143 };
00144 
00145 /*%
00146  * A configuration object.  This is the main building block
00147  * of the configuration parse tree.
00148  */
00149 
00150 struct cfg_obj {
00151         const cfg_type_t *type;
00152         union {
00153                 isc_uint32_t    uint32;
00154                 isc_uint64_t    uint64;
00155                 isc_textregion_t string; /*%< null terminated, too */
00156                 isc_boolean_t   boolean;
00157                 cfg_map_t       map;
00158                 cfg_list_t      list;
00159                 cfg_obj_t **    tuple;
00160                 isc_sockaddr_t  sockaddr;
00161                 struct {
00162                         isc_sockaddr_t  sockaddr;
00163                         isc_dscp_t      dscp;
00164                 } sockaddrdscp;
00165                 cfg_netprefix_t netprefix;
00166         }               value;
00167         isc_refcount_t  references;     /*%< reference counter */
00168         const char *    file;
00169         unsigned int    line;
00170 };
00171 
00172 
00173 /*% A list element. */
00174 struct cfg_listelt {
00175         cfg_obj_t               *obj;
00176         ISC_LINK(cfg_listelt_t)  link;
00177 };
00178 
00179 /*% The parser object. */
00180 struct cfg_parser {
00181         isc_mem_t *     mctx;
00182         isc_log_t *     lctx;
00183         isc_lex_t *     lexer;
00184         unsigned int    errors;
00185         unsigned int    warnings;
00186         isc_token_t     token;
00187 
00188         /*% We are at the end of all input. */
00189         isc_boolean_t   seen_eof;
00190 
00191         /*% The current token has been pushed back. */
00192         isc_boolean_t   ungotten;
00193 
00194         /*%
00195          * The stack of currently active files, represented
00196          * as a configuration list of configuration strings.
00197          * The head is the top-level file, subsequent elements
00198          * (if any) are the nested include files, and the
00199          * last element is the file currently being parsed.
00200          */
00201         cfg_obj_t *     open_files;
00202 
00203         /*%
00204          * Names of files that we have parsed and closed
00205          * and were previously on the open_file list.
00206          * We keep these objects around after closing
00207          * the files because the file names may still be
00208          * referenced from other configuration objects
00209          * for use in reporting semantic errors after
00210          * parsing is complete.
00211          */
00212         cfg_obj_t *     closed_files;
00213 
00214         /*%
00215          * Current line number.  We maintain our own
00216          * copy of this so that it is available even
00217          * when a file has just been closed.
00218          */
00219         unsigned int    line;
00220 
00221         /*%
00222          * Parser context flags, used for maintaining state
00223          * from one token to the next.
00224          */
00225         unsigned int flags;
00226 
00227         /*%< Reference counter */
00228         isc_refcount_t  references;
00229 
00230         cfg_parsecallback_t callback;
00231         void *callbackarg;
00232 };
00233 
00234 /* Parser context flags */
00235 #define CFG_PCTX_SKIP           0x1
00236 
00237 /*@{*/
00238 /*%
00239  * Flags defining whether to accept certain types of network addresses.
00240  */
00241 #define CFG_ADDR_V4OK           0x00000001
00242 #define CFG_ADDR_V4PREFIXOK     0x00000002
00243 #define CFG_ADDR_V6OK           0x00000004
00244 #define CFG_ADDR_WILDOK         0x00000008
00245 #define CFG_ADDR_DSCPOK         0x00000010
00246 #define CFG_ADDR_MASK           (CFG_ADDR_V6OK|CFG_ADDR_V4OK)
00247 /*@}*/
00248 
00249 /*@{*/
00250 /*%
00251  * Predefined data representation types.
00252  */
00253 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint32;
00254 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint64;
00255 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_string;
00256 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_boolean;
00257 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_map;
00258 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_list;
00259 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_tuple;
00260 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_sockaddr;
00261 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix;
00262 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void;
00263 /*@}*/
00264 
00265 /*@{*/
00266 /*%
00267  * Predefined configuration object types.
00268  */
00269 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_boolean;
00270 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint32;
00271 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint64;
00272 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_qstring;
00273 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring;
00274 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring;
00275 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sstring;
00276 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr;
00277 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddrdscp;
00278 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr;
00279 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4;
00280 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4wild;
00281 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6;
00282 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6wild;
00283 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netprefix;
00284 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_void;
00285 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token;
00286 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported;
00287 /*@}*/
00288 
00289 isc_result_t
00290 cfg_gettoken(cfg_parser_t *pctx, int options);
00291 
00292 isc_result_t
00293 cfg_peektoken(cfg_parser_t *pctx, int options);
00294 
00295 void
00296 cfg_ungettoken(cfg_parser_t *pctx);
00297 
00298 #define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE)
00299 
00300 isc_result_t
00301 cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
00302 
00303 void
00304 cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u);
00305 
00306 isc_result_t
00307 cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00308 
00309 void
00310 cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj);
00311 
00312 void
00313 cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj);
00314 
00315 isc_result_t
00316 cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00317 
00318 void
00319 cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj);
00320 
00321 isc_result_t
00322 cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00323 
00324 isc_result_t
00325 cfg_parse_sstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00326 
00327 isc_result_t
00328 cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na);
00329 
00330 void
00331 cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na);
00332 
00333 isc_boolean_t
00334 cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags);
00335 
00336 isc_result_t
00337 cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port);
00338 
00339 isc_result_t
00340 cfg_parse_dscp(cfg_parser_t *pctx, isc_dscp_t *dscp);
00341 
00342 isc_result_t
00343 cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00344 
00345 isc_result_t
00346 cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00347 
00348 void
00349 cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj);
00350 
00351 void
00352 cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj);
00353 
00354 void
00355 cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type);
00356 
00357 isc_result_t
00358 cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00359 
00360 isc_result_t
00361 cfg_parse_special(cfg_parser_t *pctx, int special);
00362 /*%< Parse a required special character 'special'. */
00363 
00364 isc_result_t
00365 cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
00366 
00367 isc_result_t
00368 cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00369 
00370 void
00371 cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj);
00372 
00373 void
00374 cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type);
00375 
00376 isc_result_t
00377 cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
00378 
00379 isc_result_t
00380 cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype,
00381                   cfg_listelt_t **ret);
00382 
00383 isc_result_t
00384 cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00385 
00386 void
00387 cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj);
00388 
00389 void
00390 cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type);
00391 
00392 isc_result_t
00393 cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00394 
00395 void
00396 cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj);
00397 
00398 isc_result_t
00399 cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00400 
00401 void
00402 cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type);
00403 
00404 void
00405 cfg_print_chars(cfg_printer_t *pctx, const char *text, int len);
00406 /*%< Print 'len' characters at 'text' */
00407 
00408 void
00409 cfg_print_cstr(cfg_printer_t *pctx, const char *s);
00410 /*%< Print the null-terminated string 's' */
00411 
00412 isc_result_t
00413 cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00414 
00415 isc_result_t
00416 cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00417 
00418 isc_result_t
00419 cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00420 
00421 isc_result_t
00422 cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **
00423 ret);
00424 
00425 void
00426 cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj);
00427 
00428 void
00429 cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type);
00430 
00431 isc_result_t
00432 cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00433 
00434 void
00435 cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj);
00436 
00437 void
00438 cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type);
00439 
00440 isc_result_t
00441 cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00442 
00443 void
00444 cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj);
00445 
00446 void
00447 cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type);
00448 
00449 isc_result_t
00450 cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00451 
00452 void
00453 cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj);
00454 
00455 void
00456 cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type);
00457 /*%<
00458  * Print a description of the grammar of an arbitrary configuration
00459  * type 'type'
00460  */
00461 
00462 void
00463 cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type);
00464 /*%<
00465  * Document the type 'type' as a terminal by printing its
00466  * name in angle brackets, e.g., &lt;uint32>.
00467  */
00468 
00469 void
00470 cfg_parser_error(cfg_parser_t *pctx, unsigned int flags,
00471                  const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);
00472 /*!
00473  * Pass one of these flags to cfg_parser_error() to include the
00474  * token text in log message.
00475  */
00476 #define CFG_LOG_NEAR    0x00000001      /*%< Say "near <token>" */
00477 #define CFG_LOG_BEFORE  0x00000002      /*%< Say "before <token>" */
00478 #define CFG_LOG_NOPREP  0x00000004      /*%< Say just "<token>" */
00479 
00480 void
00481 cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags,
00482                    const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);
00483 
00484 isc_boolean_t
00485 cfg_is_enum(const char *s, const char *const *enums);
00486 /*%< Return true iff the string 's' is one of the strings in 'enums' */
00487 
00488 #endif /* ISCCFG_GRAMMAR_H */

Generated on Tue Apr 28 17:41:06 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha