/[svn]/ircd-hybrid/src/conf/lexer.l
ViewVC logotype

Contents of /ircd-hybrid/src/conf/lexer.l

Parent Directory Parent Directory | Revision Log Revision Log


Revision 712 - (show annotations)
Sat Jul 8 12:13:14 2006 UTC (15 years, 6 months ago) by michael
File size: 6950 byte(s)
- Also show the full path of .included configuration files when reporting
  syntax errors.  This is just cosmetical.

1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * lexer.l: A set of rules for flex.
4 *
5 * Copyright (C) 2003 by Piotr Nizynski, Advanced IRC Services Project
6 * Copyright (C) 2005 by the Hybrid Development Team.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 *
23 * $Id: conf_lexer.l,v 1.5 2003/10/14 16:18:56 adx Exp $
24 */
25
26 %option case-insensitive
27 %option noyywrap
28 %option nounput
29 %option never-interactive
30
31 %x IN_COMMENT
32
33 %{
34
35 #include "stdinc.h"
36 #include "conf/conf.h"
37 #include "y.tab.h"
38
39 #undef YY_INPUT
40 #define YY_INPUT(buf, res, siz) res = conf_yy_input(buf, siz)
41 /* flex's default is to print a message and exit(0) */
42 #define YY_FATAL_ERROR(msg) conf_yy_fatal_error(msg)
43
44 #define MAX_INCLUDE_DEPTH 10
45
46 static int conf_include_sptr = 0;
47 static YY_BUFFER_STATE conf_include_yystack[MAX_INCLUDE_DEPTH];
48 struct ConfParserContext conf_include_ctxstack[MAX_INCLUDE_DEPTH];
49
50 static void conf_include(void);
51 static int conf_eof(void);
52 static int conf_yy_fatal_error(const char *msg)
53 {
54 return 0;
55 }
56
57 %}
58
59 WS [ \t]*
60 DIGIT [[:digit:]]+
61 INCLUDE \.include{WS}(\<.*\>|\".*\")
62 COMMENT ("//"|"#").*
63 qstring \"[^\"\n]*[\"\n]
64 IDENTIFIER [a-zA-Z_][a-zA-Z0-9_:]*
65
66 %%
67
68 "/*" { BEGIN IN_COMMENT; }
69 <IN_COMMENT>"*/" { BEGIN INITIAL; }
70 <IN_COMMENT>. ; /* eat everything but a newline */
71 <IN_COMMENT>\n { ++conf_curctx.lineno; }
72 <IN_COMMENT><<EOF>> { BEGIN INITIAL; if (conf_eof()) yyterminate(); }
73
74 {INCLUDE} { conf_include(); }
75 \n.* { ++conf_curctx.lineno;
76 strlcpy(conf_linebuf, yytext + 1, CONF_BUFSIZE);
77 yyless(1);
78 }
79 {WS} ;
80 {COMMENT} ;
81 {DIGIT} { yylval.number = atoi(yytext); return NUMBER; }
82 {qstring} {
83 if (yytext[yyleng - 2] == '\\')
84 {
85 yyless(yyleng - 1); /* return last quote */
86 yymore(); /* append next string */
87 }
88 else
89 {
90 yylval.string = yytext + 1;
91
92 if (yylval.string[yyleng - 2] != '"')
93 ilog(L_ERROR, "Unterminated character string");
94 else
95 {
96 int i = 0, j = 0;
97
98 yylval.string[yyleng - 2] = '\0'; /* remove close quote */
99
100 for (; yylval.string[i]; ++i, ++j)
101 {
102 if (yylval.string[i] == '\\')
103 {
104 if (yylval.string[++i] == '\0')
105 {
106 ilog(L_ERROR, "Unterminated character string");
107 break;
108 }
109 }
110
111 yylval.string[j] = yylval.string[i];
112 }
113
114 yylval.string[j] = '\0';
115 return QSTRING;
116 }
117 }
118 }
119
120 b { return BYTES; }
121 byte { return BYTES; }
122 bytes { return BYTES; }
123 d { return DAYS; }
124 day { return DAYS; }
125 days { return DAYS; }
126 false { yylval.number = 0; return BOOL; }
127 h { return HOURS; }
128 hour { return HOURS; }
129 hours { return HOURS; }
130 kb { return KBYTES; }
131 kbyte { return KBYTES; }
132 kbytes { return KBYTES; }
133 kilobyte { return KBYTES; }
134 kilobytes { return KBYTES; }
135 mb { return MBYTES; }
136 mbyte { return MBYTES; }
137 mbytes { return MBYTES; }
138 megabyte { return MBYTES; }
139 megabytes { return MBYTES; }
140 m { return MINUTES; }
141 min { return MINUTES; }
142 mins { return MINUTES; }
143 minute { return MINUTES; }
144 minutes { return MINUTES; }
145 no { yylval.number = 0; return BOOL; }
146 off { yylval.number = 0; return BOOL; }
147 on { yylval.number = 1; return BOOL; }
148 s { return SECONDS; }
149 sec { return SECONDS; }
150 secs { return SECONDS; }
151 second { return SECONDS; }
152 seconds { return SECONDS; }
153 true { yylval.number = 1; return BOOL; }
154 w { return WEEKS; }
155 week { return WEEKS; }
156 weeks { return WEEKS; }
157 yes { yylval.number = 1; return BOOL; }
158 {IDENTIFIER} { yylval.string = yytext; return IDENTIFIER; }
159 . { return yytext[0]; }
160 <<EOF>> { if (conf_eof()) yyterminate(); }
161
162 %%
163
164 /*
165 * conf_include()
166 *
167 * Enters a new configuration file.
168 *
169 * inputs: none
170 * output: none
171 */
172 static void
173 conf_include(void)
174 {
175 char filenamebuf[IRCD_BUFSIZE];
176 char *fname = NULL;
177 FBFILE *f = NULL;
178
179 if ((fname = strchr(yytext, '"')) == NULL)
180 *strchr(fname = strchr(yytext, '<') + 1, '>') = '\0';
181 else
182 *strchr(++fname, '"') = '\0';
183
184 if (conf_include_sptr == MAX_INCLUDE_DEPTH)
185 {
186 ilog(L_ERROR, "Includes nested too deep", fname);
187 return;
188 }
189
190 if (*fname == '/') /* if it is an absolute path */
191 snprintf(filenamebuf, sizeof(filenamebuf), "%s", fname);
192 else
193 snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ETCPATH, fname);
194
195 if ((f = fbopen(filenamebuf, "r")))
196 {
197 ilog(L_ERROR, "Unable to read configuration file '%s': %s",
198 filenamebuf, strerror(errno));
199 return;
200 }
201
202 /* save current state */
203 memcpy(&conf_include_ctxstack[conf_include_sptr], &conf_curctx,
204 sizeof(struct ConfParserContext));
205 conf_include_yystack[conf_include_sptr++] = YY_CURRENT_BUFFER;
206
207 /* switch lexer context */
208 conf_linebuf[0] = '\0';
209
210 conf_curctx.lineno = 1;
211 conf_curctx.f = f;
212 DupString(conf_curctx.filename, filenamebuf);
213
214 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
215 }
216
217 /*
218 * conf_eof()
219 *
220 * Ends processing of a configuration file.
221 *
222 * inputs: none
223 * output: 1 if the parser should be exited, 0 otherwise
224 */
225 static int
226 conf_eof(void)
227 {
228 if (conf_include_sptr == 0)
229 return 1;
230
231 /* destroy current buffer */
232 yy_delete_buffer(YY_CURRENT_BUFFER);
233 MyFree(conf_curctx.filename);
234 fbclose(conf_curctx.f);
235
236 /* restore old context */
237 conf_linebuf[0] = '\0';
238 memcpy(&conf_curctx, &conf_include_ctxstack[--conf_include_sptr],
239 sizeof(struct ConfParserContext));
240 yy_switch_to_buffer(conf_include_yystack[conf_include_sptr]);
241
242 return 0;
243 yy_fatal_error(NULL); /* use it somewhere to avoid the warning */
244 }

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28