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