]> jfr.im git - solanum.git/blob - ircd/ircd_lexer.l
extensions/helpops: implement DEHELPER command
[solanum.git] / ircd / ircd_lexer.l
1 /* src/ircd_lexer.l
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
16 * USA
17 *
18 * $Id: ircd_lexer.l 3540 2007-07-30 17:26:00Z jilles $
19 */
20
21 %option case-insensitive
22 %option noyywrap
23 %option nounput
24
25 %{
26 #include <sys/types.h>
27 #include <sys/stat.h>
28
29 #include <netinet/in.h>
30
31 #include <string.h>
32 #include <errno.h>
33 #include <limits.h>
34
35 #define WE_ARE_MEMORY_C
36
37 #include "stdinc.h"
38 #include "ircd_defs.h"
39 #include "common.h"
40 #include "config.h"
41 #include "logger.h"
42 #include "s_conf.h"
43 #include "newconf.h"
44
45 #include "ircd_parser.h"
46
47 int yylex(void);
48
49 #define MAX_INCLUDE_DEPTH 10
50
51 YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
52 int include_stack_ptr=0;
53 int lineno = 1;
54 void ccomment(void);
55 void cinclude(void);
56 void hashcomment(void);
57 int ieof(void);
58 int lineno_stack[MAX_INCLUDE_DEPTH];
59 char conffile_stack[MAX_INCLUDE_DEPTH][IRCD_BUFSIZE];
60 char conffilebuf[IRCD_BUFSIZE+1];
61 char *current_file = conffilebuf;
62
63 FILE *inc_fbfile_in[MAX_INCLUDE_DEPTH];
64
65 char linebuf[512];
66
67 #undef YY_INPUT
68
69 #define YY_FATAL_ERROR(msg) conf_yy_fatal_error(msg)
70
71 #define YY_INPUT(buf,result,max_size) \
72 if (!(result = conf_fgets(buf, max_size, conf_fbfile_in))) \
73 YY_FATAL_ERROR("input in flex scanner failed");
74 %}
75
76 ws [ \t]*
77 digit [0-9]
78 comment #.*
79 qstring \"[^\"\n]*[\"\n]
80 string [a-zA-Z_\~\:][a-zA-Z0-9_\:]*
81 include \.include{ws}(\<.*\>|\".*\")
82
83 %%
84 {include} { cinclude(); }
85 "/*" { ccomment(); }
86 \n.* { strcpy(linebuf, yytext+1); lineno++; yyless(1); }
87
88 {ws} ;
89 {comment} { hashcomment(); }
90
91 {digit}+ { yylval.number = atoi(yytext); return NUMBER; }
92
93 {qstring} {
94 if(yytext[yyleng-2] == '\\')
95 {
96 yyless(yyleng-1); /* return last quote */
97 yymore(); /* append next string */
98 }
99 else
100 {
101 strcpy(yylval.string, yytext + 1);
102 if(yylval.string[yyleng-2] != '"')
103 ilog(L_MAIN, "Unterminated character string");
104 else
105 {
106 int i,j;
107 yylval.string[yyleng-2] = '\0'; /* remove close
108 * quote
109 */
110
111 for (j=i=0 ;yylval.string[i] != '\0'; i++,j++)
112 {
113 if (yylval.string[i] != '\\')
114 {
115 yylval.string[j] = yylval.string[i];
116 }
117 else
118 {
119 i++;
120 if (yylval.string[i] == '\0') /* XXX
121 * should not
122 * happen
123 */
124 {
125 ilog(L_MAIN,
126 "Unterminated character string");
127 break;
128 }
129 yylval.string[j] = yylval.string[i];
130 }
131 }
132 yylval.string[j] = '\0';
133 return QSTRING;
134 }
135 }
136 }
137
138
139 loadmodule { return LOADMODULE; }
140 {string} {
141 strcpy(yylval.string, yytext);
142 yylval.string[yyleng] = '\0';
143 return STRING;
144 }
145
146 \.\. { return TWODOTS; }
147 . { return yytext[0]; }
148 <<EOF>> { if (ieof()) yyterminate(); }
149 %%
150
151 /* C-comment ignoring routine -kre*/
152 void ccomment()
153 {
154 int c;
155
156 /* log(L_NOTICE, "got comment"); */
157 while (1)
158 {
159 while ((c = input()) != '*' && c != EOF)
160 if (c == '\n') ++lineno;
161 if (c == '*')
162 {
163 while ((c = input()) == '*');
164 if (c == '/')
165 break;
166 if (c == '\n') ++lineno;
167 }
168 if (c == EOF)
169 {
170 YY_FATAL_ERROR("EOF in comment");
171 /* XXX hack alert this disables
172 * the stupid unused function warning
173 * gcc generates
174 */
175 yy_fatal_error("EOF in comment");
176 break;
177 }
178 }
179 }
180
181 void cinclude(void)
182 {
183 char *c;
184 if ((c = strchr(yytext, '<')) == NULL)
185 *strchr(c = strchr(yytext, '"') + 1, '"') = 0;
186 else
187 *strchr(++c, '>') = 0;
188
189 /* do stacking and co. */
190 if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
191 conf_report_error("Includes nested too deep (max is %d)", MAX_INCLUDE_DEPTH);
192 else
193 {
194 FILE *tmp_fbfile_in;
195
196 tmp_fbfile_in = fopen(c, "r");
197
198 if (tmp_fbfile_in == NULL)
199 {
200 /* if its not found in PREFIX, look in ETCPATH */
201 char fnamebuf[IRCD_BUFSIZE];
202
203 snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", ETCPATH, c);
204 tmp_fbfile_in = fopen(fnamebuf, "r");
205
206 /* wasnt found there either.. error. */
207 if(tmp_fbfile_in == NULL)
208 {
209 conf_report_error("Include %s: %s.", c, strerror(errno));
210 return;
211 }
212 }
213 lineno_stack[include_stack_ptr] = lineno;
214 lineno = 1;
215 inc_fbfile_in[include_stack_ptr] = conf_fbfile_in;
216 strcpy(conffile_stack[include_stack_ptr], c);
217 current_file = conffile_stack[include_stack_ptr];
218 include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
219 conf_fbfile_in = tmp_fbfile_in;
220 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
221 }
222 }
223
224 int ieof(void)
225 {
226 if (include_stack_ptr)
227 fclose(conf_fbfile_in);
228 if (--include_stack_ptr < 0)
229 {
230 /* We will now exit the lexer - restore init values if we get /rehash
231 * later and reenter lexer -kre */
232 include_stack_ptr = 0;
233 lineno = 1;
234 return 1;
235 }
236 /* switch buffer */
237 yy_delete_buffer(YY_CURRENT_BUFFER);
238 lineno = lineno_stack[include_stack_ptr];
239 conf_fbfile_in = inc_fbfile_in[include_stack_ptr];
240
241 if(include_stack_ptr)
242 current_file = conffile_stack[include_stack_ptr];
243 else
244 current_file = conffilebuf;
245
246 yy_switch_to_buffer(include_stack[include_stack_ptr]);
247 return 0;
248 }
249
250 /* #-comment style, look for #include */
251 #define INCLUDE "#include"
252
253 void hashcomment(void)
254 {
255 if (strlen(yytext) < sizeof(INCLUDE) - 1)
256 return;
257
258 if (!strncasecmp(yytext, INCLUDE, sizeof(INCLUDE) - 1))
259 yyerror("You probably meant '.include', skipping");
260 }