chiark / gitweb /
cd53b7cf88f349d919e9fc0c18af69e46479bd5a
[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 #include "secnet.h"
12 #include "conffile_internal.h"
13 #include "util.h"
14 #define YYERROR_VERBOSE
15
16 static struct p_node *node(uint32_t type, struct p_node *l, struct p_node *r);
17
18 static struct p_node *result;
19
20 static void yyerror(char *s);
21
22 %}
23
24 %%
25
26 input:            assignments { result = $1; $$=result; }
27                 ;
28
29 assignments:      assignments assignment { $$=node(T_ALIST, $2, $1); }
30                 | assignment { $$=node(T_ALIST, $1, NULL); }
31                 ;
32
33 searchpath:       /* empty */ { $$ = NULL; }
34                 | '<' list '>' { $$ = $2; }
35                 ;
36
37 dict:             searchpath '{' assignments '}'
38         { $$ = node(T_DICT, $3, $1); }
39                 | searchpath '{' '}' { $$ = node(T_DICT, NULL, $1); }
40                 ;
41
42 path:             '/' pathelements { $$ = node(T_ABSPATH, NULL, $2); }
43                 | pathelements { $$ = node(T_RELPATH, NULL, $1); }
44                 ;
45
46 pathelements:     pathelements '/' TOK_KEY { $$ = node(T_PATHELEM, $3, $1); }
47                 | TOK_KEY { $$ = node(T_PATHELEM, $1, NULL); }
48                 ;
49
50 exec:             item '(' list ')' { $$ = node(T_EXEC, $1, $3); }
51                 | item '(' ')' { $$ = node(T_EXEC, $1, NULL); }
52                 | item dict
53         { $$ = node(T_EXEC, $1, node(T_LISTITEM, $2, NULL)); }
54                 ;
55
56 list:             list ',' item { $$ = node(T_LISTITEM, $3, $1); }
57                 | item { $$ = node(T_LISTITEM, $1, NULL); }
58                 ;
59
60 assignment:       TOK_KEY '=' list ';' { $$ = node(T_ASSIGNMENT, $1, $3); }
61                 | TOK_KEY list ';' { $$ = node(T_ASSIGNMENT, $1, $2); }
62                 | error ';' { $$ = node(T_ERROR, NULL, NULL); }
63                 | error '}' { $$ = node(T_ERROR, NULL, NULL); }
64                 | error ')' { $$ = node(T_ERROR, NULL, NULL); }
65                 ;
66
67 item:             TOK_STRING
68                 | TOK_NUMBER
69                 | path
70                 | dict
71                 | exec
72                 ;
73
74 %%
75
76 static void yyerror(char *s)
77 {
78         Message(M_FATAL,"config file %s line %d: %s\n",config_file,
79                 config_lineno,s);
80 }
81
82 struct p_node *parse_conffile(FILE *conffile)
83 {
84         yyin=conffile;
85         if (yyparse()!=0) {
86                 fatal("Configuration file parsing failed\n");
87         }
88         if (yynerrs>0) {
89                 fatal("%d error%s encountered in configuration file\n",
90                 yynerrs,yynerrs==1?"":"s");
91         }
92         return result;
93 }
94
95 static struct p_node *node(uint32_t type, struct p_node *l, struct p_node *r)
96 {
97         struct p_node *rv;
98
99         rv=safe_malloc(sizeof(*rv),"p_node");
100         rv->type=type;
101         rv->loc.file=config_file;
102         rv->loc.line=config_lineno;
103         rv->l=l;
104         rv->r=r;
105         return rv;
106 }