157488Storek %{
257488Storek
357488Storek /*
4*61818Sbostic * Copyright (c) 1992, 1993
5*61818Sbostic * The Regents of the University of California. All rights reserved.
657488Storek *
757488Storek * This software was developed by the Computer Systems Engineering group
857488Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
957488Storek * contributed to Berkeley.
1057488Storek *
1157488Storek * All advertising materials mentioning features or use of this software
1257488Storek * must display the following acknowledgement:
1357488Storek * This product includes software developed by the University of
1457488Storek * California, Lawrence Berkeley Laboratories.
1557488Storek *
1657488Storek * %sccs.include.redist.c%
1757488Storek *
18*61818Sbostic * @(#)gram.y 8.1 (Berkeley) 06/06/93
1957488Storek */
2057488Storek
2157488Storek #include <sys/param.h>
2257488Storek #include <ctype.h>
2357488Storek #include <stdio.h>
2457488Storek #include <stdlib.h>
2557488Storek #include "config.h"
2657488Storek #include "sem.h"
2757488Storek
2857488Storek #define FORMAT(n) ((n) > -10 && (n) < 10 ? "%d" : "0x%x")
2957488Storek
3057488Storek #define stop(s) error(s), exit(1)
3157488Storek
3257488Storek int include __P((const char *, int));
3357488Storek void yyerror __P((const char *));
3457488Storek int yylex __P((void));
3557488Storek extern const char *lastfile;
3657488Storek
3757488Storek static struct config conf; /* at most one active at a time */
3857488Storek
3957488Storek /* the following is used to recover nvlist space after errors */
4057488Storek static struct nvlist *alloc[1000];
4157488Storek static int adepth;
4257488Storek #define new0(n,s,p,i) (alloc[adepth++] = newnv(n, s, p, i))
4357488Storek #define new_n(n) new0(n, NULL, NULL, 0)
4457488Storek #define new_ns(n, s) new0(n, s, NULL, 0)
4557488Storek #define new_si(s, i) new0(NULL, s, NULL, i)
4657488Storek #define new_nsi(n,s,i) new0(n, s, NULL, i)
4757488Storek #define new_np(n, p) new0(n, NULL, p, 0)
4857488Storek #define new_s(s) new0(NULL, s, NULL, 0)
4957488Storek #define new_p(p) new0(NULL, NULL, p, 0)
5057488Storek
5157488Storek static void cleanup __P((void));
5257488Storek static void setmachine __P((const char *));
5357488Storek
5457488Storek %}
5557488Storek
5657488Storek %union {
5757488Storek struct attr *attr;
5857488Storek struct devbase *devb;
5957488Storek struct nvlist *list;
6057488Storek const char *str;
6157488Storek int val;
6257488Storek }
6357488Storek
6457488Storek %token AND AT COMPILE_WITH CONFIG DEFINE DEVICE DUMPS ENDFILE
6557488Storek %token XFILE FLAGS INCLUDE XMACHINE MAJOR MAKEOPTIONS MAXUSERS MINOR
6657488Storek %token ON OPTIONS PSEUDO_DEVICE ROOT SWAP VECTOR
6757488Storek %token <val> FFLAG NUMBER
6857488Storek %token <str> PATHNAME WORD
6957488Storek
7057488Storek %type <list> fopts
7157488Storek %type <val> fflgs
7257488Storek %type <str> rule
7357488Storek %type <attr> attr
7457488Storek %type <devb> devbase
7557488Storek %type <list> atlist interface_opt
7657488Storek %type <str> atname
7757488Storek %type <list> loclist_opt loclist locdef
7857488Storek %type <str> locdefault
7957488Storek %type <list> veclist_opt veclist
8057488Storek %type <list> attrs_opt attrs
8157488Storek %type <list> locators locator
8257488Storek %type <list> swapdev_list dev_spec
8357488Storek %type <str> device_instance
8457488Storek %type <str> attachment
8557488Storek %type <str> value
8657488Storek %type <val> major_minor signed_number npseudo
8757488Storek %type <val> flags_opt
8857488Storek
8957488Storek %%
9057488Storek
9157488Storek /*
9257488Storek * A configuration consists of a machine type, followed by the machine
9357488Storek * definition files (via the include() mechanism), followed by the
9457488Storek * configuration specification(s) proper. In effect, this is two
9557488Storek * separate grammars, with some shared terminals and nonterminals.
9657488Storek */
9757488Storek Configuration:
9857488Storek hdrs machine_spec /* "machine foo" from machine descr. */
9957488Storek dev_defs dev_eof /* ../../conf/devices */
10057488Storek dev_defs dev_eof /* devices.foo */
10157488Storek specs; /* rest of machine description */
10257488Storek
10357488Storek hdrs:
10457488Storek hdrs hdr |
10557488Storek /* empty */;
10657488Storek
10757488Storek hdr:
10857488Storek include |
10957488Storek '\n';
11057488Storek
11157488Storek machine_spec:
11257488Storek XMACHINE WORD = { setmachine($2); } |
11357488Storek error = { stop("cannot proceed without machine specifier"); };
11457488Storek
11557488Storek dev_eof:
11657488Storek ENDFILE = { enddefs(lastfile); checkfiles(); };
11757488Storek
11857488Storek
11957488Storek
12057488Storek /*
12157488Storek * Various nonterminals shared between the grammars.
12257488Storek */
12357488Storek file:
12457488Storek XFILE PATHNAME fopts fflgs rule = { addfile($2, $3, $4, $5); };
12557488Storek
12657488Storek /* order of options is important, must use right recursion */
12757488Storek fopts:
12857488Storek WORD fopts = { ($$ = new_n($1))->nv_next = $2; } |
12957488Storek /* empty */ = { $$ = NULL; };
13057488Storek
13157488Storek fflgs:
13257488Storek fflgs FFLAG = { $$ = $1 | $2; } |
13357488Storek /* empty */ = { $$ = 0; };
13457488Storek
13557488Storek rule:
13657488Storek COMPILE_WITH WORD = { $$ = $2; } |
13757488Storek /* empty */ = { $$ = NULL; };
13857488Storek
13957488Storek include:
14057488Storek INCLUDE WORD = { (void)include($2, '\n'); };
14157488Storek
14257488Storek /*
14357488Storek * The machine definitions grammar.
14457488Storek */
14557488Storek dev_defs:
14657488Storek dev_defs dev_def |
14757488Storek /* empty */;
14857488Storek
14957488Storek dev_def:
15057488Storek one_def '\n' = { adepth = 0; } |
15157488Storek '\n' |
15257488Storek error '\n' = { cleanup(); };
15357488Storek
15457488Storek one_def:
15557488Storek file |
15657488Storek /* include | */
15757488Storek DEFINE WORD interface_opt = { (void)defattr($2, $3); } |
15857488Storek DEVICE devbase AT atlist veclist_opt interface_opt attrs_opt
15957488Storek = { defdev($2, 0, $4, $5, $6, $7); } |
16057488Storek MAXUSERS NUMBER NUMBER NUMBER = { setdefmaxusers($2, $3, $4); } |
16157488Storek PSEUDO_DEVICE devbase attrs_opt = { defdev($2,1,NULL,NULL,NULL,$3); } |
16257488Storek MAJOR '{' majorlist '}';
16357488Storek
16457488Storek atlist:
16557488Storek atlist ',' atname = { ($$ = new_n($3))->nv_next = $1; } |
16657488Storek atname = { $$ = new_n($1); };
16757488Storek
16857488Storek atname:
16957488Storek WORD = { $$ = $1; } |
17057488Storek ROOT = { $$ = NULL; };
17157488Storek
17257488Storek veclist_opt:
17357488Storek VECTOR veclist = { $$ = $2; } |
17457488Storek /* empty */ = { $$ = NULL; };
17557488Storek
17657488Storek /* veclist order matters, must use right recursion */
17757488Storek veclist:
17857488Storek WORD veclist = { ($$ = new_n($1))->nv_next = $2; } |
17957488Storek WORD = { $$ = new_n($1); };
18057488Storek
18157488Storek devbase:
18257488Storek WORD = { $$ = getdevbase($1); };
18357488Storek
18457488Storek interface_opt:
18557488Storek '{' loclist_opt '}' = { ($$ = new_n(""))->nv_next = $2; } |
18657488Storek /* empty */ = { $$ = NULL; };
18757488Storek
18857488Storek loclist_opt:
18957488Storek loclist = { $$ = $1; } |
19057488Storek /* empty */ = { $$ = NULL; };
19157488Storek
19257488Storek /* loclist order matters, must use right recursion */
19357488Storek loclist:
19457488Storek locdef ',' loclist = { ($$ = $1)->nv_next = $3; } |
19557488Storek locdef = { $$ = $1; };
19657488Storek
19757488Storek /* "[ WORD locdefault ]" syntax may be unnecessary... */
19857488Storek locdef:
19957488Storek WORD locdefault = { $$ = new_nsi($1, $2, 0); } |
20057488Storek WORD = { $$ = new_nsi($1, NULL, 0); } |
20157488Storek '[' WORD locdefault ']' = { $$ = new_nsi($2, $3, 1); };
20257488Storek
20357488Storek locdefault:
20457488Storek '=' value = { $$ = $2; };
20557488Storek
20657488Storek value:
20757488Storek WORD = { $$ = $1; } |
20857488Storek signed_number = { char bf[40];
20957488Storek (void)sprintf(bf, FORMAT($1), $1);
21057488Storek $$ = intern(bf); };
21157488Storek
21257488Storek signed_number:
21357488Storek NUMBER = { $$ = $1; } |
21457488Storek '-' NUMBER = { $$ = -$2; };
21557488Storek
21657488Storek attrs_opt:
21757488Storek ':' attrs = { $$ = $2; } |
21857488Storek /* empty */ = { $$ = NULL; };
21957488Storek
22057488Storek attrs:
22157488Storek attrs ',' attr = { ($$ = new_p($3))->nv_next = $1; } |
22257488Storek attr = { $$ = new_p($1); };
22357488Storek
22457488Storek attr:
22557488Storek WORD = { $$ = getattr($1); };
22657488Storek
22757488Storek majorlist:
22857488Storek majorlist ',' majordef |
22957488Storek majordef;
23057488Storek
23157488Storek majordef:
23257488Storek devbase '=' NUMBER = { setmajor($1, $3); };
23357488Storek
23457488Storek
23557488Storek
23657488Storek /*
23757488Storek * The configuration grammar.
23857488Storek */
23957488Storek specs:
24057488Storek specs spec |
24157488Storek /* empty */;
24257488Storek
24357488Storek spec:
24457488Storek config_spec '\n' = { adepth = 0; } |
24557488Storek '\n' |
24657488Storek error '\n' = { cleanup(); };
24757488Storek
24857488Storek config_spec:
24957488Storek file |
25057488Storek include |
25157488Storek OPTIONS opt_list |
25257488Storek MAKEOPTIONS mkopt_list |
25357488Storek MAXUSERS NUMBER = { setmaxusers($2); } |
25457488Storek CONFIG conf sysparam_list = { addconf(&conf); } |
25557488Storek PSEUDO_DEVICE WORD npseudo = { addpseudo($2, $3); } |
25657488Storek device_instance AT attachment locators flags_opt
25757488Storek = { adddev($1, $3, $4, $5); };
25857488Storek
25957488Storek mkopt_list:
26057488Storek mkopt_list ',' mkoption |
26157488Storek mkoption;
26257488Storek
26357488Storek mkoption:
26457488Storek WORD '=' value = { addmkoption($1, $3); }
26557488Storek
26657488Storek opt_list:
26757488Storek opt_list ',' option |
26857488Storek option;
26957488Storek
27057488Storek option:
27157488Storek WORD = { addoption($1, NULL); } |
27257488Storek WORD '=' value = { addoption($1, $3); };
27357488Storek
27457488Storek conf:
27557488Storek WORD = { conf.cf_name = $1;
27657488Storek conf.cf_lineno = currentline();
27757488Storek conf.cf_root = NULL;
27857488Storek conf.cf_swap = NULL;
27957488Storek conf.cf_dump = NULL; };
28057488Storek
28157488Storek sysparam_list:
28257488Storek sysparam_list sysparam |
28357488Storek sysparam;
28457488Storek
28557488Storek sysparam:
28657488Storek ROOT on_opt dev_spec = { setconf(&conf.cf_root, "root", $3); } |
28757488Storek SWAP on_opt swapdev_list = { setconf(&conf.cf_swap, "swap", $3); } |
28857488Storek DUMPS on_opt dev_spec = { setconf(&conf.cf_dump, "dumps", $3); };
28957488Storek
29057488Storek swapdev_list:
29157488Storek dev_spec AND swapdev_list = { ($$ = $1)->nv_next = $3; } |
29257488Storek dev_spec = { $$ = $1; };
29357488Storek
29457488Storek dev_spec:
29557488Storek WORD = { $$ = new_si($1, NODEV); } |
29657488Storek major_minor = { $$ = new_si(NULL, $1); };
29757488Storek
29857488Storek major_minor:
29957488Storek MAJOR NUMBER MINOR NUMBER = { $$ = makedev($2, $4); };
30057488Storek
30157488Storek on_opt:
30257488Storek ON | /* empty */;
30357488Storek
30457488Storek npseudo:
30557488Storek NUMBER = { $$ = $1; } |
30657488Storek /* empty */ = { $$ = 1; };
30757488Storek
30857488Storek device_instance:
30957488Storek WORD '*' = { $$ = starref($1); } |
31057488Storek WORD = { $$ = $1; };
31157488Storek
31257488Storek attachment:
31357488Storek ROOT = { $$ = NULL; } |
31457488Storek WORD '?' = { $$ = wildref($1); } |
31557488Storek WORD '*' = { $$ = starref($1); } |
31657488Storek WORD = { $$ = $1; };
31757488Storek
31857488Storek locators:
31957488Storek locators locator = { ($$ = $2)->nv_next = $1; } |
32057488Storek /* empty */ = { $$ = NULL; };
32157488Storek
32257488Storek locator:
32357488Storek WORD value = { $$ = new_ns($1, $2); } |
32457488Storek WORD '?' = { $$ = new_ns($1, NULL); };
32557488Storek
32657488Storek flags_opt:
32757488Storek FLAGS NUMBER = { $$ = $2; } |
32857488Storek /* empty */ = { $$ = 0; };
32957488Storek
33057488Storek %%
33157488Storek
33257488Storek void
yyerror(s)33357488Storek yyerror(s)
33457488Storek const char *s;
33557488Storek {
33657488Storek
33757488Storek error("%s", s);
33857488Storek }
33957488Storek
34057488Storek /*
34157488Storek * Cleanup procedure after syntax error: release any nvlists
34257488Storek * allocated during parsing the current line.
34357488Storek */
34457488Storek static void
cleanup()34557488Storek cleanup()
34657488Storek {
34757488Storek register struct nvlist **np;
34857488Storek register int i;
34957488Storek
35057488Storek for (np = alloc, i = adepth; --i >= 0; np++)
35157488Storek nvfree(*np);
35257488Storek adepth = 0;
35357488Storek }
35457488Storek
35557488Storek static void
setmachine(mch)35657488Storek setmachine(mch)
35757488Storek const char *mch;
35857488Storek {
35957488Storek char buf[MAXPATHLEN];
36057488Storek
36157488Storek machine = mch;
36257488Storek (void)sprintf(buf, "files.%s", mch);
36359144Storek if (include(buf, ENDFILE) ||
36459144Storek include("../../conf/files.newconf", ENDFILE))
36557488Storek exit(1);
36657488Storek }
367