4.4BSD snapshot (revision 8.1); add 1993 to copyright
[unix-history] / usr / src / usr.sbin / config.new / gram.y
CommitLineData
90b8dad5
CT
1%{
2
3/*
62a2aae7
KB
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
90b8dad5
CT
6 *
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
10 *
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratories.
15 *
16 * %sccs.include.redist.c%
17 *
62a2aae7 18 * @(#)gram.y 8.1 (Berkeley) %G%
90b8dad5
CT
19 */
20
21#include <sys/param.h>
22#include <ctype.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include "config.h"
26#include "sem.h"
27
28#define FORMAT(n) ((n) > -10 && (n) < 10 ? "%d" : "0x%x")
29
30#define stop(s) error(s), exit(1)
31
32int include __P((const char *, int));
33void yyerror __P((const char *));
34int yylex __P((void));
35extern const char *lastfile;
36
37static struct config conf; /* at most one active at a time */
38
39/* the following is used to recover nvlist space after errors */
40static struct nvlist *alloc[1000];
41static int adepth;
42#define new0(n,s,p,i) (alloc[adepth++] = newnv(n, s, p, i))
43#define new_n(n) new0(n, NULL, NULL, 0)
44#define new_ns(n, s) new0(n, s, NULL, 0)
45#define new_si(s, i) new0(NULL, s, NULL, i)
46#define new_nsi(n,s,i) new0(n, s, NULL, i)
47#define new_np(n, p) new0(n, NULL, p, 0)
48#define new_s(s) new0(NULL, s, NULL, 0)
49#define new_p(p) new0(NULL, NULL, p, 0)
50
51static void cleanup __P((void));
52static void setmachine __P((const char *));
53
54%}
55
56%union {
57 struct attr *attr;
58 struct devbase *devb;
59 struct nvlist *list;
60 const char *str;
61 int val;
62}
63
64%token AND AT COMPILE_WITH CONFIG DEFINE DEVICE DUMPS ENDFILE
65%token XFILE FLAGS INCLUDE XMACHINE MAJOR MAKEOPTIONS MAXUSERS MINOR
66%token ON OPTIONS PSEUDO_DEVICE ROOT SWAP VECTOR
67%token <val> FFLAG NUMBER
68%token <str> PATHNAME WORD
69
70%type <list> fopts
71%type <val> fflgs
72%type <str> rule
73%type <attr> attr
74%type <devb> devbase
75%type <list> atlist interface_opt
76%type <str> atname
77%type <list> loclist_opt loclist locdef
78%type <str> locdefault
79%type <list> veclist_opt veclist
80%type <list> attrs_opt attrs
81%type <list> locators locator
82%type <list> swapdev_list dev_spec
83%type <str> device_instance
84%type <str> attachment
85%type <str> value
86%type <val> major_minor signed_number npseudo
87%type <val> flags_opt
88
89%%
90
91/*
92 * A configuration consists of a machine type, followed by the machine
93 * definition files (via the include() mechanism), followed by the
94 * configuration specification(s) proper. In effect, this is two
95 * separate grammars, with some shared terminals and nonterminals.
96 */
97Configuration:
98 hdrs machine_spec /* "machine foo" from machine descr. */
99 dev_defs dev_eof /* ../../conf/devices */
100 dev_defs dev_eof /* devices.foo */
101 specs; /* rest of machine description */
102
103hdrs:
104 hdrs hdr |
105 /* empty */;
106
107hdr:
108 include |
109 '\n';
110
111machine_spec:
112 XMACHINE WORD = { setmachine($2); } |
113 error = { stop("cannot proceed without machine specifier"); };
114
115dev_eof:
116 ENDFILE = { enddefs(lastfile); checkfiles(); };
117
118
119
120/*
121 * Various nonterminals shared between the grammars.
122 */
123file:
124 XFILE PATHNAME fopts fflgs rule = { addfile($2, $3, $4, $5); };
125
126/* order of options is important, must use right recursion */
127fopts:
128 WORD fopts = { ($$ = new_n($1))->nv_next = $2; } |
129 /* empty */ = { $$ = NULL; };
130
131fflgs:
132 fflgs FFLAG = { $$ = $1 | $2; } |
133 /* empty */ = { $$ = 0; };
134
135rule:
136 COMPILE_WITH WORD = { $$ = $2; } |
137 /* empty */ = { $$ = NULL; };
138
139include:
140 INCLUDE WORD = { (void)include($2, '\n'); };
141
142/*
143 * The machine definitions grammar.
144 */
145dev_defs:
146 dev_defs dev_def |
147 /* empty */;
148
149dev_def:
150 one_def '\n' = { adepth = 0; } |
151 '\n' |
152 error '\n' = { cleanup(); };
153
154one_def:
155 file |
156 /* include | */
157 DEFINE WORD interface_opt = { (void)defattr($2, $3); } |
158 DEVICE devbase AT atlist veclist_opt interface_opt attrs_opt
159 = { defdev($2, 0, $4, $5, $6, $7); } |
160 MAXUSERS NUMBER NUMBER NUMBER = { setdefmaxusers($2, $3, $4); } |
161 PSEUDO_DEVICE devbase attrs_opt = { defdev($2,1,NULL,NULL,NULL,$3); } |
162 MAJOR '{' majorlist '}';
163
164atlist:
165 atlist ',' atname = { ($$ = new_n($3))->nv_next = $1; } |
166 atname = { $$ = new_n($1); };
167
168atname:
169 WORD = { $$ = $1; } |
170 ROOT = { $$ = NULL; };
171
172veclist_opt:
173 VECTOR veclist = { $$ = $2; } |
174 /* empty */ = { $$ = NULL; };
175
176/* veclist order matters, must use right recursion */
177veclist:
178 WORD veclist = { ($$ = new_n($1))->nv_next = $2; } |
179 WORD = { $$ = new_n($1); };
180
181devbase:
182 WORD = { $$ = getdevbase($1); };
183
184interface_opt:
185 '{' loclist_opt '}' = { ($$ = new_n(""))->nv_next = $2; } |
186 /* empty */ = { $$ = NULL; };
187
188loclist_opt:
189 loclist = { $$ = $1; } |
190 /* empty */ = { $$ = NULL; };
191
192/* loclist order matters, must use right recursion */
193loclist:
194 locdef ',' loclist = { ($$ = $1)->nv_next = $3; } |
195 locdef = { $$ = $1; };
196
197/* "[ WORD locdefault ]" syntax may be unnecessary... */
198locdef:
199 WORD locdefault = { $$ = new_nsi($1, $2, 0); } |
200 WORD = { $$ = new_nsi($1, NULL, 0); } |
201 '[' WORD locdefault ']' = { $$ = new_nsi($2, $3, 1); };
202
203locdefault:
204 '=' value = { $$ = $2; };
205
206value:
207 WORD = { $$ = $1; } |
208 signed_number = { char bf[40];
209 (void)sprintf(bf, FORMAT($1), $1);
210 $$ = intern(bf); };
211
212signed_number:
213 NUMBER = { $$ = $1; } |
214 '-' NUMBER = { $$ = -$2; };
215
216attrs_opt:
217 ':' attrs = { $$ = $2; } |
218 /* empty */ = { $$ = NULL; };
219
220attrs:
221 attrs ',' attr = { ($$ = new_p($3))->nv_next = $1; } |
222 attr = { $$ = new_p($1); };
223
224attr:
225 WORD = { $$ = getattr($1); };
226
227majorlist:
228 majorlist ',' majordef |
229 majordef;
230
231majordef:
232 devbase '=' NUMBER = { setmajor($1, $3); };
233
234
235
236/*
237 * The configuration grammar.
238 */
239specs:
240 specs spec |
241 /* empty */;
242
243spec:
244 config_spec '\n' = { adepth = 0; } |
245 '\n' |
246 error '\n' = { cleanup(); };
247
248config_spec:
249 file |
250 include |
251 OPTIONS opt_list |
252 MAKEOPTIONS mkopt_list |
253 MAXUSERS NUMBER = { setmaxusers($2); } |
254 CONFIG conf sysparam_list = { addconf(&conf); } |
255 PSEUDO_DEVICE WORD npseudo = { addpseudo($2, $3); } |
256 device_instance AT attachment locators flags_opt
257 = { adddev($1, $3, $4, $5); };
258
259mkopt_list:
260 mkopt_list ',' mkoption |
261 mkoption;
262
263mkoption:
264 WORD '=' value = { addmkoption($1, $3); }
265
266opt_list:
267 opt_list ',' option |
268 option;
269
270option:
271 WORD = { addoption($1, NULL); } |
272 WORD '=' value = { addoption($1, $3); };
273
274conf:
275 WORD = { conf.cf_name = $1;
276 conf.cf_lineno = currentline();
277 conf.cf_root = NULL;
278 conf.cf_swap = NULL;
279 conf.cf_dump = NULL; };
280
281sysparam_list:
282 sysparam_list sysparam |
283 sysparam;
284
285sysparam:
286 ROOT on_opt dev_spec = { setconf(&conf.cf_root, "root", $3); } |
287 SWAP on_opt swapdev_list = { setconf(&conf.cf_swap, "swap", $3); } |
288 DUMPS on_opt dev_spec = { setconf(&conf.cf_dump, "dumps", $3); };
289
290swapdev_list:
291 dev_spec AND swapdev_list = { ($$ = $1)->nv_next = $3; } |
292 dev_spec = { $$ = $1; };
293
294dev_spec:
295 WORD = { $$ = new_si($1, NODEV); } |
296 major_minor = { $$ = new_si(NULL, $1); };
297
298major_minor:
299 MAJOR NUMBER MINOR NUMBER = { $$ = makedev($2, $4); };
300
301on_opt:
302 ON | /* empty */;
303
304npseudo:
305 NUMBER = { $$ = $1; } |
306 /* empty */ = { $$ = 1; };
307
308device_instance:
309 WORD '*' = { $$ = starref($1); } |
310 WORD = { $$ = $1; };
311
312attachment:
313 ROOT = { $$ = NULL; } |
314 WORD '?' = { $$ = wildref($1); } |
315 WORD '*' = { $$ = starref($1); } |
316 WORD = { $$ = $1; };
317
318locators:
319 locators locator = { ($$ = $2)->nv_next = $1; } |
320 /* empty */ = { $$ = NULL; };
321
322locator:
323 WORD value = { $$ = new_ns($1, $2); } |
324 WORD '?' = { $$ = new_ns($1, NULL); };
325
326flags_opt:
327 FLAGS NUMBER = { $$ = $2; } |
328 /* empty */ = { $$ = 0; };
329
330%%
331
332void
333yyerror(s)
334 const char *s;
335{
336
337 error("%s", s);
338}
339
340/*
341 * Cleanup procedure after syntax error: release any nvlists
342 * allocated during parsing the current line.
343 */
344static void
345cleanup()
346{
347 register struct nvlist **np;
348 register int i;
349
350 for (np = alloc, i = adepth; --i >= 0; np++)
351 nvfree(*np);
352 adepth = 0;
353}
354
355static void
356setmachine(mch)
357 const char *mch;
358{
359 char buf[MAXPATHLEN];
360
361 machine = mch;
362 (void)sprintf(buf, "files.%s", mch);
43fbfd6c
CT
363 if (include(buf, ENDFILE) ||
364 include("../../conf/files.newconf", ENDFILE))
90b8dad5
CT
365 exit(1);
366}