BSD 4_4 release
[unix-history] / usr / src / usr.sbin / config.new / gram.y
CommitLineData
90b8dad5
CT
1%{
2
3/*
ad787160
C
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 *
ad787160
C
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. All advertising materials mentioning features or use of this software
25 * must display the following acknowledgement:
26 * This product includes software developed by the University of
27 * California, Berkeley and its contributors.
28 * 4. Neither the name of the University nor the names of its contributors
29 * may be used to endorse or promote products derived from this software
30 * without specific prior written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 * SUCH DAMAGE.
90b8dad5 43 *
ad787160 44 * @(#)gram.y 8.1 (Berkeley) 6/6/93
90b8dad5
CT
45 */
46
47#include <sys/param.h>
48#include <ctype.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include "config.h"
52#include "sem.h"
53
54#define FORMAT(n) ((n) > -10 && (n) < 10 ? "%d" : "0x%x")
55
56#define stop(s) error(s), exit(1)
57
58int include __P((const char *, int));
59void yyerror __P((const char *));
60int yylex __P((void));
61extern const char *lastfile;
62
63static struct config conf; /* at most one active at a time */
64
65/* the following is used to recover nvlist space after errors */
66static struct nvlist *alloc[1000];
67static int adepth;
68#define new0(n,s,p,i) (alloc[adepth++] = newnv(n, s, p, i))
69#define new_n(n) new0(n, NULL, NULL, 0)
70#define new_ns(n, s) new0(n, s, NULL, 0)
71#define new_si(s, i) new0(NULL, s, NULL, i)
72#define new_nsi(n,s,i) new0(n, s, NULL, i)
73#define new_np(n, p) new0(n, NULL, p, 0)
74#define new_s(s) new0(NULL, s, NULL, 0)
75#define new_p(p) new0(NULL, NULL, p, 0)
76
77static void cleanup __P((void));
78static void setmachine __P((const char *));
79
80%}
81
82%union {
83 struct attr *attr;
84 struct devbase *devb;
85 struct nvlist *list;
86 const char *str;
87 int val;
88}
89
90%token AND AT COMPILE_WITH CONFIG DEFINE DEVICE DUMPS ENDFILE
91%token XFILE FLAGS INCLUDE XMACHINE MAJOR MAKEOPTIONS MAXUSERS MINOR
92%token ON OPTIONS PSEUDO_DEVICE ROOT SWAP VECTOR
93%token <val> FFLAG NUMBER
94%token <str> PATHNAME WORD
95
96%type <list> fopts
97%type <val> fflgs
98%type <str> rule
99%type <attr> attr
100%type <devb> devbase
101%type <list> atlist interface_opt
102%type <str> atname
103%type <list> loclist_opt loclist locdef
104%type <str> locdefault
105%type <list> veclist_opt veclist
106%type <list> attrs_opt attrs
107%type <list> locators locator
108%type <list> swapdev_list dev_spec
109%type <str> device_instance
110%type <str> attachment
111%type <str> value
112%type <val> major_minor signed_number npseudo
113%type <val> flags_opt
114
115%%
116
117/*
118 * A configuration consists of a machine type, followed by the machine
119 * definition files (via the include() mechanism), followed by the
120 * configuration specification(s) proper. In effect, this is two
121 * separate grammars, with some shared terminals and nonterminals.
122 */
123Configuration:
124 hdrs machine_spec /* "machine foo" from machine descr. */
125 dev_defs dev_eof /* ../../conf/devices */
126 dev_defs dev_eof /* devices.foo */
127 specs; /* rest of machine description */
128
129hdrs:
130 hdrs hdr |
131 /* empty */;
132
133hdr:
134 include |
135 '\n';
136
137machine_spec:
138 XMACHINE WORD = { setmachine($2); } |
139 error = { stop("cannot proceed without machine specifier"); };
140
141dev_eof:
142 ENDFILE = { enddefs(lastfile); checkfiles(); };
143
144
145
146/*
147 * Various nonterminals shared between the grammars.
148 */
149file:
150 XFILE PATHNAME fopts fflgs rule = { addfile($2, $3, $4, $5); };
151
152/* order of options is important, must use right recursion */
153fopts:
154 WORD fopts = { ($$ = new_n($1))->nv_next = $2; } |
155 /* empty */ = { $$ = NULL; };
156
157fflgs:
158 fflgs FFLAG = { $$ = $1 | $2; } |
159 /* empty */ = { $$ = 0; };
160
161rule:
162 COMPILE_WITH WORD = { $$ = $2; } |
163 /* empty */ = { $$ = NULL; };
164
165include:
166 INCLUDE WORD = { (void)include($2, '\n'); };
167
168/*
169 * The machine definitions grammar.
170 */
171dev_defs:
172 dev_defs dev_def |
173 /* empty */;
174
175dev_def:
176 one_def '\n' = { adepth = 0; } |
177 '\n' |
178 error '\n' = { cleanup(); };
179
180one_def:
181 file |
182 /* include | */
183 DEFINE WORD interface_opt = { (void)defattr($2, $3); } |
184 DEVICE devbase AT atlist veclist_opt interface_opt attrs_opt
185 = { defdev($2, 0, $4, $5, $6, $7); } |
186 MAXUSERS NUMBER NUMBER NUMBER = { setdefmaxusers($2, $3, $4); } |
187 PSEUDO_DEVICE devbase attrs_opt = { defdev($2,1,NULL,NULL,NULL,$3); } |
188 MAJOR '{' majorlist '}';
189
190atlist:
191 atlist ',' atname = { ($$ = new_n($3))->nv_next = $1; } |
192 atname = { $$ = new_n($1); };
193
194atname:
195 WORD = { $$ = $1; } |
196 ROOT = { $$ = NULL; };
197
198veclist_opt:
199 VECTOR veclist = { $$ = $2; } |
200 /* empty */ = { $$ = NULL; };
201
202/* veclist order matters, must use right recursion */
203veclist:
204 WORD veclist = { ($$ = new_n($1))->nv_next = $2; } |
205 WORD = { $$ = new_n($1); };
206
207devbase:
208 WORD = { $$ = getdevbase($1); };
209
210interface_opt:
211 '{' loclist_opt '}' = { ($$ = new_n(""))->nv_next = $2; } |
212 /* empty */ = { $$ = NULL; };
213
214loclist_opt:
215 loclist = { $$ = $1; } |
216 /* empty */ = { $$ = NULL; };
217
218/* loclist order matters, must use right recursion */
219loclist:
220 locdef ',' loclist = { ($$ = $1)->nv_next = $3; } |
221 locdef = { $$ = $1; };
222
223/* "[ WORD locdefault ]" syntax may be unnecessary... */
224locdef:
225 WORD locdefault = { $$ = new_nsi($1, $2, 0); } |
226 WORD = { $$ = new_nsi($1, NULL, 0); } |
227 '[' WORD locdefault ']' = { $$ = new_nsi($2, $3, 1); };
228
229locdefault:
230 '=' value = { $$ = $2; };
231
232value:
233 WORD = { $$ = $1; } |
234 signed_number = { char bf[40];
235 (void)sprintf(bf, FORMAT($1), $1);
236 $$ = intern(bf); };
237
238signed_number:
239 NUMBER = { $$ = $1; } |
240 '-' NUMBER = { $$ = -$2; };
241
242attrs_opt:
243 ':' attrs = { $$ = $2; } |
244 /* empty */ = { $$ = NULL; };
245
246attrs:
247 attrs ',' attr = { ($$ = new_p($3))->nv_next = $1; } |
248 attr = { $$ = new_p($1); };
249
250attr:
251 WORD = { $$ = getattr($1); };
252
253majorlist:
254 majorlist ',' majordef |
255 majordef;
256
257majordef:
258 devbase '=' NUMBER = { setmajor($1, $3); };
259
260
261
262/*
263 * The configuration grammar.
264 */
265specs:
266 specs spec |
267 /* empty */;
268
269spec:
270 config_spec '\n' = { adepth = 0; } |
271 '\n' |
272 error '\n' = { cleanup(); };
273
274config_spec:
275 file |
276 include |
277 OPTIONS opt_list |
278 MAKEOPTIONS mkopt_list |
279 MAXUSERS NUMBER = { setmaxusers($2); } |
280 CONFIG conf sysparam_list = { addconf(&conf); } |
281 PSEUDO_DEVICE WORD npseudo = { addpseudo($2, $3); } |
282 device_instance AT attachment locators flags_opt
283 = { adddev($1, $3, $4, $5); };
284
285mkopt_list:
286 mkopt_list ',' mkoption |
287 mkoption;
288
289mkoption:
290 WORD '=' value = { addmkoption($1, $3); }
291
292opt_list:
293 opt_list ',' option |
294 option;
295
296option:
297 WORD = { addoption($1, NULL); } |
298 WORD '=' value = { addoption($1, $3); };
299
300conf:
301 WORD = { conf.cf_name = $1;
302 conf.cf_lineno = currentline();
303 conf.cf_root = NULL;
304 conf.cf_swap = NULL;
305 conf.cf_dump = NULL; };
306
307sysparam_list:
308 sysparam_list sysparam |
309 sysparam;
310
311sysparam:
312 ROOT on_opt dev_spec = { setconf(&conf.cf_root, "root", $3); } |
313 SWAP on_opt swapdev_list = { setconf(&conf.cf_swap, "swap", $3); } |
314 DUMPS on_opt dev_spec = { setconf(&conf.cf_dump, "dumps", $3); };
315
316swapdev_list:
317 dev_spec AND swapdev_list = { ($$ = $1)->nv_next = $3; } |
318 dev_spec = { $$ = $1; };
319
320dev_spec:
321 WORD = { $$ = new_si($1, NODEV); } |
322 major_minor = { $$ = new_si(NULL, $1); };
323
324major_minor:
325 MAJOR NUMBER MINOR NUMBER = { $$ = makedev($2, $4); };
326
327on_opt:
328 ON | /* empty */;
329
330npseudo:
331 NUMBER = { $$ = $1; } |
332 /* empty */ = { $$ = 1; };
333
334device_instance:
335 WORD '*' = { $$ = starref($1); } |
336 WORD = { $$ = $1; };
337
338attachment:
339 ROOT = { $$ = NULL; } |
340 WORD '?' = { $$ = wildref($1); } |
341 WORD '*' = { $$ = starref($1); } |
342 WORD = { $$ = $1; };
343
344locators:
345 locators locator = { ($$ = $2)->nv_next = $1; } |
346 /* empty */ = { $$ = NULL; };
347
348locator:
349 WORD value = { $$ = new_ns($1, $2); } |
350 WORD '?' = { $$ = new_ns($1, NULL); };
351
352flags_opt:
353 FLAGS NUMBER = { $$ = $2; } |
354 /* empty */ = { $$ = 0; };
355
356%%
357
358void
359yyerror(s)
360 const char *s;
361{
362
363 error("%s", s);
364}
365
366/*
367 * Cleanup procedure after syntax error: release any nvlists
368 * allocated during parsing the current line.
369 */
370static void
371cleanup()
372{
373 register struct nvlist **np;
374 register int i;
375
376 for (np = alloc, i = adepth; --i >= 0; np++)
377 nvfree(*np);
378 adepth = 0;
379}
380
381static void
382setmachine(mch)
383 const char *mch;
384{
385 char buf[MAXPATHLEN];
386
387 machine = mch;
388 (void)sprintf(buf, "files.%s", mch);
43fbfd6c
CT
389 if (include(buf, ENDFILE) ||
390 include("../../conf/files.newconf", ENDFILE))
90b8dad5
CT
391 exit(1);
392}