"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.17.5/lib/isc/include/isc/lex.h" (4 Sep 2020, 9786 Bytes) of package /linux/misc/dns/bind9/9.17.5/bind-9.17.5.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "lex.h" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 #ifndef ISC_LEX_H
   13 #define ISC_LEX_H 1
   14 
   15 /*****
   16 ***** Module Info
   17 *****/
   18 
   19 /*! \file isc/lex.h
   20  * \brief The "lex" module provides a lightweight tokenizer.  It can operate
   21  * on files or buffers, and can handle "include".  It is designed for
   22  * parsing of DNS master files and the BIND configuration file, but
   23  * should be general enough to tokenize other things, e.g. HTTP.
   24  *
   25  * \li MP:
   26  *  No synchronization is provided.  Clients must ensure exclusive
   27  *  access.
   28  *
   29  * \li Reliability:
   30  *  No anticipated impact.
   31  *
   32  * \li Resources:
   33  *  TBS
   34  *
   35  * \li Security:
   36  *  No anticipated impact.
   37  *
   38  * \li Standards:
   39  *  None.
   40  */
   41 
   42 /***
   43  *** Imports
   44  ***/
   45 
   46 #include <stdbool.h>
   47 #include <stdio.h>
   48 
   49 #include <isc/lang.h>
   50 #include <isc/region.h>
   51 #include <isc/types.h>
   52 
   53 ISC_LANG_BEGINDECLS
   54 
   55 /***
   56  *** Options
   57  ***/
   58 
   59 /*@{*/
   60 /*!
   61  * Various options for isc_lex_gettoken().
   62  */
   63 
   64 #define ISC_LEXOPT_EOL       0x01 /*%< Want end-of-line token. */
   65 #define ISC_LEXOPT_EOF       0x02 /*%< Want end-of-file token. */
   66 #define ISC_LEXOPT_INITIALWS 0x04 /*%< Want initial whitespace. */
   67 #define ISC_LEXOPT_NUMBER    0x08 /*%< Recognize numbers. */
   68 #define ISC_LEXOPT_QSTRING   0x10 /*%< Recognize qstrings. */
   69 /*@}*/
   70 
   71 /*@{*/
   72 /*!
   73  * The ISC_LEXOPT_DNSMULTILINE option handles the processing of '(' and ')' in
   74  * the DNS master file format.  If this option is set, then the
   75  * ISC_LEXOPT_INITIALWS and ISC_LEXOPT_EOL options will be ignored when
   76  * the paren count is > 0.  To use this option, '(' and ')' must be special
   77  * characters.
   78  */
   79 #define ISC_LEXOPT_DNSMULTILINE 0x20 /*%< Handle '(' and ')'. */
   80 #define ISC_LEXOPT_NOMORE   0x40 /*%< Want "no more" token. */
   81 
   82 #define ISC_LEXOPT_CNUMBER      0x80  /*%< Recognize octal and hex. */
   83 #define ISC_LEXOPT_ESCAPE       0x100 /*%< Recognize escapes. */
   84 #define ISC_LEXOPT_QSTRINGMULTILINE 0x200 /*%< Allow multiline "" strings */
   85 #define ISC_LEXOPT_OCTAL        0x400 /*%< Expect a octal number. */
   86 #define ISC_LEXOPT_BTEXT        0x800 /*%< Bracketed text. */
   87 /*@}*/
   88 /*@{*/
   89 /*!
   90  * Various commenting styles, which may be changed at any time with
   91  * isc_lex_setcomments().
   92  */
   93 
   94 #define ISC_LEXCOMMENT_C         0x01
   95 #define ISC_LEXCOMMENT_CPLUSPLUS     0x02
   96 #define ISC_LEXCOMMENT_SHELL         0x04
   97 #define ISC_LEXCOMMENT_DNSMASTERFILE 0x08
   98 /*@}*/
   99 
  100 /***
  101  *** Types
  102  ***/
  103 
  104 /*! Lex */
  105 
  106 typedef char isc_lexspecials_t[256];
  107 
  108 /* Tokens */
  109 
  110 typedef enum {
  111     isc_tokentype_unknown = 0,
  112     isc_tokentype_string = 1,
  113     isc_tokentype_number = 2,
  114     isc_tokentype_qstring = 3,
  115     isc_tokentype_eol = 4,
  116     isc_tokentype_eof = 5,
  117     isc_tokentype_initialws = 6,
  118     isc_tokentype_special = 7,
  119     isc_tokentype_nomore = 8,
  120     isc_tokentype_btext = 8
  121 } isc_tokentype_t;
  122 
  123 typedef union {
  124     char         as_char;
  125     unsigned long    as_ulong;
  126     isc_region_t     as_region;
  127     isc_textregion_t as_textregion;
  128     void *       as_pointer;
  129 } isc_tokenvalue_t;
  130 
  131 typedef struct isc_token {
  132     isc_tokentype_t  type;
  133     isc_tokenvalue_t value;
  134 } isc_token_t;
  135 
  136 /***
  137  *** Functions
  138  ***/
  139 
  140 isc_result_t
  141 isc_lex_create(isc_mem_t *mctx, size_t max_token, isc_lex_t **lexp);
  142 /*%<
  143  * Create a lexer.
  144  *
  145  * 'max_token' is a hint of the number of bytes in the largest token.
  146  *
  147  * Requires:
  148  *\li   '*lexp' is a valid lexer.
  149  *
  150  * Ensures:
  151  *\li   On success, *lexp is attached to the newly created lexer.
  152  *
  153  * Returns:
  154  *\li   #ISC_R_SUCCESS
  155  *\li   #ISC_R_NOMEMORY
  156  */
  157 
  158 void
  159 isc_lex_destroy(isc_lex_t **lexp);
  160 /*%<
  161  * Destroy the lexer.
  162  *
  163  * Requires:
  164  *\li   '*lexp' is a valid lexer.
  165  *
  166  * Ensures:
  167  *\li   *lexp == NULL
  168  */
  169 
  170 unsigned int
  171 isc_lex_getcomments(isc_lex_t *lex);
  172 /*%<
  173  * Return the current lexer commenting styles.
  174  *
  175  * Requires:
  176  *\li   'lex' is a valid lexer.
  177  *
  178  * Returns:
  179  *\li   The commenting styles which are currently allowed.
  180  */
  181 
  182 void
  183 isc_lex_setcomments(isc_lex_t *lex, unsigned int comments);
  184 /*%<
  185  * Set allowed lexer commenting styles.
  186  *
  187  * Requires:
  188  *\li   'lex' is a valid lexer.
  189  *
  190  *\li   'comments' has meaningful values.
  191  */
  192 
  193 void
  194 isc_lex_getspecials(isc_lex_t *lex, isc_lexspecials_t specials);
  195 /*%<
  196  * Put the current list of specials into 'specials'.
  197  *
  198  * Requires:
  199  *\li   'lex' is a valid lexer.
  200  */
  201 
  202 void
  203 isc_lex_setspecials(isc_lex_t *lex, isc_lexspecials_t specials);
  204 /*!<
  205  * The characters in 'specials' are returned as tokens.  Along with
  206  * whitespace, they delimit strings and numbers.
  207  *
  208  * Note:
  209  *\li   Comment processing takes precedence over special character
  210  *  recognition.
  211  *
  212  * Requires:
  213  *\li   'lex' is a valid lexer.
  214  */
  215 
  216 isc_result_t
  217 isc_lex_openfile(isc_lex_t *lex, const char *filename);
  218 /*%<
  219  * Open 'filename' and make it the current input source for 'lex'.
  220  *
  221  * Requires:
  222  *\li   'lex' is a valid lexer.
  223  *
  224  *\li   filename is a valid C string.
  225  *
  226  * Returns:
  227  *\li   #ISC_R_SUCCESS
  228  *\li   #ISC_R_NOMEMORY         Out of memory
  229  *\li   #ISC_R_NOTFOUND         File not found
  230  *\li   #ISC_R_NOPERM           No permission to open file
  231  *\li   #ISC_R_FAILURE          Couldn't open file, not sure why
  232  *\li   #ISC_R_UNEXPECTED
  233  */
  234 
  235 isc_result_t
  236 isc_lex_openstream(isc_lex_t *lex, FILE *stream);
  237 /*%<
  238  * Make 'stream' the current input source for 'lex'.
  239  *
  240  * Requires:
  241  *\li   'lex' is a valid lexer.
  242  *
  243  *\li   'stream' is a valid C stream.
  244  *
  245  * Returns:
  246  *\li   #ISC_R_SUCCESS
  247  *\li   #ISC_R_NOMEMORY         Out of memory
  248  */
  249 
  250 isc_result_t
  251 isc_lex_openbuffer(isc_lex_t *lex, isc_buffer_t *buffer);
  252 /*%<
  253  * Make 'buffer' the current input source for 'lex'.
  254  *
  255  * Requires:
  256  *\li   'lex' is a valid lexer.
  257  *
  258  *\li   'buffer' is a valid buffer.
  259  *
  260  * Returns:
  261  *\li   #ISC_R_SUCCESS
  262  *\li   #ISC_R_NOMEMORY         Out of memory
  263  */
  264 
  265 isc_result_t
  266 isc_lex_close(isc_lex_t *lex);
  267 /*%<
  268  * Close the most recently opened object (i.e. file or buffer).
  269  *
  270  * Returns:
  271  *\li   #ISC_R_SUCCESS
  272  *\li   #ISC_R_NOMORE           No more input sources
  273  */
  274 
  275 isc_result_t
  276 isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp);
  277 /*%<
  278  * Get the next token.
  279  *
  280  * Requires:
  281  *\li   'lex' is a valid lexer.
  282  *
  283  *\li   'lex' has an input source.
  284  *
  285  *\li   'options' contains valid options.
  286  *
  287  *\li   '*tokenp' is a valid pointer.
  288  *
  289  * Returns:
  290  *\li   #ISC_R_SUCCESS
  291  *\li   #ISC_R_UNEXPECTEDEND
  292  *\li   #ISC_R_NOMEMORY
  293  *
  294  *  These two results are returned only if their corresponding lexer
  295  *  options are not set.
  296  *
  297  *\li   #ISC_R_EOF          End of input source
  298  *\li   #ISC_R_NOMORE           No more input sources
  299  */
  300 
  301 isc_result_t
  302 isc_lex_getmastertoken(isc_lex_t *lex, isc_token_t *token,
  303                isc_tokentype_t expect, bool eol);
  304 /*%<
  305  * Get the next token from a DNS master file type stream.  This is a
  306  * convenience function that sets appropriate options and handles quoted
  307  * strings and end of line correctly for master files.  It also ungets
  308  * unexpected tokens.  If `eol` is set then expect end-of-line otherwise
  309  * eol is a error.
  310  *
  311  * Requires:
  312  *\li   'lex' is a valid lexer.
  313  *
  314  *\li   'token' is a valid pointer
  315  *
  316  * Returns:
  317  *
  318  * \li  any return code from isc_lex_gettoken().
  319  */
  320 
  321 isc_result_t
  322 isc_lex_getoctaltoken(isc_lex_t *lex, isc_token_t *token, bool eol);
  323 /*%<
  324  * Get the next token from a DNS master file type stream.  This is a
  325  * convenience function that sets appropriate options and handles end
  326  * of line correctly for master files.  It also ungets unexpected tokens.
  327  * If `eol` is set then expect end-of-line otherwise eol is a error.
  328  *
  329  * Requires:
  330  *\li   'lex' is a valid lexer.
  331  *
  332  *\li   'token' is a valid pointer
  333  *
  334  * Returns:
  335  *
  336  * \li  any return code from isc_lex_gettoken().
  337  */
  338 
  339 void
  340 isc_lex_ungettoken(isc_lex_t *lex, isc_token_t *tokenp);
  341 /*%<
  342  * Unget the current token.
  343  *
  344  * Requires:
  345  *\li   'lex' is a valid lexer.
  346  *
  347  *\li   'lex' has an input source.
  348  *
  349  *\li   'tokenp' points to a valid token.
  350  *
  351  *\li   There is no ungotten token already.
  352  */
  353 
  354 void
  355 isc_lex_getlasttokentext(isc_lex_t *lex, isc_token_t *tokenp, isc_region_t *r);
  356 /*%<
  357  * Returns a region containing the text of the last token returned.
  358  *
  359  * Requires:
  360  *\li   'lex' is a valid lexer.
  361  *
  362  *\li   'lex' has an input source.
  363  *
  364  *\li   'tokenp' points to a valid token.
  365  *
  366  *\li   A token has been gotten and not ungotten.
  367  */
  368 
  369 char *
  370 isc_lex_getsourcename(isc_lex_t *lex);
  371 /*%<
  372  * Return the input source name.
  373  *
  374  * Requires:
  375  *\li   'lex' is a valid lexer.
  376  *
  377  * Returns:
  378  * \li  source name or NULL if no current source.
  379  *\li   result valid while current input source exists.
  380  */
  381 
  382 unsigned long
  383 isc_lex_getsourceline(isc_lex_t *lex);
  384 /*%<
  385  * Return the input source line number.
  386  *
  387  * Requires:
  388  *\li   'lex' is a valid lexer.
  389  *
  390  * Returns:
  391  *\li   Current line number or 0 if no current source.
  392  */
  393 
  394 isc_result_t
  395 isc_lex_setsourcename(isc_lex_t *lex, const char *name);
  396 /*%<
  397  * Assigns a new name to the input source.
  398  *
  399  * Requires:
  400  *
  401  * \li  'lex' is a valid lexer.
  402  *
  403  * Returns:
  404  * \li  #ISC_R_SUCCESS
  405  * \li  #ISC_R_NOMEMORY
  406  * \li  #ISC_R_NOTFOUND - there are no sources.
  407  */
  408 
  409 isc_result_t
  410 isc_lex_setsourceline(isc_lex_t *lex, unsigned long line);
  411 /*%<
  412  * Assigns a new line number to the input source. This can be used
  413  * when parsing a buffer that's been excerpted from the middle a file,
  414  * allowing logged messages to display the correct line number,
  415  * rather than the line number within the buffer.
  416  *
  417  * Requires:
  418  *
  419  * \li  'lex' is a valid lexer.
  420  *
  421  * Returns:
  422  * \li  #ISC_R_SUCCESS
  423  * \li  #ISC_R_NOTFOUND - there are no sources.
  424  */
  425 
  426 bool
  427 isc_lex_isfile(isc_lex_t *lex);
  428 /*%<
  429  * Return whether the current input source is a file.
  430  *
  431  * Requires:
  432  *\li   'lex' is a valid lexer.
  433  *
  434  * Returns:
  435  * \li  #true if the current input is a file,
  436  *\li   #false otherwise.
  437  */
  438 
  439 ISC_LANG_ENDDECLS
  440 
  441 #endif /* ISC_LEX_H */