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