xref: /csrg-svn/usr.sbin/config.new/gram.y (revision 61818)
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