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