]> jfr.im git - solanum.git/blob - ircd/ircd_parser.y
Add a comment explaining match_arrange_stars
[solanum.git] / ircd / ircd_parser.y
1 /* This code is in the public domain.
2 * $Nightmare: nightmare/src/main/parser.y,v 1.2.2.1.2.1 2002/07/02 03:42:10 ejb Exp $
3 */
4
5 %{
6 #include <sys/types.h>
7 #include <sys/stat.h>
8
9 #include <string.h>
10 #include <stdlib.h>
11 #include <stdarg.h>
12 #include <stdio.h>
13 #define WE_ARE_MEMORY_C
14 #include "stdinc.h"
15 #include "setup.h"
16 #include "ircd_defs.h"
17 #include "defaults.h"
18 #include "client.h"
19 #include "modules.h"
20 #include "newconf.h"
21
22 #define YY_NO_UNPUT
23
24 int yyparse(void);
25 void yyerror(const char *);
26 int yylex(void);
27
28 static time_t conf_find_time(char*);
29
30 static struct {
31 const char * name;
32 const char * plural;
33 time_t val;
34 } ircd_times[] = {
35 {"second", "seconds", 1},
36 {"minute", "minutes", 60},
37 {"hour", "hours", 60 * 60},
38 {"day", "days", 60 * 60 * 24},
39 {"week", "weeks", 60 * 60 * 24 * 7},
40 {"fortnight", "fortnights", 60 * 60 * 24 * 14},
41 {"month", "months", 60 * 60 * 24 * 7 * 4},
42 {"year", "years", 60 * 60 * 24 * 365},
43 /* ok-- we now do sizes here too. they aren't times, but
44 it's close enough */
45 {"byte", "bytes", 1},
46 {"kb", NULL, 1024},
47 {"kbyte", "kbytes", 1024},
48 {"kilobyte", "kilebytes", 1024},
49 {"mb", NULL, 1024 * 1024},
50 {"mbyte", "mbytes", 1024 * 1024},
51 {"megabyte", "megabytes", 1024 * 1024},
52 {NULL, NULL, 0},
53 };
54
55 time_t conf_find_time(char *name)
56 {
57 int i;
58
59 for (i = 0; ircd_times[i].name; i++)
60 {
61 if (rb_strcasecmp(ircd_times[i].name, name) == 0 ||
62 (ircd_times[i].plural && rb_strcasecmp(ircd_times[i].plural, name) == 0))
63 return ircd_times[i].val;
64 }
65
66 return 0;
67 }
68
69 static struct
70 {
71 const char *word;
72 int yesno;
73 } yesno[] = {
74 {"yes", 1},
75 {"no", 0},
76 {"true", 1},
77 {"false", 0},
78 {"on", 1},
79 {"off", 0},
80 {NULL, 0}
81 };
82
83 static int conf_get_yesno_value(char *str)
84 {
85 int i;
86
87 for (i = 0; yesno[i].word; i++)
88 {
89 if (rb_strcasecmp(str, yesno[i].word) == 0)
90 {
91 return yesno[i].yesno;
92 }
93 }
94
95 return -1;
96 }
97
98 static void free_cur_list(conf_parm_t* list)
99 {
100 if (list->type == CF_STRING || list->type == CF_QSTRING) {
101 rb_free(list->v.string);
102 } else if (list->type == CF_FLIST) {
103 /* Even though CF_FLIST is a flag, comparing with == is valid
104 * because conf_parm_t.type must be either a type or one flag.
105 */
106 free_cur_list(list->v.list);
107 }
108
109 if (list->next) {
110 free_cur_list(list->next);
111 }
112
113 rb_free(list);
114 }
115
116
117 conf_parm_t * cur_list = NULL;
118
119 static void add_cur_list_cpt(conf_parm_t *new)
120 {
121 if (cur_list == NULL)
122 {
123 cur_list = rb_malloc(sizeof(conf_parm_t));
124 cur_list->type = CF_FLIST;
125 cur_list->v.list = new;
126 }
127 else
128 {
129 new->next = cur_list->v.list;
130 cur_list->v.list = new;
131 }
132 }
133
134 static void add_cur_list(int type, char *str, int number)
135 {
136 conf_parm_t *new;
137
138 new = rb_malloc(sizeof(conf_parm_t));
139 new->next = NULL;
140 new->type = type;
141
142 switch(type)
143 {
144 case CF_INT:
145 case CF_TIME:
146 case CF_YESNO:
147 new->v.number = number;
148 break;
149 case CF_STRING:
150 case CF_QSTRING:
151 new->v.string = rb_strdup(str);
152 break;
153 }
154
155 add_cur_list_cpt(new);
156 }
157
158
159 %}
160
161 %union {
162 int number;
163 char string[1024];
164 conf_parm_t * conf_parm;
165 }
166
167 %token LOADMODULE TWODOTS
168
169 %token <string> QSTRING STRING
170 %token <number> NUMBER
171
172 %type <string> qstring string
173 %type <number> number timespec
174 %type <conf_parm> oneitem single itemlist
175
176 %start conf
177
178 %%
179
180 conf:
181 | conf conf_item
182 | error
183 ;
184
185 conf_item: block
186 | loadmodule
187 ;
188
189 block: string
190 {
191 conf_start_block($1, NULL);
192 }
193 '{' block_items '}' ';'
194 {
195 if (conf_cur_block)
196 conf_end_block(conf_cur_block);
197 }
198 | string qstring
199 {
200 conf_start_block($1, $2);
201 }
202 '{' block_items '}' ';'
203 {
204 if (conf_cur_block)
205 conf_end_block(conf_cur_block);
206 }
207 ;
208
209 block_items: block_items block_item
210 | block_item
211 ;
212
213 block_item: string '=' itemlist ';'
214 {
215 conf_call_set(conf_cur_block, $1, cur_list);
216 free_cur_list(cur_list);
217 cur_list = NULL;
218 }
219 ;
220
221 itemlist: itemlist ',' single
222 | single
223 ;
224
225 single: oneitem
226 {
227 add_cur_list_cpt($1);
228 }
229 | oneitem TWODOTS oneitem
230 {
231 /* "1 .. 5" meaning 1,2,3,4,5 - only valid for integers */
232 if ($1->type != CF_INT || $3->type != CF_INT)
233 {
234 conf_report_error("Both arguments in '..' notation must be integers.");
235 break;
236 }
237 else
238 {
239 int i;
240
241 for (i = $1->v.number; i <= $3->v.number; i++)
242 {
243 add_cur_list(CF_INT, 0, i);
244 }
245
246 rb_free($1);
247 rb_free($3);
248 }
249 }
250 ;
251
252 oneitem: qstring
253 {
254 $$ = rb_malloc(sizeof(conf_parm_t));
255 $$->type = CF_QSTRING;
256 $$->v.string = rb_strdup($1);
257 }
258 | timespec
259 {
260 $$ = rb_malloc(sizeof(conf_parm_t));
261 $$->type = CF_TIME;
262 $$->v.number = $1;
263 }
264 | number
265 {
266 $$ = rb_malloc(sizeof(conf_parm_t));
267 $$->type = CF_INT;
268 $$->v.number = $1;
269 }
270 | string
271 {
272 /* a 'string' could also be a yes/no value ..
273 so pass it as that, if so */
274 int val = conf_get_yesno_value($1);
275
276 $$ = rb_malloc(sizeof(conf_parm_t));
277
278 if (val != -1)
279 {
280 $$->type = CF_YESNO;
281 $$->v.number = val;
282 }
283 else
284 {
285 $$->type = CF_STRING;
286 $$->v.string = rb_strdup($1);
287 }
288 }
289 ;
290
291 loadmodule:
292 LOADMODULE QSTRING
293 {
294 char *m_bn;
295 m_bn = rb_basename((char *) $2);
296
297 if (findmodule_byname(m_bn) == NULL)
298 {
299 load_one_module($2, MAPI_ORIGIN_EXTENSION, 0);
300 }
301
302 rb_free(m_bn);
303 }
304 ';'
305 ;
306
307 qstring: QSTRING { strcpy($$, $1); } ;
308 string: STRING { strcpy($$, $1); } ;
309 number: NUMBER { $$ = $1; } ;
310
311 timespec: number string
312 {
313 time_t t;
314
315 if ((t = conf_find_time($2)) == 0)
316 {
317 conf_report_error("Unrecognised time type/size '%s'", $2);
318 t = 1;
319 }
320
321 $$ = $1 * t;
322 }
323 | timespec timespec
324 {
325 $$ = $1 + $2;
326 }
327 | timespec number
328 {
329 $$ = $1 + $2;
330 }
331 ;