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