chiark / gitweb /
make-secnet-sites: refactor to break out new function "pfilepath"
[secnet.git] / conffile.y
1 %token TOK_STRING
2 %token TOK_NUMBER
3 %token TOK_KEY
4
5 %start input
6
7 %{
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 /* Bison stupidly redeclares malloc/free unless they are #defined
12  * (or a bunch of madder conditions) */
13 #ifndef malloc
14 # define malloc malloc
15 # define free free
16 #endif
17 #include "secnet.h"
18 #include "conffile_internal.h"
19 #include "conffile.yy.h"
20 #include "util.h"
21 #define YYERROR_VERBOSE
22
23 static struct p_node *node(uint32_t type, struct p_node *l, struct p_node *r);
24
25 static struct p_node *result;
26
27 static void yyerror(const char *s);
28
29 %}
30
31 %%
32
33 input:            assignments { result = $1; $$=result; }
34                 ;
35
36 assignments:      assignments assignment { $$=node(T_ALIST, $2, $1); }
37                 | assignment { $$=node(T_ALIST, $1, NULL); }
38                 ;
39
40 searchpath:       /* empty */ { $$ = NULL; }
41                 | '<' list '>' { $$ = $2; }
42                 ;
43
44 dict:             searchpath '{' assignments '}'
45         { $$ = node(T_DICT, $3, $1); }
46                 | searchpath '{' '}' { $$ = node(T_DICT, NULL, $1); }
47                 ;
48
49 path:             '/' pathelements { $$ = node(T_ABSPATH, NULL, $2); }
50                 | pathelements { $$ = node(T_RELPATH, NULL, $1); }
51                 ;
52
53 pathelements:     pathelements '/' TOK_KEY { $$ = node(T_PATHELEM, $3, $1); }
54                 | TOK_KEY { $$ = node(T_PATHELEM, $1, NULL); }
55                 ;
56
57 exec:             item '(' list ')' { $$ = node(T_EXEC, $1, $3); }
58                 | item '(' ')' { $$ = node(T_EXEC, $1, NULL); }
59                 | item dict
60         { $$ = node(T_EXEC, $1, node(T_LISTITEM, $2, NULL)); }
61                 ;
62
63 list:             list ',' item { $$ = node(T_LISTITEM, $3, $1); }
64                 | item { $$ = node(T_LISTITEM, $1, NULL); }
65                 ;
66
67 assignment:       TOK_KEY '=' list ';' { $$ = node(T_ASSIGNMENT, $1, $3); }
68                 | TOK_KEY list ';' { $$ = node(T_ASSIGNMENT, $1, $2); }
69                 | error ';' { $$ = node(T_ERROR, NULL, NULL); }
70                 | error '}' { $$ = node(T_ERROR, NULL, NULL); }
71                 | error ')' { $$ = node(T_ERROR, NULL, NULL); }
72                 ;
73
74 item:             TOK_STRING
75                 | TOK_NUMBER
76                 | path
77                 | dict
78                 | exec
79                 ;
80
81 %%
82
83 static void yyerror(const char *s)
84 {
85         Message(M_FATAL,"config file %s line %d: %s\n",config_file,
86                 config_lineno,s);
87 }
88
89 struct p_node *parse_conffile(FILE *conffile)
90 {
91         yyin=conffile;
92         if (yyparse()!=0) {
93                 fatal("Configuration file parsing failed\n");
94         }
95         if (yynerrs>0) {
96                 fatal("%d error%s encountered in configuration file\n",
97                 yynerrs,yynerrs==1?"":"s");
98         }
99         return result;
100 }
101
102 static struct p_node *node(uint32_t type, struct p_node *l, struct p_node *r)
103 {
104         struct p_node *rv;
105
106         rv=safe_malloc(sizeof(*rv),"p_node");
107         rv->type=type;
108         rv->loc.file=config_file;
109         rv->loc.line=config_lineno;
110         rv->l=l;
111         rv->r=r;
112         return rv;
113 }