Home | History | Annotate | Line # | Download | only in ntpd
      1 /*	$NetBSD: ntp_scanner.h,v 1.5 2020/05/25 20:47:25 christos Exp $	*/
      2 
      3 /* ntp_scanner.h
      4  *
      5  * The header file for a simple lexical analyzer.
      6  *
      7  * Written By:	Sachin Kamboj
      8  *		University of Delaware
      9  *		Newark, DE 19711
     10  * Copyright (c) 2006
     11  */
     12 
     13 #ifndef NTP_SCANNER_H
     14 #define NTP_SCANNER_H
     15 
     16 #include "ntp_config.h"
     17 
     18 /*
     19  * ntp.conf syntax is slightly irregular in that some tokens such as
     20  * hostnames do not require quoting even if they might otherwise be
     21  * recognized as T_ terminal tokens.  This hand-crafted lexical scanner
     22  * uses a "followed by" value associated with each keyword to indicate
     23  * normal scanning of the next token, forced scanning of the next token
     24  * alone as a T_String, or forced scanning of all tokens to the end of
     25  * the command as T_String.
     26  * In the past the identifiers for this functionality ended in _ARG:
     27  *
     28  * NO_ARG	->	FOLLBY_TOKEN
     29  * SINGLE_ARG	->	FOLLBY_STRING
     30  * MULTIPLE_ARG	->	FOLLBY_STRINGS_TO_EOC
     31  *
     32  * Note that some tokens use FOLLBY_TOKEN even though they sometimes
     33  * are followed by strings.  FOLLBY_STRING is used only when needed to
     34  * avoid the keyword scanner matching a token where a string is needed.
     35  *
     36  * FOLLBY_NON_ACCEPT is an overloading of this field to distinguish
     37  * non-accepting states (where the state number does not match a T_
     38  * value).
     39  */
     40 typedef enum {
     41 	FOLLBY_TOKEN = 0,
     42 	FOLLBY_STRING,
     43 	FOLLBY_STRINGS_TO_EOC,
     44 	FOLLBY_NON_ACCEPTING
     45 } follby;
     46 
     47 #define MAXLINE		1024	/* maximum length of line */
     48 #define MAXINCLUDELEVEL	5	/* maximum include file levels */
     49 
     50 /* STRUCTURES
     51  * ----------
     52  */
     53 
     54 /*
     55  * Define a structure to hold the FSA for the keywords.
     56  * The structure is actually a trie.
     57  *
     58  * To save space, a single u_int32 encodes four fields, and a fifth
     59  * (the token completed for terminal states) is implied by the index of
     60  * the rule within the scan state array, taking advantage of the fact
     61  * there are more scan states than the highest T_ token number.
     62  *
     63  * The lowest 8 bits hold the character the state matches on.
     64  * Bits 8 and 9 hold the followedby value (0 - 3).  For non-accepting
     65  *   states (which do not match a completed token) the followedby
     66  *   value 3 (FOLLBY_NONACCEPTING) denotes that fact.  For accepting
     67  *   states, values 0 - 2 control whether the scanner forces the
     68  *   following token(s) to strings.
     69  * Bits 10 through 20 hold the next state to check not matching
     70  * this state's character.
     71  * Bits 21 through 31 hold the next state to check matching the char.
     72  */
     73 
     74 #define S_ST(ch, fb, match_n, other_n) (			\
     75 	(u_char)((ch) & 0xff) |					\
     76 	((u_int32)(fb) << 8) |					\
     77 	((u_int32)(match_n) << 10) |				\
     78 	((u_int32)(other_n) << 21)				\
     79 )
     80 
     81 #define SS_CH(ss)	((char)(u_char)((ss) & 0xff))
     82 #define SS_FB(ss)	(((u_int)(ss) >>  8) & 0x3)
     83 #define SS_MATCH_N(ss)	(((u_int)(ss) >> 10) & 0x7ff)
     84 #define SS_OTHER_N(ss)	(((u_int)(ss) >> 21) & 0x7ff)
     85 
     86 typedef u_int32 scan_state;
     87 
     88 struct LCPOS {
     89 	int nline;
     90 	int ncol;
     91 };
     92 
     93 /* Structure to hold a filename, file pointer and positional info.
     94  * Instances are dynamically allocated, and the file name is copied by
     95  * value into a dynamic extension of the 'fname' array. (Which *must* be
     96  * the last field for that reason!)
     97  */
     98 struct FILE_INFO {
     99 	struct FILE_INFO * st_next;	/* next on stack */
    100 	FILE *		   fpi;		/* File Descriptor */
    101 	int                force_eof;	/* locked or not */
    102 	int                backch;	/* ungetch buffer */
    103 
    104 	struct LCPOS       curpos;	/* current scan position */
    105 	struct LCPOS       bakpos;	/* last line end for ungetc */
    106 	struct LCPOS       tokpos;	/* current token position */
    107 	struct LCPOS       errpos;	/* error position */
    108 
    109 	char               fname[1];	/* (formal only) buffered name */
    110 };
    111 
    112 
    113 /* SCANNER GLOBAL VARIABLES
    114  * ------------------------
    115  */
    116 extern config_tree cfgt;	  /* Parser output stored here */
    117 
    118 /* VARIOUS EXTERNAL DECLARATIONS
    119  * -----------------------------
    120  */
    121 extern int old_config_style;
    122 
    123 /* VARIOUS SUBROUTINE DECLARATIONS
    124  * -------------------------------
    125  */
    126 extern const char *keyword(int token);
    127 extern char *quote_if_needed(char *str);
    128 int yylex(void);
    129 
    130 /* managing the input source stack itself */
    131 extern int/*BOOL*/ lex_init_stack(const char * path, const char * mode);
    132 extern void        lex_drop_stack(void);
    133 extern int/*BOOL*/ lex_flush_stack(void);
    134 
    135 /* add/remove a nested input source */
    136 extern int/*BOOL*/ lex_push_file(const char * path, const char * mode);
    137 extern int/*BOOL*/ lex_pop_file(void);
    138 
    139 /* input stack state query functions */
    140 extern size_t      lex_level(void);
    141 extern int/*BOOL*/ lex_from_file(void);
    142 extern struct FILE_INFO * lex_current(void);
    143 
    144 #endif	/* NTP_SCANNER_H */
    145