diff options
Diffstat (limited to 'src/grecs-gram.y')
-rw-r--r-- | src/grecs-gram.y | 709 |
1 files changed, 38 insertions, 671 deletions
diff --git a/src/grecs-gram.y b/src/grecs-gram.y index f65e2dd..c2429a4 100644 --- a/src/grecs-gram.y +++ b/src/grecs-gram.y | |||
@@ -22,45 +22,22 @@ | |||
22 | #include <grecs-gram.h> | 22 | #include <grecs-gram.h> |
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | #include <stdarg.h> | 24 | #include <stdarg.h> |
25 | #include <sys/types.h> | ||
26 | #include <sys/socket.h> | ||
27 | #include <sys/time.h> | ||
28 | #include <sys/un.h> | ||
29 | #include <netinet/in.h> | ||
30 | #include <arpa/inet.h> | ||
31 | #include <netdb.h> | ||
32 | #include <string.h> | 25 | #include <string.h> |
33 | #include <errno.h> | 26 | #include <errno.h> |
34 | 27 | ||
35 | typedef union | 28 | static struct grecs_node *parse_tree; |
36 | { | ||
37 | struct sockaddr s; | ||
38 | struct sockaddr_in s_in; | ||
39 | struct sockaddr_un s_un; | ||
40 | } sockaddr_union_t; | ||
41 | |||
42 | static struct grecs_keyword config_keywords; | ||
43 | static struct grecs_keyword *cursect; | ||
44 | #define CURRENT_BASE ((char*)(cursect ? cursect->callback_data : NULL)) | ||
45 | static struct grecs_list *sections; | ||
46 | int grecs_error_count; | 29 | int grecs_error_count; |
47 | 30 | ||
48 | int grecs_default_port = 0; | 31 | int grecs_default_port = 0; |
49 | 32 | ||
50 | static void *target_ptr(struct grecs_keyword *kwp, char *base); | ||
51 | static void stmt_begin(struct grecs_keyword *kwp, grecs_value_t tag); | ||
52 | static void stmt_end(struct grecs_keyword *kwp); | ||
53 | static struct grecs_keyword *find_keyword(const char *ident); | ||
54 | |||
55 | static void process_ident(struct grecs_keyword *kwp, grecs_value_t *value); | ||
56 | static struct grecs_list *simple_list_create(int dispose); | ||
57 | %} | 33 | %} |
58 | 34 | ||
59 | %union { | 35 | %union { |
60 | char *string; | 36 | char *string; |
61 | grecs_value_t value; | 37 | grecs_value_t value; |
62 | struct grecs_list *list; | 38 | struct grecs_list *list; |
63 | struct grecs_keyword *kw; | 39 | struct grecs_node *node; |
40 | struct { struct grecs_node *head, *tail; } node_list; | ||
64 | } | 41 | } |
65 | 42 | ||
66 | %token <string> IDENT STRING QSTRING MSTRING | 43 | %token <string> IDENT STRING QSTRING MSTRING |
@@ -68,39 +45,47 @@ static struct grecs_list *simple_list_create(int dispose); | |||
68 | %type <list> slist0 | 45 | %type <list> slist0 |
69 | %type <value> value tag vallist | 46 | %type <value> value tag vallist |
70 | %type <list> values list vlist | 47 | %type <list> values list vlist |
71 | %type <kw> ident | 48 | %type <node> stmt simple block |
49 | %type <node_list> stmtlist | ||
72 | 50 | ||
73 | %% | 51 | %% |
74 | 52 | ||
75 | input : stmtlist | 53 | input : stmtlist |
54 | { | ||
55 | parse_tree = $1.head; | ||
56 | } | ||
76 | ; | 57 | ; |
77 | 58 | ||
78 | stmtlist: stmt | 59 | stmtlist: stmt |
60 | { | ||
61 | $$.head = $$.tail = $1; | ||
62 | } | ||
79 | | stmtlist stmt | 63 | | stmtlist stmt |
64 | { | ||
65 | grecs_node_bind($1.tail, $2, 0); | ||
66 | } | ||
80 | ; | 67 | ; |
81 | 68 | ||
82 | stmt : simple | 69 | stmt : simple |
83 | | block | 70 | | block |
84 | ; | 71 | ; |
85 | 72 | ||
86 | simple : ident vallist ';' | 73 | simple : IDENT vallist ';' |
87 | { | ||
88 | process_ident($1, &$2); | ||
89 | } | ||
90 | ; | ||
91 | |||
92 | block : ident tag { stmt_begin($<kw>1, $<value>2); } '{' stmtlist '}' opt_sc | ||
93 | { | 74 | { |
94 | stmt_end($1); | 75 | $$ = grecs_node_create(grecs_node_stmt, |
76 | &grecs_current_locus); | ||
77 | $$->ident = $1; | ||
78 | $$->value = $2; | ||
95 | } | 79 | } |
96 | ; | 80 | ; |
97 | 81 | ||
98 | ident : IDENT | 82 | block : IDENT tag '{' stmtlist '}' opt_sc |
99 | { | 83 | { |
100 | $$ = find_keyword($1); | 84 | $$ = grecs_node_create(grecs_node_block, |
101 | if (!$$) | 85 | &grecs_current_locus); |
102 | grecs_error(&grecs_current_locus, 0, | 86 | $$->ident = $1; |
103 | _("Unknown keyword")); | 87 | $$->value = $2; |
88 | grecs_node_bind($$, $4.head, 1); | ||
104 | } | 89 | } |
105 | ; | 90 | ; |
106 | 91 | ||
@@ -135,7 +120,7 @@ vallist : vlist | |||
135 | 120 | ||
136 | vlist : value | 121 | vlist : value |
137 | { | 122 | { |
138 | $$ = simple_list_create(0); | 123 | $$ = _grecs_simple_list_create(0); |
139 | grecs_list_append($$, grecs_value_dup(&$1)); | 124 | grecs_list_append($$, grecs_value_dup(&$1)); |
140 | } | 125 | } |
141 | | vlist value | 126 | | vlist value |
@@ -169,7 +154,6 @@ string : STRING | |||
169 | slist : slist0 | 154 | slist : slist0 |
170 | { | 155 | { |
171 | struct grecs_list_entry *ep; | 156 | struct grecs_list_entry *ep; |
172 | const void *p; | ||
173 | 157 | ||
174 | grecs_line_begin(); | 158 | grecs_line_begin(); |
175 | for (ep = $1->head; ep; ep = ep->next) | 159 | for (ep = $1->head; ep; ep = ep->next) |
@@ -181,7 +165,7 @@ slist : slist0 | |||
181 | 165 | ||
182 | slist0 : QSTRING | 166 | slist0 : QSTRING |
183 | { | 167 | { |
184 | $$ = simple_list_create(0); | 168 | $$ = _grecs_simple_list_create(0); |
185 | grecs_list_append($$, $1); | 169 | grecs_list_append($$, $1); |
186 | } | 170 | } |
187 | | slist0 QSTRING | 171 | | slist0 QSTRING |
@@ -207,7 +191,7 @@ list : '(' ')' | |||
207 | 191 | ||
208 | values : value | 192 | values : value |
209 | { | 193 | { |
210 | $$ = simple_list_create(0); | 194 | $$ = _grecs_simple_list_create(0); |
211 | grecs_list_append($$, grecs_value_dup(&$1)); | 195 | grecs_list_append($$, grecs_value_dup(&$1)); |
212 | } | 196 | } |
213 | | values ',' value | 197 | | values ',' value |
@@ -236,8 +220,8 @@ listel_dispose(void *el) | |||
236 | free(el); | 220 | free(el); |
237 | } | 221 | } |
238 | 222 | ||
239 | static struct grecs_list * | 223 | struct grecs_list * |
240 | simple_list_create(int dispose) | 224 | _grecs_simple_list_create(int dispose) |
241 | { | 225 | { |
242 | struct grecs_list *lp = grecs_list_create(); | 226 | struct grecs_list *lp = grecs_list_create(); |
243 | if (dispose) | 227 | if (dispose) |
@@ -307,59 +291,20 @@ grecs_asprintf(char **pbuf, size_t *psize, const char *fmt, ...) | |||
307 | return rc; | 291 | return rc; |
308 | } | 292 | } |
309 | 293 | ||
310 | void | 294 | struct grecs_node * |
311 | grecs_warning(grecs_locus_t *locus, int errcode, const char *fmt, ...) | ||
312 | { | ||
313 | va_list ap; | ||
314 | char *buf = NULL; | ||
315 | size_t size = 0; | ||
316 | |||
317 | va_start(ap, fmt); | ||
318 | if (grecs_vasprintf(&buf, &size, fmt, ap)) | ||
319 | grecs_alloc_die(); | ||
320 | va_end(ap); | ||
321 | grecs_print_diag(locus, 0, errcode, buf); | ||
322 | free(buf); | ||
323 | } | ||
324 | |||
325 | void | ||
326 | grecs_error(grecs_locus_t *locus, int errcode, const char *fmt, ...) | ||
327 | { | ||
328 | va_list ap; | ||
329 | char *buf = NULL; | ||
330 | size_t size = 0; | ||
331 | |||
332 | va_start(ap, fmt); | ||
333 | if (grecs_vasprintf(&buf, &size, fmt, ap)) | ||
334 | grecs_alloc_die(); | ||
335 | va_end(ap); | ||
336 | grecs_print_diag(locus, 1, errcode, buf); | ||
337 | free(buf); | ||
338 | grecs_error_count++; | ||
339 | } | ||
340 | |||
341 | void | ||
342 | grecs_set_keywords(struct grecs_keyword *kwd) | ||
343 | { | ||
344 | config_keywords.kwd = kwd; | ||
345 | } | ||
346 | |||
347 | int | ||
348 | grecs_parse(const char *name) | 295 | grecs_parse(const char *name) |
349 | { | 296 | { |
350 | int rc; | 297 | int rc; |
351 | if (grecs_lex_begin(name)) | 298 | if (grecs_lex_begin(name)) |
352 | return 1; | 299 | return NULL; |
353 | cursect = &config_keywords; | 300 | parse_tree = NULL; |
354 | if (sections) { | ||
355 | grecs_list_free(sections); | ||
356 | sections = NULL; | ||
357 | } | ||
358 | rc = yyparse(); | 301 | rc = yyparse(); |
359 | grecs_lex_end(); | 302 | grecs_lex_end(); |
360 | if (grecs_error_count) | 303 | if (grecs_error_count) { |
361 | rc = 1; | 304 | grecs_tree_free(parse_tree); |
362 | return rc; | 305 | parse_tree = NULL; |