/contrib/bind9/lib/isccfg/include/isccfg/grammar.h

https://bitbucket.org/freebsd/freebsd-head/ · C Header · 474 lines · 259 code · 95 blank · 120 comment · 0 complexity · 89df11fc36fe8f1c93cb2ffb1fc98359 MD5 · raw file

  1. /*
  2. * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 2002, 2003 Internet Software Consortium.
  4. *
  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.
  8. *
  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.
  16. */
  17. /* $Id: grammar.h,v 1.24 2011/01/04 23:47:14 tbox Exp $ */
  18. #ifndef ISCCFG_GRAMMAR_H
  19. #define ISCCFG_GRAMMAR_H 1
  20. /*! \file isccfg/grammar.h */
  21. #include <isc/lex.h>
  22. #include <isc/netaddr.h>
  23. #include <isc/sockaddr.h>
  24. #include <isc/region.h>
  25. #include <isc/types.h>
  26. #include <isccfg/cfg.h>
  27. /*
  28. * Definitions shared between the configuration parser
  29. * and the grammars; not visible to users of the parser.
  30. */
  31. /*% Clause may occur multiple times (e.g., "zone") */
  32. #define CFG_CLAUSEFLAG_MULTI 0x00000001
  33. /*% Clause is obsolete */
  34. #define CFG_CLAUSEFLAG_OBSOLETE 0x00000002
  35. /*% Clause is not implemented, and may never be */
  36. #define CFG_CLAUSEFLAG_NOTIMP 0x00000004
  37. /*% Clause is not implemented yet */
  38. #define CFG_CLAUSEFLAG_NYI 0x00000008
  39. /*% Default value has changed since earlier release */
  40. #define CFG_CLAUSEFLAG_NEWDEFAULT 0x00000010
  41. /*%
  42. * Clause needs to be interpreted during parsing
  43. * by calling a callback function, like the
  44. * "directory" option.
  45. */
  46. #define CFG_CLAUSEFLAG_CALLBACK 0x00000020
  47. /*% A option that is only used in testing. */
  48. #define CFG_CLAUSEFLAG_TESTONLY 0x00000040
  49. /*% A configuration option that was not configured at compile time. */
  50. #define CFG_CLAUSEFLAG_NOTCONFIGURED 0x00000080
  51. typedef struct cfg_clausedef cfg_clausedef_t;
  52. typedef struct cfg_tuplefielddef cfg_tuplefielddef_t;
  53. typedef struct cfg_printer cfg_printer_t;
  54. typedef ISC_LIST(cfg_listelt_t) cfg_list_t;
  55. typedef struct cfg_map cfg_map_t;
  56. typedef struct cfg_rep cfg_rep_t;
  57. /*
  58. * Function types for configuration object methods
  59. */
  60. typedef isc_result_t (*cfg_parsefunc_t)(cfg_parser_t *, const cfg_type_t *type,
  61. cfg_obj_t **);
  62. typedef void (*cfg_printfunc_t)(cfg_printer_t *, const cfg_obj_t *);
  63. typedef void (*cfg_docfunc_t)(cfg_printer_t *, const cfg_type_t *);
  64. typedef void (*cfg_freefunc_t)(cfg_parser_t *, cfg_obj_t *);
  65. /*
  66. * Structure definitions
  67. */
  68. /*%
  69. * A configuration printer object. This is an abstract
  70. * interface to a destination to which text can be printed
  71. * by calling the function 'f'.
  72. */
  73. struct cfg_printer {
  74. void (*f)(void *closure, const char *text, int textlen);
  75. void *closure;
  76. int indent;
  77. };
  78. /*% A clause definition. */
  79. struct cfg_clausedef {
  80. const char *name;
  81. cfg_type_t *type;
  82. unsigned int flags;
  83. };
  84. /*% A tuple field definition. */
  85. struct cfg_tuplefielddef {
  86. const char *name;
  87. cfg_type_t *type;
  88. unsigned int flags;
  89. };
  90. /*% A configuration object type definition. */
  91. struct cfg_type {
  92. const char *name; /*%< For debugging purposes only */
  93. cfg_parsefunc_t parse;
  94. cfg_printfunc_t print;
  95. cfg_docfunc_t doc; /*%< Print grammar description */
  96. cfg_rep_t * rep; /*%< Data representation */
  97. const void * of; /*%< Additional data for meta-types */
  98. };
  99. /*% A keyword-type definition, for things like "port <integer>". */
  100. typedef struct {
  101. const char *name;
  102. const cfg_type_t *type;
  103. } keyword_type_t;
  104. struct cfg_map {
  105. cfg_obj_t *id; /*%< Used for 'named maps' like keys, zones, &c */
  106. const cfg_clausedef_t * const *clausesets; /*%< The clauses that
  107. can occur in this map;
  108. used for printing */
  109. isc_symtab_t *symtab;
  110. };
  111. typedef struct cfg_netprefix cfg_netprefix_t;
  112. struct cfg_netprefix {
  113. isc_netaddr_t address; /* IP4/IP6 */
  114. unsigned int prefixlen;
  115. };
  116. /*%
  117. * A configuration data representation.
  118. */
  119. struct cfg_rep {
  120. const char * name; /*%< For debugging only */
  121. cfg_freefunc_t free; /*%< How to free this kind of data. */
  122. };
  123. /*%
  124. * A configuration object. This is the main building block
  125. * of the configuration parse tree.
  126. */
  127. struct cfg_obj {
  128. const cfg_type_t *type;
  129. union {
  130. isc_uint32_t uint32;
  131. isc_uint64_t uint64;
  132. isc_textregion_t string; /*%< null terminated, too */
  133. isc_boolean_t boolean;
  134. cfg_map_t map;
  135. cfg_list_t list;
  136. cfg_obj_t ** tuple;
  137. isc_sockaddr_t sockaddr;
  138. cfg_netprefix_t netprefix;
  139. } value;
  140. isc_refcount_t references; /*%< reference counter */
  141. const char * file;
  142. unsigned int line;
  143. };
  144. /*% A list element. */
  145. struct cfg_listelt {
  146. cfg_obj_t *obj;
  147. ISC_LINK(cfg_listelt_t) link;
  148. };
  149. /*% The parser object. */
  150. struct cfg_parser {
  151. isc_mem_t * mctx;
  152. isc_log_t * lctx;
  153. isc_lex_t * lexer;
  154. unsigned int errors;
  155. unsigned int warnings;
  156. isc_token_t token;
  157. /*% We are at the end of all input. */
  158. isc_boolean_t seen_eof;
  159. /*% The current token has been pushed back. */
  160. isc_boolean_t ungotten;
  161. /*%
  162. * The stack of currently active files, represented
  163. * as a configuration list of configuration strings.
  164. * The head is the top-level file, subsequent elements
  165. * (if any) are the nested include files, and the
  166. * last element is the file currently being parsed.
  167. */
  168. cfg_obj_t * open_files;
  169. /*%
  170. * Names of files that we have parsed and closed
  171. * and were previously on the open_file list.
  172. * We keep these objects around after closing
  173. * the files because the file names may still be
  174. * referenced from other configuration objects
  175. * for use in reporting semantic errors after
  176. * parsing is complete.
  177. */
  178. cfg_obj_t * closed_files;
  179. /*%
  180. * Current line number. We maintain our own
  181. * copy of this so that it is available even
  182. * when a file has just been closed.
  183. */
  184. unsigned int line;
  185. /*%
  186. * Parser context flags, used for maintaining state
  187. * from one token to the next.
  188. */
  189. unsigned int flags;
  190. /*%< Reference counter */
  191. isc_refcount_t references;
  192. cfg_parsecallback_t callback;
  193. void *callbackarg;
  194. };
  195. /* Parser context flags */
  196. #define CFG_PCTX_SKIP 0x1
  197. /*@{*/
  198. /*%
  199. * Flags defining whether to accept certain types of network addresses.
  200. */
  201. #define CFG_ADDR_V4OK 0x00000001
  202. #define CFG_ADDR_V4PREFIXOK 0x00000002
  203. #define CFG_ADDR_V6OK 0x00000004
  204. #define CFG_ADDR_WILDOK 0x00000008
  205. #define CFG_ADDR_MASK (CFG_ADDR_V6OK|CFG_ADDR_V4OK)
  206. /*@}*/
  207. /*@{*/
  208. /*%
  209. * Predefined data representation types.
  210. */
  211. LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint32;
  212. LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint64;
  213. LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_string;
  214. LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_boolean;
  215. LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_map;
  216. LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_list;
  217. LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_tuple;
  218. LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_sockaddr;
  219. LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix;
  220. LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void;
  221. /*@}*/
  222. /*@{*/
  223. /*%
  224. * Predefined configuration object types.
  225. */
  226. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_boolean;
  227. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint32;
  228. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint64;
  229. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_qstring;
  230. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring;
  231. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring;
  232. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr;
  233. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr;
  234. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4;
  235. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4wild;
  236. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6;
  237. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6wild;
  238. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netprefix;
  239. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_void;
  240. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token;
  241. LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported;
  242. /*@}*/
  243. isc_result_t
  244. cfg_gettoken(cfg_parser_t *pctx, int options);
  245. isc_result_t
  246. cfg_peektoken(cfg_parser_t *pctx, int options);
  247. void
  248. cfg_ungettoken(cfg_parser_t *pctx);
  249. #define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE)
  250. isc_result_t
  251. cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
  252. void
  253. cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u);
  254. isc_result_t
  255. cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  256. void
  257. cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj);
  258. void
  259. cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj);
  260. isc_result_t
  261. cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  262. void
  263. cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj);
  264. isc_result_t
  265. cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  266. isc_result_t
  267. cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na);
  268. void
  269. cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na);
  270. isc_boolean_t
  271. cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags);
  272. isc_result_t
  273. cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port);
  274. isc_result_t
  275. cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  276. isc_result_t
  277. cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  278. void
  279. cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj);
  280. void
  281. cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj);
  282. void
  283. cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type);
  284. isc_result_t
  285. cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  286. isc_result_t
  287. cfg_parse_special(cfg_parser_t *pctx, int special);
  288. /*%< Parse a required special character 'special'. */
  289. isc_result_t
  290. cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
  291. isc_result_t
  292. cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  293. void
  294. cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj);
  295. void
  296. cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type);
  297. isc_result_t
  298. cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
  299. isc_result_t
  300. cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype,
  301. cfg_listelt_t **ret);
  302. isc_result_t
  303. cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  304. void
  305. cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj);
  306. void
  307. cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type);
  308. isc_result_t
  309. cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  310. void
  311. cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj);
  312. isc_result_t
  313. cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  314. void
  315. cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type);
  316. void
  317. cfg_print_chars(cfg_printer_t *pctx, const char *text, int len);
  318. /*%< Print 'len' characters at 'text' */
  319. void
  320. cfg_print_cstr(cfg_printer_t *pctx, const char *s);
  321. /*%< Print the null-terminated string 's' */
  322. isc_result_t
  323. cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  324. isc_result_t
  325. cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  326. isc_result_t
  327. cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  328. isc_result_t
  329. cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **
  330. ret);
  331. void
  332. cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj);
  333. void
  334. cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type);
  335. isc_result_t
  336. cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  337. void
  338. cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj);
  339. void
  340. cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type);
  341. isc_result_t
  342. cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  343. void
  344. cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj);
  345. void
  346. cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type);
  347. isc_result_t
  348. cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
  349. void
  350. cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj);
  351. void
  352. cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type);
  353. /*%<
  354. * Print a description of the grammar of an arbitrary configuration
  355. * type 'type'
  356. */
  357. void
  358. cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type);
  359. /*%<
  360. * Document the type 'type' as a terminal by printing its
  361. * name in angle brackets, e.g., &lt;uint32>.
  362. */
  363. void
  364. cfg_parser_error(cfg_parser_t *pctx, unsigned int flags,
  365. const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);
  366. /*!
  367. * Pass one of these flags to cfg_parser_error() to include the
  368. * token text in log message.
  369. */
  370. #define CFG_LOG_NEAR 0x00000001 /*%< Say "near <token>" */
  371. #define CFG_LOG_BEFORE 0x00000002 /*%< Say "before <token>" */
  372. #define CFG_LOG_NOPREP 0x00000004 /*%< Say just "<token>" */
  373. void
  374. cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags,
  375. const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);
  376. isc_boolean_t
  377. cfg_is_enum(const char *s, const char *const *enums);
  378. /*%< Return true iff the string 's' is one of the strings in 'enums' */
  379. #endif /* ISCCFG_GRAMMAR_H */