summaryrefslogtreecommitdiffstats
path: root/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_scanner.h
blob: 11bbfe914be56bb675b1cc47824176bb60bff631 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* 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

#include "ntp_config.h"

/*
 * 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;

struct LCPOS {
	int nline;
	int ncol;
};

/* 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!)
 */
struct FILE_INFO {
	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 */
};


/* SCANNER GLOBAL VARIABLES 
 * ------------------------
 */
extern config_tree cfgt;	  /* Parser output stored here */

/* VARIOUS EXTERNAL DECLARATIONS
 * -----------------------------
 */
extern int old_config_style;

/* VARIOUS SUBROUTINE DECLARATIONS
 * -------------------------------
 */
extern const char *keyword(int token);
extern char *quote_if_needed(char *str);
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);

/* 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);

#endif	/* NTP_SCANNER_H */