]> jfr.im git - irc/rqf/shadowircd.git/blame - src/ircd_lexer.l
Add topic TS and channel TS constraints for /LIST.
[irc/rqf/shadowircd.git] / src / ircd_lexer.l
CommitLineData
212380e3 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 *
4f3f411b 18 * $Id: ircd_lexer.l 3540 2007-07-30 17:26:00Z jilles $
212380e3 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"
ba05bde6 41#include "logger.h"
212380e3 42#include "s_conf.h"
43#include "newconf.h"
44
45#include "y.tab.h"
46
47int yylex(void);
48
212380e3 49#define MAX_INCLUDE_DEPTH 10
50
51YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
52int include_stack_ptr=0;
53int lineno = 1;
54void ccomment(void);
55void cinclude(void);
56void hashcomment(void);
57int ieof(void);
58int lineno_stack[MAX_INCLUDE_DEPTH];
59char conffile_stack[MAX_INCLUDE_DEPTH][IRCD_BUFSIZE];
60char conffilebuf[IRCD_BUFSIZE+1];
61char *current_file = conffilebuf;
62
63FILE *inc_fbfile_in[MAX_INCLUDE_DEPTH];
64
65char 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
76ws [ \t]*
77digit [0-9]
78comment #.*
79qstring \"[^\"\n]*[\"\n]
7ce46e04 80string [a-zA-Z_\~\:][a-zA-Z0-9_\:]*
212380e3 81include \.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
139loadmodule { 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*/
152void 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;
4f3f411b 166 if (c == '\n') ++lineno;
212380e3 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
181void 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
224int 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
253void 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}