2013-12-04 21:33:17 +00:00
|
|
|
/* ntp_scanner.h
|
|
|
|
*
|
|
|
|
* The header file for a simple lexical analyzer.
|
|
|
|
*
|
|
|
|
* Written By: Sachin Kamboj
|
|
|
|
* University of Delaware
|
|
|
|
* Newark, DE 19711
|
|
|
|
* Copyright (c) 2006
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef NTP_SCANNER_H
|
|
|
|
#define NTP_SCANNER_H
|
|
|
|
|
2014-12-20 22:52:39 +00:00
|
|
|
#include "ntp_config.h"
|
|
|
|
|
2013-12-04 21:33:17 +00:00
|
|
|
/*
|
|
|
|
* ntp.conf syntax is slightly irregular in that some tokens such as
|
|
|
|
* hostnames do not require quoting even if they might otherwise be
|
|
|
|
* recognized as T_ terminal tokens. This hand-crafted lexical scanner
|
|
|
|
* uses a "followed by" value associated with each keyword to indicate
|
|
|
|
* normal scanning of the next token, forced scanning of the next token
|
|
|
|
* alone as a T_String, or forced scanning of all tokens to the end of
|
|
|
|
* the command as T_String.
|
|
|
|
* In the past the identifiers for this functionality ended in _ARG:
|
|
|
|
*
|
|
|
|
* NO_ARG -> FOLLBY_TOKEN
|
|
|
|
* SINGLE_ARG -> FOLLBY_STRING
|
|
|
|
* MULTIPLE_ARG -> FOLLBY_STRINGS_TO_EOC
|
|
|
|
*
|
|
|
|
* Note that some tokens use FOLLBY_TOKEN even though they sometimes
|
|
|
|
* are followed by strings. FOLLBY_STRING is used only when needed to
|
|
|
|
* avoid the keyword scanner matching a token where a string is needed.
|
|
|
|
*
|
|
|
|
* FOLLBY_NON_ACCEPT is an overloading of this field to distinguish
|
|
|
|
* non-accepting states (where the state number does not match a T_
|
|
|
|
* value).
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
FOLLBY_TOKEN = 0,
|
|
|
|
FOLLBY_STRING,
|
|
|
|
FOLLBY_STRINGS_TO_EOC,
|
|
|
|
FOLLBY_NON_ACCEPTING
|
|
|
|
} follby;
|
|
|
|
|
|
|
|
#define MAXLINE 1024 /* maximum length of line */
|
|
|
|
#define MAXINCLUDELEVEL 5 /* maximum include file levels */
|
|
|
|
|
|
|
|
/* STRUCTURES
|
|
|
|
* ----------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Define a structure to hold the FSA for the keywords.
|
|
|
|
* The structure is actually a trie.
|
|
|
|
*
|
|
|
|
* To save space, a single u_int32 encodes four fields, and a fifth
|
|
|
|
* (the token completed for terminal states) is implied by the index of
|
|
|
|
* the rule within the scan state array, taking advantage of the fact
|
|
|
|
* there are more scan states than the highest T_ token number.
|
|
|
|
*
|
|
|
|
* The lowest 8 bits hold the character the state matches on.
|
|
|
|
* Bits 8 and 9 hold the followedby value (0 - 3). For non-accepting
|
|
|
|
* states (which do not match a completed token) the followedby
|
|
|
|
* value 3 (FOLLBY_NONACCEPTING) denotes that fact. For accepting
|
|
|
|
* states, values 0 - 2 control whether the scanner forces the
|
|
|
|
* following token(s) to strings.
|
|
|
|
* Bits 10 through 20 hold the next state to check not matching
|
|
|
|
* this state's character.
|
|
|
|
* Bits 21 through 31 hold the next state to check matching the char.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define S_ST(ch, fb, match_n, other_n) ( \
|
|
|
|
(u_char)((ch) & 0xff) | \
|
|
|
|
((u_int32)(fb) << 8) | \
|
|
|
|
((u_int32)(match_n) << 10) | \
|
|
|
|
((u_int32)(other_n) << 21) \
|
|
|
|
)
|
|
|
|
|
|
|
|
#define SS_CH(ss) ((char)(u_char)((ss) & 0xff))
|
|
|
|
#define SS_FB(ss) (((u_int)(ss) >> 8) & 0x3)
|
|
|
|
#define SS_MATCH_N(ss) (((u_int)(ss) >> 10) & 0x7ff)
|
|
|
|
#define SS_OTHER_N(ss) (((u_int)(ss) >> 21) & 0x7ff)
|
|
|
|
|
|
|
|
typedef u_int32 scan_state;
|
|
|
|
|
2015-07-01 03:12:13 +00:00
|
|
|
struct LCPOS {
|
|
|
|
int nline;
|
|
|
|
int ncol;
|
|
|
|
};
|
2013-12-04 21:33:17 +00:00
|
|
|
|
2015-07-01 03:12:13 +00:00
|
|
|
/* Structure to hold a filename, file pointer and positional info.
|
|
|
|
* Instances are dynamically allocated, and the file name is copied by
|
|
|
|
* value into a dynamic extension of the 'fname' array. (Which *must* be
|
|
|
|
* the last field for that reason!)
|
|
|
|
*/
|
2013-12-04 21:33:17 +00:00
|
|
|
struct FILE_INFO {
|
2015-07-01 03:12:13 +00:00
|
|
|
struct FILE_INFO * st_next; /* next on stack */
|
|
|
|
FILE * fpi; /* File Descriptor */
|
|
|
|
int force_eof; /* locked or not */
|
|
|
|
int backch; /* ungetch buffer */
|
|
|
|
|
|
|
|
struct LCPOS curpos; /* current scan position */
|
|
|
|
struct LCPOS bakpos; /* last line end for ungetc */
|
|
|
|
struct LCPOS tokpos; /* current token position */
|
|
|
|
struct LCPOS errpos; /* error position */
|
|
|
|
|
|
|
|
char fname[1]; /* (formal only) buffered name */
|
2013-12-04 21:33:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* SCANNER GLOBAL VARIABLES
|
|
|
|
* ------------------------
|
|
|
|
*/
|
2014-12-20 22:52:39 +00:00
|
|
|
extern config_tree cfgt; /* Parser output stored here */
|
2013-12-04 21:33:17 +00:00
|
|
|
|
|
|
|
/* VARIOUS EXTERNAL DECLARATIONS
|
|
|
|
* -----------------------------
|
|
|
|
*/
|
|
|
|
extern int old_config_style;
|
|
|
|
|
|
|
|
/* VARIOUS SUBROUTINE DECLARATIONS
|
|
|
|
* -------------------------------
|
|
|
|
*/
|
|
|
|
extern const char *keyword(int token);
|
|
|
|
extern char *quote_if_needed(char *str);
|
2015-07-01 03:12:13 +00:00
|
|
|
int yylex(void);
|
|
|
|
|
|
|
|
/* managing the input source stack itself */
|
|
|
|
extern int/*BOOL*/ lex_init_stack(const char * path, const char * mode);
|
|
|
|
extern void lex_drop_stack(void);
|
|
|
|
extern int/*BOOL*/ lex_flush_stack(void);
|
|
|
|
|
|
|
|
/* add/remove a nested input source */
|
|
|
|
extern int/*BOOL*/ lex_push_file(const char * path, const char * mode);
|
|
|
|
extern int/*BOOL*/ lex_pop_file(void);
|
2013-12-04 21:33:17 +00:00
|
|
|
|
2015-07-01 03:12:13 +00:00
|
|
|
/* input stack state query functions */
|
|
|
|
extern size_t lex_level(void);
|
|
|
|
extern int/*BOOL*/ lex_from_file(void);
|
|
|
|
extern struct FILE_INFO * lex_current(void);
|
2013-12-04 21:33:17 +00:00
|
|
|
|
|
|
|
#endif /* NTP_SCANNER_H */
|