xref: /netbsd/usr.bin/config/gram.y (revision 564e2cec)
15ecc953bSthorpej %{
2*564e2cecSuwe /*	$NetBSD: gram.y,v 1.56 2020/07/26 22:40:52 uwe Exp $	*/
35ecc953bSthorpej 
45ecc953bSthorpej /*
55ecc953bSthorpej  * Copyright (c) 1992, 1993
65ecc953bSthorpej  *	The Regents of the University of California.  All rights reserved.
75ecc953bSthorpej  *
85ecc953bSthorpej  * This software was developed by the Computer Systems Engineering group
95ecc953bSthorpej  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
105ecc953bSthorpej  * contributed to Berkeley.
115ecc953bSthorpej  *
125ecc953bSthorpej  * All advertising materials mentioning features or use of this software
135ecc953bSthorpej  * must display the following acknowledgement:
145ecc953bSthorpej  *	This product includes software developed by the University of
155ecc953bSthorpej  *	California, Lawrence Berkeley Laboratories.
165ecc953bSthorpej  *
175ecc953bSthorpej  * Redistribution and use in source and binary forms, with or without
185ecc953bSthorpej  * modification, are permitted provided that the following conditions
195ecc953bSthorpej  * are met:
205ecc953bSthorpej  * 1. Redistributions of source code must retain the above copyright
215ecc953bSthorpej  *    notice, this list of conditions and the following disclaimer.
225ecc953bSthorpej  * 2. Redistributions in binary form must reproduce the above copyright
235ecc953bSthorpej  *    notice, this list of conditions and the following disclaimer in the
245ecc953bSthorpej  *    documentation and/or other materials provided with the distribution.
255ecc953bSthorpej  * 3. Neither the name of the University nor the names of its contributors
265ecc953bSthorpej  *    may be used to endorse or promote products derived from this software
275ecc953bSthorpej  *    without specific prior written permission.
285ecc953bSthorpej  *
295ecc953bSthorpej  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
305ecc953bSthorpej  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
315ecc953bSthorpej  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
325ecc953bSthorpej  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
335ecc953bSthorpej  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
345ecc953bSthorpej  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
355ecc953bSthorpej  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
365ecc953bSthorpej  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
375ecc953bSthorpej  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
385ecc953bSthorpej  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
395ecc953bSthorpej  * SUCH DAMAGE.
405ecc953bSthorpej  *
415ecc953bSthorpej  *	from: @(#)gram.y	8.1 (Berkeley) 6/6/93
425ecc953bSthorpej  */
435ecc953bSthorpej 
449a7f4bbaSchristos #include <sys/cdefs.h>
45*564e2cecSuwe __RCSID("$NetBSD: gram.y,v 1.56 2020/07/26 22:40:52 uwe Exp $");
469a7f4bbaSchristos 
475ecc953bSthorpej #include <sys/types.h>
485ecc953bSthorpej #include <sys/param.h>
495ecc953bSthorpej #include <ctype.h>
505ecc953bSthorpej #include <stdio.h>
515ecc953bSthorpej #include <stdlib.h>
525ecc953bSthorpej #include <string.h>
535ecc953bSthorpej #include <errno.h>
545ecc953bSthorpej #include "defs.h"
555ecc953bSthorpej #include "sem.h"
565ecc953bSthorpej 
575ecc953bSthorpej #define	FORMAT(n) (((n).fmt == 8 && (n).val != 0) ? "0%llo" : \
585ecc953bSthorpej     ((n).fmt == 16) ? "0x%llx" : "%lld")
595ecc953bSthorpej 
60c7295a4cSchristos #define	stop(s)	cfgerror(s), exit(1)
615ecc953bSthorpej 
625ecc953bSthorpej static	struct	config conf;	/* at most one active at a time */
633dbd1573Schristos static	int	nowarn;		/* if warning suppression is on */
645ecc953bSthorpej 
652839b938Sdholland 
662839b938Sdholland /*
672839b938Sdholland  * Allocation wrapper functions
682839b938Sdholland  */
692839b938Sdholland static void wrap_alloc(void *ptr, unsigned code);
702839b938Sdholland static void wrap_continue(void);
712839b938Sdholland static void wrap_cleanup(void);
722839b938Sdholland 
732839b938Sdholland /*
742839b938Sdholland  * Allocation wrapper type codes
752839b938Sdholland  */
762839b938Sdholland #define WRAP_CODE_nvlist	1
77d74eb995Sdholland #define WRAP_CODE_defoptlist	2
78d74eb995Sdholland #define WRAP_CODE_loclist	3
79d74eb995Sdholland #define WRAP_CODE_attrlist	4
80d74eb995Sdholland #define WRAP_CODE_condexpr	5
812839b938Sdholland 
822839b938Sdholland /*
832839b938Sdholland  * The allocation wrappers themselves
842839b938Sdholland  */
852839b938Sdholland #define DECL_ALLOCWRAP(t)	static struct t *wrap_mk_##t(struct t *arg)
862839b938Sdholland 
872839b938Sdholland DECL_ALLOCWRAP(nvlist);
88d74eb995Sdholland DECL_ALLOCWRAP(defoptlist);
8916a8771bSdholland DECL_ALLOCWRAP(loclist);
904caf067bSdholland DECL_ALLOCWRAP(attrlist);
919483bda7Sdholland DECL_ALLOCWRAP(condexpr);
929483bda7Sdholland 
939483bda7Sdholland /* allow shorter names */
9416a8771bSdholland #define wrap_mk_loc(p) wrap_mk_loclist(p)
959483bda7Sdholland #define wrap_mk_cx(p) wrap_mk_condexpr(p)
962839b938Sdholland 
972839b938Sdholland /*
982839b938Sdholland  * Macros for allocating new objects
992839b938Sdholland  */
1002839b938Sdholland 
1014caf067bSdholland /* old-style for struct nvlist */
1022839b938Sdholland #define	new0(n,s,p,i,x)	wrap_mk_nvlist(newnv(n, s, p, i, x))
1035ecc953bSthorpej #define	new_n(n)	new0(n, NULL, NULL, 0, NULL)
1045ecc953bSthorpej #define	new_nx(n, x)	new0(n, NULL, NULL, 0, x)
1055ecc953bSthorpej #define	new_ns(n, s)	new0(n, s, NULL, 0, NULL)
1065ecc953bSthorpej #define	new_si(s, i)	new0(NULL, s, NULL, i, NULL)
10779cd2972Smlelstv #define	new_spi(s, p, i)	new0(NULL, s, p, i, NULL)
1085ecc953bSthorpej #define	new_nsi(n,s,i)	new0(n, s, NULL, i, NULL)
1095ecc953bSthorpej #define	new_np(n, p)	new0(n, NULL, p, 0, NULL)
1105ecc953bSthorpej #define	new_s(s)	new0(NULL, s, NULL, 0, NULL)
1115ecc953bSthorpej #define	new_p(p)	new0(NULL, NULL, p, 0, NULL)
1125ecc953bSthorpej #define	new_px(p, x)	new0(NULL, NULL, p, 0, x)
1135ecc953bSthorpej #define	new_sx(s, x)	new0(NULL, s, NULL, 0, x)
11490426267Scube #define	new_nsx(n,s,x)	new0(n, s, NULL, 0, x)
1153da3ab25Spooka #define	new_i(i)	new0(NULL, NULL, NULL, i, NULL)
1165ecc953bSthorpej 
1179483bda7Sdholland /* new style, type-polymorphic; ordinary and for types with multiple flavors */
1184caf067bSdholland #define MK0(t)		wrap_mk_##t(mk_##t())
1194caf067bSdholland #define MK1(t, a0)	wrap_mk_##t(mk_##t(a0))
1204caf067bSdholland #define MK2(t, a0, a1)	wrap_mk_##t(mk_##t(a0, a1))
12116a8771bSdholland #define MK3(t, a0, a1, a2)	wrap_mk_##t(mk_##t(a0, a1, a2))
1224caf067bSdholland 
1239483bda7Sdholland #define MKF0(t, f)		wrap_mk_##t(mk_##t##_##f())
1249483bda7Sdholland #define MKF1(t, f, a0)		wrap_mk_##t(mk_##t##_##f(a0))
1259483bda7Sdholland #define MKF2(t, f, a0, a1)	wrap_mk_##t(mk_##t##_##f(a0, a1))
1269483bda7Sdholland 
1274caf067bSdholland /*
1284caf067bSdholland  * Data constructors
1294caf067bSdholland  */
1304caf067bSdholland 
131d74eb995Sdholland static struct defoptlist *mk_defoptlist(const char *, const char *,
132d74eb995Sdholland 					const char *);
13316a8771bSdholland static struct loclist *mk_loc(const char *, const char *, long long);
13416a8771bSdholland static struct loclist *mk_loc_val(const char *, struct loclist *);
1354caf067bSdholland static struct attrlist *mk_attrlist(struct attrlist *, struct attr *);
1369483bda7Sdholland static struct condexpr *mk_cx_atom(const char *);
1379483bda7Sdholland static struct condexpr *mk_cx_not(struct condexpr *);
1389483bda7Sdholland static struct condexpr *mk_cx_and(struct condexpr *, struct condexpr *);
1399483bda7Sdholland static struct condexpr *mk_cx_or(struct condexpr *, struct condexpr *);
1404caf067bSdholland 
1412839b938Sdholland /*
1422839b938Sdholland  * Other private functions
1432839b938Sdholland  */
1442839b938Sdholland 
145e239742fSpooka static	void	setmachine(const char *, const char *, struct nvlist *, int);
1465ecc953bSthorpej static	void	check_maxpart(void);
1475ecc953bSthorpej 
14816a8771bSdholland static struct loclist *present_loclist(struct loclist *ll);
14916a8771bSdholland static void app(struct loclist *, struct loclist *);
15016a8771bSdholland static struct loclist *locarray(const char *, int, struct loclist *, int);
15116a8771bSdholland static struct loclist *namelocvals(const char *, struct loclist *);
1525ecc953bSthorpej 
1535ecc953bSthorpej %}
1545ecc953bSthorpej 
1555ecc953bSthorpej %union {
1565ecc953bSthorpej 	struct	attr *attr;
1575ecc953bSthorpej 	struct	devbase *devb;
1585ecc953bSthorpej 	struct	deva *deva;
1595ecc953bSthorpej 	struct	nvlist *list;
160d74eb995Sdholland 	struct defoptlist *defoptlist;
16116a8771bSdholland 	struct loclist *loclist;
1624caf067bSdholland 	struct attrlist *attrlist;
1639483bda7Sdholland 	struct condexpr *condexpr;
1645ecc953bSthorpej 	const char *str;
1655ecc953bSthorpej 	struct	numconst num;
1665ecc953bSthorpej 	int64_t	val;
1679a7f4bbaSchristos 	u_char	flag;
1689a7f4bbaSchristos 	devmajor_t devmajor;
1699a7f4bbaSchristos 	int32_t i32;
1705ecc953bSthorpej }
1715ecc953bSthorpej 
1725ecc953bSthorpej %token	AND AT ATTACH
1735ecc953bSthorpej %token	BLOCK BUILD
17490426267Scube %token	CHAR COLONEQ COMPILE_WITH CONFIG
1758456b350Sdrochner %token	DEFFS DEFINE DEFOPT DEFPARAM DEFFLAG DEFPSEUDO DEFPSEUDODEV
1768456b350Sdrochner %token	DEVICE DEVCLASS DUMPS DEVICE_MAJOR
1775ecc953bSthorpej %token	ENDFILE
1785ecc953bSthorpej %token	XFILE FILE_SYSTEM FLAGS
179e239742fSpooka %token	IDENT IOCONF
1803da3ab25Spooka %token	LINKZERO
1815ecc953bSthorpej %token	XMACHINE MAJOR MAKEOPTIONS MAXUSERS MAXPARTITIONS MINOR
1823dbd1573Schristos %token	NEEDS_COUNT NEEDS_FLAG NO CNO
183ac24e161Scube %token	XOBJECT OBSOLETE ON OPTIONS
18466c67372Suebayasi %token	PACKAGE PLUSEQ PREFIX BUILDPREFIX PSEUDO_DEVICE PSEUDO_ROOT
1855ecc953bSthorpej %token	ROOT
1868d928a75Suebayasi %token	SELECT SINGLE SOURCE
1875ecc953bSthorpej %token	TYPE
1883da3ab25Spooka %token	VECTOR VERSION
1895ecc953bSthorpej %token	WITH
1905ecc953bSthorpej %token	<num> NUMBER
191d0fb8901Schristos %token	<str> PATHNAME QSTRING WORD EMPTYSTRING
1925ecc953bSthorpej %token	ENDDEFS
1935ecc953bSthorpej 
1949483bda7Sdholland %type	<condexpr>	fopts condexpr condatom
1959483bda7Sdholland %type	<condexpr>	cond_or_expr cond_and_expr cond_prefix_expr
1969483bda7Sdholland %type	<condexpr>	 cond_base_expr
1975ecc953bSthorpej %type	<str>	fs_spec
1989a7f4bbaSchristos %type	<flag>	fflags fflag oflags oflag
199611f2b9cSuebayasi %type	<str>	rule
2004e34eebcSdholland %type	<attr>	depend
2015ecc953bSthorpej %type	<devb>	devbase
2025ecc953bSthorpej %type	<deva>	devattach_opt
20316a8771bSdholland %type	<list>	atlist
20416a8771bSdholland %type	<loclist> interface_opt
2055ecc953bSthorpej %type	<str>	atname
20616a8771bSdholland %type	<loclist>	loclist locdef
2075ecc953bSthorpej %type	<str>	locdefault
20816a8771bSdholland %type	<loclist>	values locdefaults
2094e34eebcSdholland %type	<attrlist>	depend_list depends
21016a8771bSdholland %type	<loclist>	locators locator
2115ecc953bSthorpej %type	<list>	dev_spec
2125ecc953bSthorpej %type	<str>	device_instance
2135ecc953bSthorpej %type	<str>	attachment
2145ecc953bSthorpej %type	<str>	value
2159a7f4bbaSchristos %type	<val>	major_minor
2165ecc953bSthorpej %type	<num>	signed_number
2173dbd1573Schristos %type	<i32>	int32 npseudo device_flags no
2185ecc953bSthorpej %type	<str>	deffs
2195ecc953bSthorpej %type	<list>	deffses
220d74eb995Sdholland %type	<defoptlist>	defopt
221d74eb995Sdholland %type	<defoptlist>	defopts
222ebd45116Sdholland %type	<str>	optdepend
223ebd45116Sdholland %type	<list>	optdepends
224ebd45116Sdholland %type	<list>	optdepend_list
2255ecc953bSthorpej %type	<str>	optfile_opt
2264c38d3adSdholland %type	<list>	subarches
2275ecc953bSthorpej %type	<str>	filename stringvalue locname mkvarname
2289a7f4bbaSchristos %type	<devmajor>	device_major_block device_major_char
2293da3ab25Spooka %type	<list>	devnodes devnodetype devnodeflags devnode_dims
2305ecc953bSthorpej 
2315ecc953bSthorpej %%
2325ecc953bSthorpej 
2335ecc953bSthorpej /*
23487ef93d9Suebayasi  * A complete configuration consists of both the selection part (a
235682f0402Sdholland  * kernel config such as GENERIC or SKYNET, plus also the various
236682f0402Sdholland  * std.* files), which selects the material to be in the kernel, and
237682f0402Sdholland  * also the definition part (files, files.*, etc.) that declares what
238682f0402Sdholland  * material is available to be placed in kernels.
239682f0402Sdholland  *
240682f0402Sdholland  * The two parts have almost entirely separate syntaxes. This grammar
241682f0402Sdholland  * covers both of them. When config is run on a kernel configuration
242682f0402Sdholland  * file, the std.* file for the port is included explicitly. The
243682f0402Sdholland  * files.* files are included implicitly when the std.* file declares
244682f0402Sdholland  * the machine type.
245682f0402Sdholland  *
246682f0402Sdholland  * The machine spec, which brings in the definition part, must appear
247682f0402Sdholland  * before all configuration material except for the "topthings"; these
248682f0402Sdholland  * are the "source" and "build" declarations that tell config where
249682f0402Sdholland  * things are. These are not used by default.
250682f0402Sdholland  *
251682f0402Sdholland  * A previous version of this comment contained the following text:
252682f0402Sdholland  *
253682f0402Sdholland  *       Note that we do not have sufficient keywords to enforce any
254682f0402Sdholland  *       order between elements of "topthings" without introducing
255682f0402Sdholland  *       shift/reduce conflicts.  Instead, check order requirements in
256682f0402Sdholland  *       the C code.
257682f0402Sdholland  *
258682f0402Sdholland  * As of March 2012 this comment makes no sense, as there are only two
259682f0402Sdholland  * topthings and no reason for them to be forcibly ordered.
260682f0402Sdholland  * Furthermore, the statement about conflicts is false.
2615ecc953bSthorpej  */
2625ecc953bSthorpej 
263682f0402Sdholland /* Complete configuration. */
2644c38d3adSdholland configuration:
26587ef93d9Suebayasi 	topthings machine_spec definition_part selection_part
266c1e3ceeaSdholland ;
267682f0402Sdholland 
268682f0402Sdholland /* Sequence of zero or more topthings. */
2695ecc953bSthorpej topthings:
270c1e3ceeaSdholland 	  /* empty */
271c1e3ceeaSdholland 	| topthings topthing
272c1e3ceeaSdholland ;
2735ecc953bSthorpej 
274682f0402Sdholland /* Directory specification. */
2755ecc953bSthorpej topthing:
276244ef363Sdholland 	                  '\n'
277244ef363Sdholland 	| SOURCE filename '\n'		{ if (!srcdir) srcdir = $2; }
278c1e3ceeaSdholland 	| BUILD  filename '\n'		{ if (!builddir) builddir = $2; }
279c1e3ceeaSdholland ;
2805ecc953bSthorpej 
281682f0402Sdholland /* "machine foo" from std.whatever */
2825ecc953bSthorpej machine_spec:
283c1e3ceeaSdholland 	  XMACHINE WORD '\n'			{ setmachine($2,NULL,NULL,0); }
2844c38d3adSdholland 	| XMACHINE WORD WORD '\n'		{ setmachine($2,$3,NULL,0); }
2854c38d3adSdholland 	| XMACHINE WORD WORD subarches '\n'	{ setmachine($2,$3,$4,0); }
286c1e3ceeaSdholland 	| IOCONF WORD '\n'			{ setmachine($2,NULL,NULL,1); }
287c1e3ceeaSdholland 	| error { stop("cannot proceed without machine or ioconf specifier"); }
288c1e3ceeaSdholland ;
2895ecc953bSthorpej 
2904c38d3adSdholland /* One or more sub-arches. */
2915ecc953bSthorpej subarches:
292244ef363Sdholland 	  WORD				{ $$ = new_n($1); }
293244ef363Sdholland 	| subarches WORD		{ $$ = new_nx($2, $1); }
294c1e3ceeaSdholland ;
2955ecc953bSthorpej 
2963dbd1573Schristos no:
2973dbd1573Schristos 	  NO	{ $$ = 0; }
2983dbd1573Schristos 	| CNO	{ $$ = 1; }
2993dbd1573Schristos ;
3003dbd1573Schristos 
301682f0402Sdholland /************************************************************/
302682f0402Sdholland 
3035ecc953bSthorpej /*
3045ecc953bSthorpej  * The machine definitions grammar.
3055ecc953bSthorpej  */
306682f0402Sdholland 
307682f0402Sdholland /* Complete definition part: the contents of all files.* files. */
3084c38d3adSdholland definition_part:
309*564e2cecSuwe 	definitions ENDDEFS		{
310*564e2cecSuwe 		CFGDBG(1, "ENDDEFS");
311*564e2cecSuwe 		check_maxpart();
312*564e2cecSuwe 		check_version();
313*564e2cecSuwe 	}
314c1e3ceeaSdholland ;
3155ecc953bSthorpej 
3164c38d3adSdholland /* Zero or more definitions. Trap errors. */
3174c38d3adSdholland definitions:
3184c38d3adSdholland 	  /* empty */
3194c38d3adSdholland 	| definitions '\n'
3202839b938Sdholland 	| definitions definition '\n'	{ wrap_continue(); }
3212839b938Sdholland 	| definitions error '\n'	{ wrap_cleanup(); }
3224c38d3adSdholland 	| definitions ENDFILE		{ enddefs(); checkfiles(); }
323c1e3ceeaSdholland ;
3245ecc953bSthorpej 
325682f0402Sdholland /* A single definition. */
3264c38d3adSdholland definition:
32738146c24Suebayasi 	  define_file
32838146c24Suebayasi 	| define_object
32938146c24Suebayasi 	| define_device_major
33038146c24Suebayasi 	| define_prefix
33166c67372Suebayasi 	| define_buildprefix
33238146c24Suebayasi 	| define_devclass
33338146c24Suebayasi 	| define_filesystems
33438146c24Suebayasi 	| define_attribute
33538146c24Suebayasi 	| define_option
33638146c24Suebayasi 	| define_flag
33738146c24Suebayasi 	| define_obsolete_flag
33838146c24Suebayasi 	| define_param
33938146c24Suebayasi 	| define_obsolete_param
34038146c24Suebayasi 	| define_device
34138146c24Suebayasi 	| define_device_attachment
34238146c24Suebayasi 	| define_maxpartitions
34338146c24Suebayasi 	| define_maxusers
34438146c24Suebayasi 	| define_makeoptions
34538146c24Suebayasi 	| define_pseudo
34638146c24Suebayasi 	| define_pseudodev
34738146c24Suebayasi 	| define_major
34838146c24Suebayasi 	| define_version
349c1e3ceeaSdholland ;
3505ecc953bSthorpej 
35182d86132Sdholland /* source file: file foo/bar.c bar|baz needs-flag compile-with blah */
35238146c24Suebayasi define_file:
353611f2b9cSuebayasi 	XFILE filename fopts fflags rule	{ addfile($2, $3, $4, $5); }
354c1e3ceeaSdholland ;
3555ecc953bSthorpej 
35638146c24Suebayasi /* object file: object zot.o foo|zot needs-flag */
35738146c24Suebayasi define_object:
358371348aaSuebayasi 	XOBJECT filename fopts oflags	{ addfile($2, $3, $4, NULL); }
35938146c24Suebayasi ;
36038146c24Suebayasi 
36138146c24Suebayasi /* device major declaration */
36238146c24Suebayasi define_device_major:
36338146c24Suebayasi 	DEVICE_MAJOR WORD device_major_char device_major_block fopts devnodes
36438146c24Suebayasi 					{
36538146c24Suebayasi 		adddevm($2, $3, $4, $5, $6);
36638146c24Suebayasi 		do_devsw = 1;
36738146c24Suebayasi 	}
36838146c24Suebayasi ;
36938146c24Suebayasi 
37038146c24Suebayasi /* prefix delimiter */
37138146c24Suebayasi define_prefix:
37238146c24Suebayasi 	  PREFIX filename		{ prefix_push($2); }
37338146c24Suebayasi 	| PREFIX			{ prefix_pop(); }
37438146c24Suebayasi ;
37538146c24Suebayasi 
37666c67372Suebayasi define_buildprefix:
37766c67372Suebayasi 	  BUILDPREFIX filename		{ buildprefix_push($2); }
37866c67372Suebayasi 	| BUILDPREFIX WORD		{ buildprefix_push($2); }
37966c67372Suebayasi 	| BUILDPREFIX			{ buildprefix_pop(); }
38066c67372Suebayasi ;
38166c67372Suebayasi 
38238146c24Suebayasi define_devclass:
383bb4307a6Suebayasi 	DEVCLASS WORD			{ (void)defdevclass($2, NULL, NULL, 1); }
38438146c24Suebayasi ;
38538146c24Suebayasi 
38638146c24Suebayasi define_filesystems:
38738146c24Suebayasi 	DEFFS deffses optdepend_list	{ deffilesystem($2, $3); }
38838146c24Suebayasi ;
38938146c24Suebayasi 
39038146c24Suebayasi define_attribute:
39138146c24Suebayasi 	DEFINE WORD interface_opt depend_list
392bb4307a6Suebayasi 					{ (void)defattr0($2, $3, $4, 0); }
39338146c24Suebayasi ;
39438146c24Suebayasi 
39538146c24Suebayasi define_option:
39638146c24Suebayasi 	DEFOPT optfile_opt defopts optdepend_list
39738146c24Suebayasi 					{ defoption($2, $3, $4); }
39838146c24Suebayasi ;
39938146c24Suebayasi 
40038146c24Suebayasi define_flag:
40138146c24Suebayasi 	DEFFLAG optfile_opt defopts optdepend_list
40238146c24Suebayasi 					{ defflag($2, $3, $4, 0); }
40338146c24Suebayasi ;
40438146c24Suebayasi 
40538146c24Suebayasi define_obsolete_flag:
40638146c24Suebayasi 	OBSOLETE DEFFLAG optfile_opt defopts
40738146c24Suebayasi 					{ defflag($3, $4, NULL, 1); }
40838146c24Suebayasi ;
40938146c24Suebayasi 
41038146c24Suebayasi define_param:
41138146c24Suebayasi 	DEFPARAM optfile_opt defopts optdepend_list
41238146c24Suebayasi 					{ defparam($2, $3, $4, 0); }
41338146c24Suebayasi ;
41438146c24Suebayasi 
41538146c24Suebayasi define_obsolete_param:
41638146c24Suebayasi 	OBSOLETE DEFPARAM optfile_opt defopts
41738146c24Suebayasi 					{ defparam($3, $4, NULL, 1); }
41838146c24Suebayasi ;
41938146c24Suebayasi 
42038146c24Suebayasi define_device:
42138146c24Suebayasi 	DEVICE devbase interface_opt depend_list
42238146c24Suebayasi 					{ defdev($2, $3, $4, 0); }
42338146c24Suebayasi ;
42438146c24Suebayasi 
42538146c24Suebayasi define_device_attachment:
42638146c24Suebayasi 	ATTACH devbase AT atlist devattach_opt depend_list
42738146c24Suebayasi 					{ defdevattach($5, $2, $4, $6); }
42838146c24Suebayasi ;
42938146c24Suebayasi 
43038146c24Suebayasi define_maxpartitions:
4319a7f4bbaSchristos 	MAXPARTITIONS int32		{ maxpartitions = $2; }
43238146c24Suebayasi ;
43338146c24Suebayasi 
43438146c24Suebayasi define_maxusers:
4359a7f4bbaSchristos 	MAXUSERS int32 int32 int32
4369a7f4bbaSchristos 					{ setdefmaxusers($2, $3, $4); }
43738146c24Suebayasi ;
43838146c24Suebayasi 
43938146c24Suebayasi define_makeoptions:
44038146c24Suebayasi 	MAKEOPTIONS condmkopt_list
44138146c24Suebayasi ;
44238146c24Suebayasi 
44338146c24Suebayasi define_pseudo:
44438146c24Suebayasi 	/* interface_opt in DEFPSEUDO is for backwards compatibility */
44538146c24Suebayasi 	DEFPSEUDO devbase interface_opt depend_list
44638146c24Suebayasi 					{ defdev($2, $3, $4, 1); }
44738146c24Suebayasi ;
44838146c24Suebayasi 
44938146c24Suebayasi define_pseudodev:
45038146c24Suebayasi 	DEFPSEUDODEV devbase interface_opt depend_list
45138146c24Suebayasi 					{ defdev($2, $3, $4, 2); }
45238146c24Suebayasi ;
45338146c24Suebayasi 
45438146c24Suebayasi define_major:
45538146c24Suebayasi 	MAJOR '{' majorlist '}'
45638146c24Suebayasi ;
45738146c24Suebayasi 
45838146c24Suebayasi define_version:
4599a7f4bbaSchristos 	VERSION int32		{ setversion($2); }
46038146c24Suebayasi ;
46138146c24Suebayasi 
4624e34eebcSdholland /* file options: optional expression of conditions */
46382d86132Sdholland fopts:
46482d86132Sdholland 	  /* empty */			{ $$ = NULL; }
4654e34eebcSdholland 	| condexpr			{ $$ = $1; }
46682d86132Sdholland ;
46782d86132Sdholland 
46882d86132Sdholland /* zero or more flags for a file */
469ebd45116Sdholland fflags:
47082d86132Sdholland 	  /* empty */			{ $$ = 0; }
471ebd45116Sdholland 	| fflags fflag			{ $$ = $1 | $2; }
47282d86132Sdholland ;
47382d86132Sdholland 
47482d86132Sdholland /* one flag for a file */
47582d86132Sdholland fflag:
47682d86132Sdholland 	  NEEDS_COUNT			{ $$ = FI_NEEDSCOUNT; }
47782d86132Sdholland 	| NEEDS_FLAG			{ $$ = FI_NEEDSFLAG; }
47882d86132Sdholland ;
47982d86132Sdholland 
480611f2b9cSuebayasi /* extra compile directive for a source file */
481611f2b9cSuebayasi rule:
482611f2b9cSuebayasi 	  /* empty */			{ $$ = NULL; }
483611f2b9cSuebayasi 	| COMPILE_WITH stringvalue	{ $$ = $2; }
484611f2b9cSuebayasi ;
485611f2b9cSuebayasi 
48682d86132Sdholland /* zero or more flags for an object file */
487ebd45116Sdholland oflags:
48882d86132Sdholland 	  /* empty */			{ $$ = 0; }
489ebd45116Sdholland 	| oflags oflag			{ $$ = $1 | $2; }
49082d86132Sdholland ;
49182d86132Sdholland 
49282d86132Sdholland /* a single flag for an object file */
49382d86132Sdholland oflag:
494371348aaSuebayasi 	NEEDS_FLAG			{ $$ = FI_NEEDSFLAG; }
49582d86132Sdholland ;
49682d86132Sdholland 
49782d86132Sdholland /* char 55 */
49882d86132Sdholland device_major_char:
49982d86132Sdholland 	  /* empty */			{ $$ = -1; }
5009a7f4bbaSchristos 	| CHAR int32			{ $$ = $2; }
50182d86132Sdholland ;
50282d86132Sdholland 
50382d86132Sdholland /* block 33 */
50482d86132Sdholland device_major_block:
50582d86132Sdholland 	  /* empty */			{ $$ = -1; }
5069a7f4bbaSchristos 	| BLOCK int32			{ $$ = $2; }
50782d86132Sdholland ;
50882d86132Sdholland 
50982d86132Sdholland /* device node specification */
51082d86132Sdholland devnodes:
51182d86132Sdholland 	  /* empty */			{ $$ = new_s("DEVNODE_DONTBOTHER"); }
51282d86132Sdholland 	| devnodetype ',' devnodeflags	{ $$ = nvcat($1, $3); }
51382d86132Sdholland 	| devnodetype			{ $$ = $1; }
51482d86132Sdholland ;
51582d86132Sdholland 
51682d86132Sdholland /* device nodes without flags */
51782d86132Sdholland devnodetype:
51882d86132Sdholland 	  SINGLE			{ $$ = new_s("DEVNODE_SINGLE"); }
51982d86132Sdholland 	| VECTOR '=' devnode_dims  { $$ = nvcat(new_s("DEVNODE_VECTOR"), $3); }
52082d86132Sdholland ;
52182d86132Sdholland 
52282d86132Sdholland /* dimensions (?) */
52382d86132Sdholland devnode_dims:
52482d86132Sdholland 	  NUMBER			{ $$ = new_i($1.val); }
52582d86132Sdholland 	| NUMBER ':' NUMBER		{
52682d86132Sdholland 		struct nvlist *__nv1, *__nv2;
52782d86132Sdholland 
52882d86132Sdholland 		__nv1 = new_i($1.val);
52982d86132Sdholland 		__nv2 = new_i($3.val);
53082d86132Sdholland 		$$ = nvcat(__nv1, __nv2);
53182d86132Sdholland 	  }
53282d86132Sdholland ;
53382d86132Sdholland 
53482d86132Sdholland /* flags for device nodes */
53582d86132Sdholland devnodeflags:
53682d86132Sdholland 	LINKZERO			{ $$ = new_s("DEVNODE_FLAG_LINKZERO");}
53782d86132Sdholland ;
53882d86132Sdholland 
539682f0402Sdholland /* one or more file system names */
5405ecc953bSthorpej deffses:
541c1e3ceeaSdholland 	  deffs				{ $$ = new_n($1); }
542c1e3ceeaSdholland 	| deffses deffs			{ $$ = new_nx($2, $1); }
543c1e3ceeaSdholland ;
5445ecc953bSthorpej 
545682f0402Sdholland /* a single file system name */
5465ecc953bSthorpej deffs:
547c1e3ceeaSdholland 	WORD				{ $$ = $1; }
548c1e3ceeaSdholland ;
5495ecc953bSthorpej 
5504c38d3adSdholland /* optional locator specification */
5515ecc953bSthorpej interface_opt:
552c1e3ceeaSdholland 	  /* empty */			{ $$ = NULL; }
55316a8771bSdholland 	| '{' '}'			{ $$ = present_loclist(NULL); }
55416a8771bSdholland 	| '{' loclist '}'		{ $$ = present_loclist($2); }
555c1e3ceeaSdholland ;
5565ecc953bSthorpej 
557682f0402Sdholland /*
558682f0402Sdholland  * loclist order matters, must use right recursion
559682f0402Sdholland  * XXX wot?
560682f0402Sdholland  */
561682f0402Sdholland 
562682f0402Sdholland /* list of locator definitions */
5635ecc953bSthorpej loclist:
564c1e3ceeaSdholland 	  locdef			{ $$ = $1; }
565c1e3ceeaSdholland 	| locdef ',' loclist		{ $$ = $1; app($1, $3); }
566c1e3ceeaSdholland ;
5675ecc953bSthorpej 
568682f0402Sdholland /*
569682f0402Sdholland  * "[ WORD locdefault ]" syntax may be unnecessary...
570682f0402Sdholland  */
571682f0402Sdholland 
572682f0402Sdholland /* one locator definition */
5735ecc953bSthorpej locdef:
57416a8771bSdholland 	  locname locdefault 		{ $$ = MK3(loc, $1, $2, 0); }
57516a8771bSdholland 	| locname			{ $$ = MK3(loc, $1, NULL, 0); }
57616a8771bSdholland 	| '[' locname locdefault ']'	{ $$ = MK3(loc, $2, $3, 1); }
5779a7f4bbaSchristos 	| locname '[' int32 ']'	{ $$ = locarray($1, $3, NULL, 0); }
5789a7f4bbaSchristos 	| locname '[' int32 ']' locdefaults
5799a7f4bbaSchristos 					{ $$ = locarray($1, $3, $5, 0); }
5809a7f4bbaSchristos 	| '[' locname '[' int32 ']' locdefaults ']'
5819a7f4bbaSchristos 					{ $$ = locarray($2, $4, $6, 1); }
582c1e3ceeaSdholland ;
5835ecc953bSthorpej 
584682f0402Sdholland /* locator name */
5855ecc953bSthorpej locname:
586c1e3ceeaSdholland 	  WORD				{ $$ = $1; }
587c1e3ceeaSdholland 	| QSTRING			{ $$ = $1; }
588c1e3ceeaSdholland ;
5895ecc953bSthorpej 
590682f0402Sdholland /* locator default value */
5915ecc953bSthorpej locdefault:
592c1e3ceeaSdholland 	'=' value			{ $$ = $2; }
593c1e3ceeaSdholland ;
5945ecc953bSthorpej 
595682f0402Sdholland /* multiple locator default values */
5965ecc953bSthorpej locdefaults:
597c1e3ceeaSdholland 	'=' '{' values '}'		{ $$ = $3; }
598c1e3ceeaSdholland ;
5995ecc953bSthorpej 
6004e34eebcSdholland /* list of depends, may be empty */
6014e34eebcSdholland depend_list:
602c1e3ceeaSdholland 	  /* empty */			{ $$ = NULL; }
6034e34eebcSdholland 	| ':' depends			{ $$ = $2; }
604c1e3ceeaSdholland ;
6055ecc953bSthorpej 
6064e34eebcSdholland /* one or more depend items */
6074e34eebcSdholland depends:
6084e34eebcSdholland 	  depend			{ $$ = MK2(attrlist, NULL, $1); }
6094e34eebcSdholland 	| depends ',' depend		{ $$ = MK2(attrlist, $1, $3); }
610c1e3ceeaSdholland ;
6115ecc953bSthorpej 
6124e34eebcSdholland /* one depend item (which is an attribute) */
6134e34eebcSdholland depend:
61451deed3eSuebayasi 	WORD				{ $$ = refattr($1); }
615c1e3ceeaSdholland ;
6165ecc953bSthorpej 
617ebd45116Sdholland /* list of option depends, may be empty */
618ebd45116Sdholland optdepend_list:
619ebd45116Sdholland 	  /* empty */			{ $$ = NULL; }
620ebd45116Sdholland 	| ':' optdepends		{ $$ = $2; }
621ebd45116Sdholland ;
622ebd45116Sdholland 
623ebd45116Sdholland /* a list of option dependencies */
624ebd45116Sdholland optdepends:
625ebd45116Sdholland 	  optdepend			{ $$ = new_n($1); }
626ebd45116Sdholland 	| optdepends ',' optdepend	{ $$ = new_nx($3, $1); }
627ebd45116Sdholland ;
628ebd45116Sdholland 
629ebd45116Sdholland /* one option depend, which is an option name */
630ebd45116Sdholland optdepend:
631ebd45116Sdholland 	WORD				{ $$ = $1; }
632ebd45116Sdholland ;
633ebd45116Sdholland 
634ebd45116Sdholland 
63582d86132Sdholland /* list of places to attach: attach blah at ... */
63682d86132Sdholland atlist:
63782d86132Sdholland 	  atname			{ $$ = new_n($1); }
63882d86132Sdholland 	| atlist ',' atname		{ $$ = new_nx($3, $1); }
63982d86132Sdholland ;
64082d86132Sdholland 
64182d86132Sdholland /* a place to attach a device */
64282d86132Sdholland atname:
64382d86132Sdholland 	  WORD				{ $$ = $1; }
64482d86132Sdholland 	| ROOT				{ $$ = NULL; }
64582d86132Sdholland ;
64682d86132Sdholland 
64782d86132Sdholland /* one or more defined options */
64882d86132Sdholland defopts:
64982d86132Sdholland 	  defopt			{ $$ = $1; }
650d74eb995Sdholland 	| defopts defopt		{ $$ = defoptlist_append($2, $1); }
65182d86132Sdholland ;
65282d86132Sdholland 
65382d86132Sdholland /* one defined option */
65482d86132Sdholland defopt:
655d74eb995Sdholland 	  WORD				{ $$ = MK3(defoptlist, $1, NULL, NULL); }
656d74eb995Sdholland 	| WORD '=' value		{ $$ = MK3(defoptlist, $1, $3, NULL); }
657d74eb995Sdholland 	| WORD COLONEQ value		{ $$ = MK3(defoptlist, $1, NULL, $3); }
658d74eb995Sdholland 	| WORD '=' value COLONEQ value	{ $$ = MK3(defoptlist, $1, $3, $5); }
65982d86132Sdholland ;
66082d86132Sdholland 
66182d86132Sdholland /* list of conditional makeoptions */
66282d86132Sdholland condmkopt_list:
66382d86132Sdholland 	  condmkoption
66482d86132Sdholland 	| condmkopt_list ',' condmkoption
66582d86132Sdholland ;
66682d86132Sdholland 
66782d86132Sdholland /* one conditional make option */
66882d86132Sdholland condmkoption:
6694e34eebcSdholland 	condexpr mkvarname PLUSEQ value	{ appendcondmkoption($1, $2, $4); }
67082d86132Sdholland ;
67182d86132Sdholland 
67282d86132Sdholland /* device name */
67382d86132Sdholland devbase:
67482d86132Sdholland 	WORD				{ $$ = getdevbase($1); }
67582d86132Sdholland ;
67682d86132Sdholland 
67782d86132Sdholland /* optional attachment: with foo */
67882d86132Sdholland devattach_opt:
67982d86132Sdholland 	  /* empty */			{ $$ = NULL; }
68082d86132Sdholland 	| WITH WORD			{ $$ = getdevattach($2); }
68182d86132Sdholland ;
68282d86132Sdholland 
683682f0402Sdholland /* list of major numbers */
684682f0402Sdholland /* XXX why is this right-recursive? */
6855ecc953bSthorpej majorlist:
686c1e3ceeaSdholland 	  majordef
687c1e3ceeaSdholland 	| majorlist ',' majordef
688c1e3ceeaSdholland ;
6895ecc953bSthorpej 
690682f0402Sdholland /* one major number */
6915ecc953bSthorpej majordef:
6929a7f4bbaSchristos 	devbase '=' int32		{ setmajor($1, $3); }
6939a7f4bbaSchristos ;
6949a7f4bbaSchristos 
6959a7f4bbaSchristos int32:
6969a7f4bbaSchristos 	NUMBER	{
6979a7f4bbaSchristos 		if ($1.val > INT_MAX || $1.val < INT_MIN)
6989a7f4bbaSchristos 			cfgerror("overflow %" PRId64, $1.val);
6999a7f4bbaSchristos 		else
7009a7f4bbaSchristos 			$$ = (int32_t)$1.val;
7019a7f4bbaSchristos 	}
702c1e3ceeaSdholland ;
7035ecc953bSthorpej 
704682f0402Sdholland /************************************************************/
7055ecc953bSthorpej 
7065ecc953bSthorpej /*
70787ef93d9Suebayasi  * The selection grammar.
7085ecc953bSthorpej  */
709682f0402Sdholland 
71087ef93d9Suebayasi /* Complete selection part: all std.* files plus selected config. */
71187ef93d9Suebayasi selection_part:
71287ef93d9Suebayasi 	selections
713c1e3ceeaSdholland ;
7145ecc953bSthorpej 
7154c38d3adSdholland /* Zero or more config items. Trap errors. */
71687ef93d9Suebayasi selections:
7174c38d3adSdholland 	  /* empty */
71887ef93d9Suebayasi 	| selections '\n'
71987ef93d9Suebayasi 	| selections selection '\n'	{ wrap_continue(); }
72087ef93d9Suebayasi 	| selections error '\n'		{ wrap_cleanup(); }
721c1e3ceeaSdholland ;
7225ecc953bSthorpej 
723682f0402Sdholland /* One config item. */
72487ef93d9Suebayasi selection:
7254c38d3adSdholland 	  definition
7268d928a75Suebayasi 	| select_attr
7278d928a75Suebayasi 	| select_no_attr
72838146c24Suebayasi 	| select_no_filesystems
72938146c24Suebayasi 	| select_filesystems
73038146c24Suebayasi 	| select_no_makeoptions
73138146c24Suebayasi 	| select_makeoptions
73238146c24Suebayasi 	| select_no_options
73338146c24Suebayasi 	| select_options
73438146c24Suebayasi 	| select_maxusers
73538146c24Suebayasi 	| select_ident
73638146c24Suebayasi 	| select_no_ident
73738146c24Suebayasi 	| select_config
73838146c24Suebayasi 	| select_no_config
73938146c24Suebayasi 	| select_no_pseudodev
74038146c24Suebayasi 	| select_pseudodev
74138146c24Suebayasi 	| select_pseudoroot
74238146c24Suebayasi 	| select_no_device_instance_attachment
74338146c24Suebayasi 	| select_no_device_attachment
74438146c24Suebayasi 	| select_no_device_instance
74538146c24Suebayasi 	| select_device_instance
74638146c24Suebayasi ;
74738146c24Suebayasi 
7488d928a75Suebayasi select_attr:
7498d928a75Suebayasi 	SELECT WORD			{ addattr($2); }
7508d928a75Suebayasi ;
7518d928a75Suebayasi 
7528d928a75Suebayasi select_no_attr:
7533dbd1573Schristos 	no SELECT WORD			{ delattr($3, $1); }
7548d928a75Suebayasi ;
7558d928a75Suebayasi 
75638146c24Suebayasi select_no_filesystems:
7573dbd1573Schristos 	no FILE_SYSTEM { nowarn = $1; } no_fs_list { nowarn = 0; }
75838146c24Suebayasi ;
75938146c24Suebayasi 
76038146c24Suebayasi select_filesystems:
76138146c24Suebayasi 	FILE_SYSTEM fs_list
76238146c24Suebayasi ;
76338146c24Suebayasi 
76438146c24Suebayasi select_no_makeoptions:
7653dbd1573Schristos 	no MAKEOPTIONS { nowarn = $1; } no_mkopt_list { nowarn = 0; }
76638146c24Suebayasi ;
76738146c24Suebayasi 
76838146c24Suebayasi select_makeoptions:
76938146c24Suebayasi 	MAKEOPTIONS mkopt_list
77038146c24Suebayasi ;
77138146c24Suebayasi 
77238146c24Suebayasi select_no_options:
7733dbd1573Schristos 	no OPTIONS { nowarn = $1; } no_opt_list { nowarn = 0; }
77438146c24Suebayasi ;
77538146c24Suebayasi 
77638146c24Suebayasi select_options:
77738146c24Suebayasi 	OPTIONS opt_list
77838146c24Suebayasi ;
77938146c24Suebayasi 
78038146c24Suebayasi select_maxusers:
781e8a8b10dSuebayasi 	MAXUSERS int32			{ setmaxusers($2); }
78238146c24Suebayasi ;
78338146c24Suebayasi 
78438146c24Suebayasi select_ident:
78538146c24Suebayasi 	IDENT stringvalue		{ setident($2); }
78638146c24Suebayasi ;
78738146c24Suebayasi 
78838146c24Suebayasi select_no_ident:
7893dbd1573Schristos 	no IDENT			{ setident(NULL); }
79038146c24Suebayasi ;
79138146c24Suebayasi 
79238146c24Suebayasi select_config:
79338146c24Suebayasi 	CONFIG conf root_spec sysparam_list
794c1e3ceeaSdholland 					{ addconf(&conf); }
79538146c24Suebayasi ;
79638146c24Suebayasi 
79738146c24Suebayasi select_no_config:
7983dbd1573Schristos 	no CONFIG WORD			{ delconf($3, $1); }
79938146c24Suebayasi ;
80038146c24Suebayasi 
80138146c24Suebayasi select_no_pseudodev:
8023dbd1573Schristos 	no PSEUDO_DEVICE WORD		{ delpseudo($3, $1); }
80338146c24Suebayasi ;
80438146c24Suebayasi 
80538146c24Suebayasi select_pseudodev:
80638146c24Suebayasi 	PSEUDO_DEVICE WORD npseudo	{ addpseudo($2, $3); }
80738146c24Suebayasi ;
80838146c24Suebayasi 
80938146c24Suebayasi select_pseudoroot:
81038146c24Suebayasi 	PSEUDO_ROOT device_instance	{ addpseudoroot($2); }
81138146c24Suebayasi ;
81238146c24Suebayasi 
81338146c24Suebayasi select_no_device_instance_attachment:
8143dbd1573Schristos 	no device_instance AT attachment
8153dbd1573Schristos 					{ deldevi($2, $4, $1); }
81638146c24Suebayasi ;
81738146c24Suebayasi 
81838146c24Suebayasi select_no_device_attachment:
8193dbd1573Schristos 	no DEVICE AT attachment		{ deldeva($4, $1); }
82038146c24Suebayasi ;
82138146c24Suebayasi 
82238146c24Suebayasi select_no_device_instance:
8233dbd1573Schristos 	no device_instance		{ deldev($2, $1); }
82438146c24Suebayasi ;
82538146c24Suebayasi 
82638146c24Suebayasi select_device_instance:
82738146c24Suebayasi 	device_instance AT attachment locators device_flags
828c1e3ceeaSdholland 					{ adddev($1, $3, $4, $5); }
829c1e3ceeaSdholland ;
8305ecc953bSthorpej 
831682f0402Sdholland /* list of filesystems */
8325ecc953bSthorpej fs_list:
833c1e3ceeaSdholland 	  fsoption
834c1e3ceeaSdholland 	| fs_list ',' fsoption
835c1e3ceeaSdholland ;
8365ecc953bSthorpej 
837682f0402Sdholland /* one filesystem */
8385ecc953bSthorpej fsoption:
839c1e3ceeaSdholland 	WORD				{ addfsoption($1); }
840c1e3ceeaSdholland ;
8415ecc953bSthorpej 
842682f0402Sdholland /* list of filesystems that had NO in front */
8435ecc953bSthorpej no_fs_list:
844c1e3ceeaSdholland 	  no_fsoption
845c1e3ceeaSdholland 	| no_fs_list ',' no_fsoption
846c1e3ceeaSdholland ;
8475ecc953bSthorpej 
848682f0402Sdholland /* one filesystem that had NO in front */
8495ecc953bSthorpej no_fsoption:
8503dbd1573Schristos 	WORD				{ delfsoption($1, nowarn); }
851c1e3ceeaSdholland ;
8525ecc953bSthorpej 
853682f0402Sdholland /* list of make options */
854682f0402Sdholland /* XXX why is this right-recursive? */
8555ecc953bSthorpej mkopt_list:
856c1e3ceeaSdholland 	  mkoption
857c1e3ceeaSdholland 	| mkopt_list ',' mkoption
858c1e3ceeaSdholland ;
8595ecc953bSthorpej 
860682f0402Sdholland /* one make option */
8615ecc953bSthorpej mkoption:
862c1e3ceeaSdholland 	  mkvarname '=' value		{ addmkoption($1, $3); }
863c1e3ceeaSdholland 	| mkvarname PLUSEQ value	{ appendmkoption($1, $3); }
864c1e3ceeaSdholland ;
8655ecc953bSthorpej 
866682f0402Sdholland /* list of make options that had NO in front */
8675ecc953bSthorpej no_mkopt_list:
868c1e3ceeaSdholland 	  no_mkoption
869c1e3ceeaSdholland 	| no_mkopt_list ',' no_mkoption
870c1e3ceeaSdholland ;
8715ecc953bSthorpej 
872682f0402Sdholland /* one make option that had NO in front */
87382d86132Sdholland /* XXX shouldn't this be mkvarname rather than WORD? */
8745ecc953bSthorpej no_mkoption:
8753dbd1573Schristos 	WORD				{ delmkoption($1, nowarn); }
876c1e3ceeaSdholland ;
8775ecc953bSthorpej 
878682f0402Sdholland /* list of options */
8795ecc953bSthorpej opt_list:
880c1e3ceeaSdholland 	  option
881c1e3ceeaSdholland 	| opt_list ',' option
882c1e3ceeaSdholland ;
8835ecc953bSthorpej 
884682f0402Sdholland /* one option */
8855ecc953bSthorpej option:
886c1e3ceeaSdholland 	  WORD				{ addoption($1, NULL); }
887c1e3ceeaSdholland 	| WORD '=' value		{ addoption($1, $3); }
888c1e3ceeaSdholland ;
8895ecc953bSthorpej 
890682f0402Sdholland /* list of options that had NO in front */
8915ecc953bSthorpej no_opt_list:
892c1e3ceeaSdholland 	  no_option
893c1e3ceeaSdholland 	| no_opt_list ',' no_option
894c1e3ceeaSdholland ;
8955ecc953bSthorpej 
896682f0402Sdholland /* one option that had NO in front */
8975ecc953bSthorpej no_option:
8983dbd1573Schristos 	WORD				{ deloption($1, nowarn); }
899c1e3ceeaSdholland ;
9005ecc953bSthorpej 
901682f0402Sdholland /* the name in "config name root on ..." */
9025ecc953bSthorpej conf:
903c1e3ceeaSdholland 	WORD				{
904c1e3ceeaSdholland 		conf.cf_name = $1;
905f079f926Schristos 		conf.cf_where.w_srcline = currentline();
9065ecc953bSthorpej 		conf.cf_fstype = NULL;
9075ecc953bSthorpej 		conf.cf_root = NULL;
908c1e3ceeaSdholland 		conf.cf_dump = NULL;
909c1e3ceeaSdholland 	}
910c1e3ceeaSdholland ;
9115ecc953bSthorpej 
912682f0402Sdholland /* root fs specification */
9135ecc953bSthorpej root_spec:
9144c38d3adSdholland 	  ROOT on_opt dev_spec		{ setconf(&conf.cf_root, "root", $3); }
9154c38d3adSdholland 	| ROOT on_opt dev_spec fs_spec	{ setconf(&conf.cf_root, "root", $3); }
916c1e3ceeaSdholland ;
9175ecc953bSthorpej 
91882d86132Sdholland /* device for root fs or dump */
91982d86132Sdholland dev_spec:
92079cd2972Smlelstv 	  '?'				{ $$ = new_spi(intern("?"),
92179cd2972Smlelstv 					    NULL,
9229a7f4bbaSchristos 					    (long long)NODEV); }
92379cd2972Smlelstv 	| QSTRING			{ $$ = new_spi($1,
92479cd2972Smlelstv 					    __UNCONST("spec"),
92579cd2972Smlelstv 					    (long long)NODEV); }
92679cd2972Smlelstv 	| WORD				{ $$ = new_spi($1,
92779cd2972Smlelstv 					    NULL,
9289a7f4bbaSchristos 					    (long long)NODEV); }
92982d86132Sdholland 	| major_minor			{ $$ = new_si(NULL, $1); }
93082d86132Sdholland ;
93182d86132Sdholland 
93282d86132Sdholland /* major and minor device number */
93382d86132Sdholland major_minor:
9349c962d50Sjoerg 	MAJOR NUMBER MINOR NUMBER	{ $$ = (int64_t)makedev($2.val, $4.val); }
93582d86132Sdholland ;
93682d86132Sdholland 
937682f0402Sdholland /* filesystem type for root fs specification */
9385ecc953bSthorpej fs_spec:
9394c38d3adSdholland 	  TYPE '?'		   { setfstype(&conf.cf_fstype, intern("?")); }
9404c38d3adSdholland 	| TYPE WORD			{ setfstype(&conf.cf_fstype, $2); }
941c1e3ceeaSdholland ;
9425ecc953bSthorpej 
943682f0402Sdholland /* zero or more additional system parameters */
9445ecc953bSthorpej sysparam_list:
945c1e3ceeaSdholland 	  /* empty */
946c1e3ceeaSdholland 	| sysparam_list sysparam
947c1e3ceeaSdholland ;
9485ecc953bSthorpej 
949682f0402Sdholland /* one additional system parameter (there's only one: dumps) */
9505ecc953bSthorpej sysparam:
951c1e3ceeaSdholland 	DUMPS on_opt dev_spec	       { setconf(&conf.cf_dump, "dumps", $3); }
952c1e3ceeaSdholland ;
9535ecc953bSthorpej 
954682f0402Sdholland /* number of pseudo devices to configure (which is optional) */
9555ecc953bSthorpej npseudo:
956c1e3ceeaSdholland 	  /* empty */			{ $$ = 1; }
9579a7f4bbaSchristos 	| int32				{ $$ = $1; }
958c1e3ceeaSdholland ;
9595ecc953bSthorpej 
960682f0402Sdholland /* name of a device to configure */
9615ecc953bSthorpej device_instance:
962c1e3ceeaSdholland 	  WORD				{ $$ = $1; }
963c1e3ceeaSdholland 	| WORD '*'			{ $$ = starref($1); }
964c1e3ceeaSdholland ;
9655ecc953bSthorpej 
966682f0402Sdholland /* name of a device to configure an attachment to */
9675ecc953bSthorpej attachment:
968c1e3ceeaSdholland 	  ROOT				{ $$ = NULL; }
969c1e3ceeaSdholland 	| WORD				{ $$ = $1; }
970c1e3ceeaSdholland 	| WORD '?'			{ $$ = wildref($1); }
971c1e3ceeaSdholland ;
9725ecc953bSthorpej 
973682f0402Sdholland /* zero or more locators */
9745ecc953bSthorpej locators:
975c1e3ceeaSdholland 	  /* empty */			{ $$ = NULL; }
976c1e3ceeaSdholland 	| locators locator		{ $$ = $2; app($2, $1); }
977c1e3ceeaSdholland ;
9785ecc953bSthorpej 
979682f0402Sdholland /* one locator */
9805ecc953bSthorpej locator:
98116a8771bSdholland 	  WORD '?'			{ $$ = MK3(loc, $1, NULL, 0); }
98216a8771bSdholland 	| WORD values			{ $$ = namelocvals($1, $2); }
983c1e3ceeaSdholland ;
9845ecc953bSthorpej 
985682f0402Sdholland /* optional device flags */
9864c38d3adSdholland device_flags:
987c1e3ceeaSdholland 	  /* empty */			{ $$ = 0; }
9889a7f4bbaSchristos 	| FLAGS int32			{ $$ = $2; }
989c1e3ceeaSdholland ;
9905ecc953bSthorpej 
99182d86132Sdholland /************************************************************/
99282d86132Sdholland 
99382d86132Sdholland /*
9944e34eebcSdholland  * conditions
99582d86132Sdholland  */
99682d86132Sdholland 
99782d86132Sdholland 
99882d86132Sdholland /*
99982d86132Sdholland  * order of options is important, must use right recursion
100082d86132Sdholland  *
100182d86132Sdholland  * dholland 20120310: wut?
100282d86132Sdholland  */
100382d86132Sdholland 
10044e34eebcSdholland /* expression of conditions */
10054e34eebcSdholland condexpr:
10064e34eebcSdholland 	cond_or_expr
10072b9f70f8Sdholland ;
10082b9f70f8Sdholland 
10094e34eebcSdholland cond_or_expr:
10104e34eebcSdholland 	  cond_and_expr
10119483bda7Sdholland 	| cond_or_expr '|' cond_and_expr	{ $$ = MKF2(cx, or, $1, $3); }
10122b9f70f8Sdholland ;
10132b9f70f8Sdholland 
10144e34eebcSdholland cond_and_expr:
10154e34eebcSdholland 	  cond_prefix_expr
10169483bda7Sdholland 	| cond_and_expr '&' cond_prefix_expr	{ $$ = MKF2(cx, and, $1, $3); }
10172b9f70f8Sdholland ;
10182b9f70f8Sdholland 
10194e34eebcSdholland cond_prefix_expr:
10204e34eebcSdholland 	  cond_base_expr
10212b9f70f8Sdholland /* XXX notyet - need to strengthen downstream first */
10229483bda7Sdholland /*	| '!' cond_prefix_expr			{ $$ = MKF1(cx, not, $2); } */
10232b9f70f8Sdholland ;
10242b9f70f8Sdholland 
10254e34eebcSdholland cond_base_expr:
10264e34eebcSdholland 	  condatom			{ $$ = $1; }
10279483bda7Sdholland 	| '!' condatom			{ $$ = MKF1(cx, not, $2); }
10284e34eebcSdholland 	| '(' condexpr ')'		{ $$ = $2; }
102982d86132Sdholland ;
103082d86132Sdholland 
103182d86132Sdholland /* basic element of config element expression: a config element */
10324e34eebcSdholland condatom:
10339483bda7Sdholland 	WORD				{ $$ = MKF1(cx, atom, $1); }
103482d86132Sdholland ;
103582d86132Sdholland 
103682d86132Sdholland /************************************************************/
103782d86132Sdholland 
103882d86132Sdholland /*
103982d86132Sdholland  * Various nonterminals shared between the grammars.
104082d86132Sdholland  */
104182d86132Sdholland 
104282d86132Sdholland /* variable name for make option */
104382d86132Sdholland mkvarname:
104482d86132Sdholland 	  QSTRING			{ $$ = $1; }
104582d86132Sdholland 	| WORD				{ $$ = $1; }
104682d86132Sdholland ;
104782d86132Sdholland 
104882d86132Sdholland /* optional file for an option */
104982d86132Sdholland optfile_opt:
105082d86132Sdholland 	  /* empty */			{ $$ = NULL; }
105182d86132Sdholland 	| filename			{ $$ = $1; }
105282d86132Sdholland ;
105382d86132Sdholland 
105482d86132Sdholland /* filename. */
105582d86132Sdholland filename:
105682d86132Sdholland 	  QSTRING			{ $$ = $1; }
105782d86132Sdholland 	| PATHNAME			{ $$ = $1; }
105882d86132Sdholland ;
105982d86132Sdholland 
106082d86132Sdholland /* constant value */
106182d86132Sdholland value:
106282d86132Sdholland 	  QSTRING			{ $$ = $1; }
106382d86132Sdholland 	| WORD				{ $$ = $1; }
106482d86132Sdholland 	| EMPTYSTRING			{ $$ = $1; }
106582d86132Sdholland 	| signed_number			{
106682d86132Sdholland 		char bf[40];
106782d86132Sdholland 
106882d86132Sdholland 		(void)snprintf(bf, sizeof(bf), FORMAT($1), (long long)$1.val);
106982d86132Sdholland 		$$ = intern(bf);
107082d86132Sdholland 	  }
107182d86132Sdholland ;
107282d86132Sdholland 
107382d86132Sdholland /* constant value that is a string */
107482d86132Sdholland stringvalue:
107582d86132Sdholland 	  QSTRING			{ $$ = $1; }
107682d86132Sdholland 	| WORD				{ $$ = $1; }
107782d86132Sdholland ;
107882d86132Sdholland 
107982d86132Sdholland /* comma-separated list of values */
108082d86132Sdholland /* XXX why right-recursive? */
108182d86132Sdholland values:
108216a8771bSdholland 	  value				{ $$ = MKF2(loc, val, $1, NULL); }
108316a8771bSdholland 	| value ',' values		{ $$ = MKF2(loc, val, $1, $3); }
108482d86132Sdholland ;
108582d86132Sdholland 
108682d86132Sdholland /* possibly negative number */
108782d86132Sdholland signed_number:
108882d86132Sdholland 	  NUMBER			{ $$ = $1; }
108982d86132Sdholland 	| '-' NUMBER			{ $$.fmt = $2.fmt; $$.val = -$2.val; }
109082d86132Sdholland ;
109182d86132Sdholland 
109282d86132Sdholland /* optional ON keyword */
109382d86132Sdholland on_opt:
109482d86132Sdholland 	  /* empty */
109582d86132Sdholland 	| ON
109682d86132Sdholland ;
109782d86132Sdholland 
10985ecc953bSthorpej %%
10995ecc953bSthorpej 
11005ecc953bSthorpej void
11015ecc953bSthorpej yyerror(const char *s)
11025ecc953bSthorpej {
11035ecc953bSthorpej 
1104c7295a4cSchristos 	cfgerror("%s", s);
11055ecc953bSthorpej }
11065ecc953bSthorpej 
11072839b938Sdholland /************************************************************/
11082839b938Sdholland 
11095ecc953bSthorpej /*
11102839b938Sdholland  * Wrap allocations that live on the parser stack so that we can free
11112839b938Sdholland  * them again on error instead of leaking.
11122839b938Sdholland  */
11132839b938Sdholland 
11142839b938Sdholland #define MAX_WRAP 1000
11152839b938Sdholland 
11162839b938Sdholland struct wrap_entry {
11172839b938Sdholland 	void *ptr;
11182839b938Sdholland 	unsigned typecode;
11192839b938Sdholland };
11202839b938Sdholland 
11212839b938Sdholland static struct wrap_entry wrapstack[MAX_WRAP];
11222839b938Sdholland static unsigned wrap_depth;
11232839b938Sdholland 
11242839b938Sdholland /*
11252839b938Sdholland  * Remember pointer PTR with type-code CODE.
11265ecc953bSthorpej  */
11275ecc953bSthorpej static void
wrap_alloc(void * ptr,unsigned code)11282839b938Sdholland wrap_alloc(void *ptr, unsigned code)
11295ecc953bSthorpej {
11302839b938Sdholland 	unsigned pos;
11315ecc953bSthorpej 
11322839b938Sdholland 	if (wrap_depth >= MAX_WRAP) {
11332839b938Sdholland 		panic("allocation wrapper stack overflow");
11345ecc953bSthorpej 	}
11352839b938Sdholland 	pos = wrap_depth++;
11362839b938Sdholland 	wrapstack[pos].ptr = ptr;
11372839b938Sdholland 	wrapstack[pos].typecode = code;
11382839b938Sdholland }
11392839b938Sdholland 
11402839b938Sdholland /*
11412839b938Sdholland  * We succeeded; commit to keeping everything that's been allocated so
11422839b938Sdholland  * far and clear the stack.
11432839b938Sdholland  */
11442839b938Sdholland static void
wrap_continue(void)11452839b938Sdholland wrap_continue(void)
11462839b938Sdholland {
11472839b938Sdholland 	wrap_depth = 0;
11482839b938Sdholland }
11492839b938Sdholland 
11502839b938Sdholland /*
11512839b938Sdholland  * We failed; destroy all the objects allocated.
11522839b938Sdholland  */
11532839b938Sdholland static void
wrap_cleanup(void)11542839b938Sdholland wrap_cleanup(void)
11552839b938Sdholland {
11562839b938Sdholland 	unsigned i;
11572839b938Sdholland 
115816a8771bSdholland 	/*
115916a8771bSdholland 	 * Destroy each item. Note that because everything allocated
116016a8771bSdholland 	 * is entered on the list separately, lists and trees need to
116116a8771bSdholland 	 * have their links blanked before being destroyed. Also note
116216a8771bSdholland 	 * that strings are interned elsewhere and not handled by this
116316a8771bSdholland 	 * mechanism.
116416a8771bSdholland 	 */
116516a8771bSdholland 
11662839b938Sdholland 	for (i=0; i<wrap_depth; i++) {
11672839b938Sdholland 		switch (wrapstack[i].typecode) {
11682839b938Sdholland 		    case WRAP_CODE_nvlist:
11692839b938Sdholland 			nvfree(wrapstack[i].ptr);
11702839b938Sdholland 			break;
1171d74eb995Sdholland 		    case WRAP_CODE_defoptlist:
1172d74eb995Sdholland 			{
1173d74eb995Sdholland 				struct defoptlist *dl = wrapstack[i].ptr;
1174d74eb995Sdholland 
1175d74eb995Sdholland 				dl->dl_next = NULL;
1176d74eb995Sdholland 				defoptlist_destroy(dl);
1177d74eb995Sdholland 			}
1178d74eb995Sdholland 			break;
117916a8771bSdholland 		    case WRAP_CODE_loclist:
118016a8771bSdholland 			{
118116a8771bSdholland 				struct loclist *ll = wrapstack[i].ptr;
118216a8771bSdholland 
118316a8771bSdholland 				ll->ll_next = NULL;
118416a8771bSdholland 				loclist_destroy(ll);
118516a8771bSdholland 			}
118616a8771bSdholland 			break;
11874caf067bSdholland 		    case WRAP_CODE_attrlist:
11884caf067bSdholland 			{
11894caf067bSdholland 				struct attrlist *al = wrapstack[i].ptr;
11904caf067bSdholland 
11914caf067bSdholland 				al->al_next = NULL;
11924caf067bSdholland 				al->al_this = NULL;
11934caf067bSdholland 				attrlist_destroy(al);
11944caf067bSdholland 			}
11954caf067bSdholland 			break;
119616a8771bSdholland 		    case WRAP_CODE_condexpr:
119716a8771bSdholland 			{
119816a8771bSdholland 				struct condexpr *cx = wrapstack[i].ptr;
119916a8771bSdholland 
120016a8771bSdholland 				cx->cx_type = CX_ATOM;
120116a8771bSdholland 				cx->cx_atom = NULL;
120216a8771bSdholland 				condexpr_destroy(cx);
120316a8771bSdholland 			}
120416a8771bSdholland 			break;
12052839b938Sdholland 		    default:
12062839b938Sdholland 			panic("invalid code %u on allocation wrapper stack",
12072839b938Sdholland 			      wrapstack[i].typecode);
12082839b938Sdholland 		}
12092839b938Sdholland 	}
12104caf067bSdholland 
12112839b938Sdholland 	wrap_depth = 0;
12122839b938Sdholland }
12132839b938Sdholland 
12142839b938Sdholland /*
12152839b938Sdholland  * Instantiate the wrapper functions.
12162839b938Sdholland  *
12172839b938Sdholland  * Each one calls wrap_alloc to save the pointer and then returns the
12182839b938Sdholland  * pointer again; these need to be generated with the preprocessor in
12192839b938Sdholland  * order to be typesafe.
12202839b938Sdholland  */
12212839b938Sdholland #define DEF_ALLOCWRAP(t) \
12222839b938Sdholland 	static struct t *				\
12232839b938Sdholland 	wrap_mk_##t(struct t *arg)			\
12242839b938Sdholland 	{						\
12252839b938Sdholland 		wrap_alloc(arg, WRAP_CODE_##t);		\
12262839b938Sdholland 		return arg;				\
12272839b938Sdholland 	}
12282839b938Sdholland 
12292839b938Sdholland DEF_ALLOCWRAP(nvlist);
1230d74eb995Sdholland DEF_ALLOCWRAP(defoptlist);
123116a8771bSdholland DEF_ALLOCWRAP(loclist);
12324caf067bSdholland DEF_ALLOCWRAP(attrlist);
12339483bda7Sdholland DEF_ALLOCWRAP(condexpr);
12344caf067bSdholland 
12354caf067bSdholland /************************************************************/
12364caf067bSdholland 
12374caf067bSdholland /*
12384caf067bSdholland  * Data constructors
123916a8771bSdholland  *
124016a8771bSdholland  * (These are *beneath* the allocation wrappers.)
12414caf067bSdholland  */
12424caf067bSdholland 
1243d74eb995Sdholland static struct defoptlist *
mk_defoptlist(const char * name,const char * val,const char * lintval)1244d74eb995Sdholland mk_defoptlist(const char *name, const char *val, const char *lintval)
1245d74eb995Sdholland {
1246d74eb995Sdholland 	return defoptlist_create(name, val, lintval);
1247d74eb995Sdholland }
1248d74eb995Sdholland 
124916a8771bSdholland static struct loclist *
mk_loc(const char * name,const char * str,long long num)125016a8771bSdholland mk_loc(const char *name, const char *str, long long num)
125116a8771bSdholland {
125216a8771bSdholland 	return loclist_create(name, str, num);
125316a8771bSdholland }
125416a8771bSdholland 
125516a8771bSdholland static struct loclist *
mk_loc_val(const char * str,struct loclist * next)125616a8771bSdholland mk_loc_val(const char *str, struct loclist *next)
125716a8771bSdholland {
125816a8771bSdholland 	struct loclist *ll;
125916a8771bSdholland 
126016a8771bSdholland 	ll = mk_loc(NULL, str, 0);
126116a8771bSdholland 	ll->ll_next = next;
126216a8771bSdholland 	return ll;
126316a8771bSdholland }
126416a8771bSdholland 
12654caf067bSdholland static struct attrlist *
mk_attrlist(struct attrlist * next,struct attr * a)12664caf067bSdholland mk_attrlist(struct attrlist *next, struct attr *a)
12674caf067bSdholland {
12684caf067bSdholland 	return attrlist_cons(next, a);
12694caf067bSdholland }
12702839b938Sdholland 
12719483bda7Sdholland static struct condexpr *
mk_cx_atom(const char * s)12729483bda7Sdholland mk_cx_atom(const char *s)
12739483bda7Sdholland {
12749483bda7Sdholland 	struct condexpr *cx;
12759483bda7Sdholland 
12769483bda7Sdholland 	cx = condexpr_create(CX_ATOM);
12779483bda7Sdholland 	cx->cx_atom = s;
12789483bda7Sdholland 	return cx;
12799483bda7Sdholland }
12809483bda7Sdholland 
12819483bda7Sdholland static struct condexpr *
mk_cx_not(struct condexpr * sub)12829483bda7Sdholland mk_cx_not(struct condexpr *sub)
12839483bda7Sdholland {
12849483bda7Sdholland 	struct condexpr *cx;
12859483bda7Sdholland 
12869483bda7Sdholland 	cx = condexpr_create(CX_NOT);
12879483bda7Sdholland 	cx->cx_not = sub;
12889483bda7Sdholland 	return cx;
12899483bda7Sdholland }
12909483bda7Sdholland 
12919483bda7Sdholland static struct condexpr *
mk_cx_and(struct condexpr * left,struct condexpr * right)12929483bda7Sdholland mk_cx_and(struct condexpr *left, struct condexpr *right)
12939483bda7Sdholland {
12949483bda7Sdholland 	struct condexpr *cx;
12959483bda7Sdholland 
12969483bda7Sdholland 	cx = condexpr_create(CX_AND);
12979483bda7Sdholland 	cx->cx_and.left = left;
12989483bda7Sdholland 	cx->cx_and.right = right;
12999483bda7Sdholland 	return cx;
13009483bda7Sdholland }
13019483bda7Sdholland 
13029483bda7Sdholland static struct condexpr *
mk_cx_or(struct condexpr * left,struct condexpr * right)13039483bda7Sdholland mk_cx_or(struct condexpr *left, struct condexpr *right)
13049483bda7Sdholland {
13059483bda7Sdholland 	struct condexpr *cx;
13069483bda7Sdholland 
13079483bda7Sdholland 	cx = condexpr_create(CX_OR);
13089483bda7Sdholland 	cx->cx_or.left = left;
13099483bda7Sdholland 	cx->cx_or.right = right;
13109483bda7Sdholland 	return cx;
13119483bda7Sdholland }
13129483bda7Sdholland 
13132839b938Sdholland /************************************************************/
13145ecc953bSthorpej 
13155ecc953bSthorpej static void
setmachine(const char * mch,const char * mcharch,struct nvlist * mchsubarches,int isioconf)1316e239742fSpooka setmachine(const char *mch, const char *mcharch, struct nvlist *mchsubarches,
1317e239742fSpooka 	int isioconf)
13185ecc953bSthorpej {
13195ecc953bSthorpej 	char buf[MAXPATHLEN];
13205ecc953bSthorpej 	struct nvlist *nv;
13215ecc953bSthorpej 
1322e239742fSpooka 	if (isioconf) {
1323e239742fSpooka 		if (include(_PATH_DEVNULL, ENDDEFS, 0, 0) != 0)
1324e239742fSpooka 			exit(1);
1325e239742fSpooka 		ioconfname = mch;
1326e239742fSpooka 		return;
1327e239742fSpooka 	}
1328e239742fSpooka 
13295ecc953bSthorpej 	machine = mch;
13305ecc953bSthorpej 	machinearch = mcharch;
13315ecc953bSthorpej 	machinesubarches = mchsubarches;
13325ecc953bSthorpej 
13335ecc953bSthorpej 	/*
133466796c65Scube 	 * Define attributes for all the given names
133566796c65Scube 	 */
133666a59dccScube 	if (defattr(machine, NULL, NULL, 0) != 0 ||
133766a59dccScube 	    (machinearch != NULL &&
133866a59dccScube 	     defattr(machinearch, NULL, NULL, 0) != 0))
133966796c65Scube 		exit(1);
134066796c65Scube 	for (nv = machinesubarches; nv != NULL; nv = nv->nv_next) {
134166796c65Scube 		if (defattr(nv->nv_name, NULL, NULL, 0) != 0)
134266796c65Scube 			exit(1);
134366796c65Scube 	}
134466796c65Scube 
134566796c65Scube 	/*
13465ecc953bSthorpej 	 * Set up the file inclusion stack.  This empty include tells
13475ecc953bSthorpej 	 * the parser there are no more device definitions coming.
13485ecc953bSthorpej 	 */
1349e239742fSpooka 	if (include(_PATH_DEVNULL, ENDDEFS, 0, 0) != 0)
13505ecc953bSthorpej 		exit(1);
13515ecc953bSthorpej 
13525ecc953bSthorpej 	/* Include arch/${MACHINE}/conf/files.${MACHINE} */
13535ecc953bSthorpej 	(void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s",
13545ecc953bSthorpej 	    machine, machine);
13555ecc953bSthorpej 	if (include(buf, ENDFILE, 0, 0) != 0)
13565ecc953bSthorpej 		exit(1);
13575ecc953bSthorpej 
13585ecc953bSthorpej 	/* Include any arch/${MACHINE_SUBARCH}/conf/files.${MACHINE_SUBARCH} */
13595ecc953bSthorpej 	for (nv = machinesubarches; nv != NULL; nv = nv->nv_next) {
13605ecc953bSthorpej 		(void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s",
13615ecc953bSthorpej 		    nv->nv_name, nv->nv_name);
13625ecc953bSthorpej 		if (include(buf, ENDFILE, 0, 0) != 0)
13635ecc953bSthorpej 			exit(1);
13645ecc953bSthorpej 	}
13655ecc953bSthorpej 
13665ecc953bSthorpej 	/* Include any arch/${MACHINE_ARCH}/conf/files.${MACHINE_ARCH} */
13675ecc953bSthorpej 	if (machinearch != NULL)
13685ecc953bSthorpej 		(void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s",
13695ecc953bSthorpej 		    machinearch, machinearch);
13705ecc953bSthorpej 	else
13715ecc953bSthorpej 		strlcpy(buf, _PATH_DEVNULL, sizeof(buf));
13725ecc953bSthorpej 	if (include(buf, ENDFILE, 0, 0) != 0)
13735ecc953bSthorpej 		exit(1);
13745ecc953bSthorpej 
13755ecc953bSthorpej 	/*
13765ecc953bSthorpej 	 * Include the global conf/files.  As the last thing
13775ecc953bSthorpej 	 * pushed on the stack, it will be processed first.
13785ecc953bSthorpej 	 */
13795ecc953bSthorpej 	if (include("conf/files", ENDFILE, 0, 0) != 0)
13805ecc953bSthorpej 		exit(1);
13816fd5c015Smartin 
13826fd5c015Smartin 	oktopackage = 1;
13835ecc953bSthorpej }
13845ecc953bSthorpej 
13855ecc953bSthorpej static void
check_maxpart(void)13865ecc953bSthorpej check_maxpart(void)
13875ecc953bSthorpej {
13885ecc953bSthorpej 
1389e239742fSpooka 	if (maxpartitions <= 0 && ioconfname == NULL) {
13905ecc953bSthorpej 		stop("cannot proceed without maxpartitions specifier");
13915ecc953bSthorpej 	}
13925ecc953bSthorpej }
13935ecc953bSthorpej 
13945ecc953bSthorpej static void
check_version(void)1395437f8925Scube check_version(void)
1396437f8925Scube {
1397437f8925Scube 	/*
1398437f8925Scube 	 * In essence, version is 0 and is not supported anymore
1399437f8925Scube 	 */
1400437f8925Scube 	if (version < CONFIG_MINVERSION)
1401437f8925Scube 		stop("your sources are out of date -- please update.");
1402437f8925Scube }
1403437f8925Scube 
140416a8771bSdholland /*
140516a8771bSdholland  * Prepend a blank entry to the locator definitions so the code in
140616a8771bSdholland  * sem.c can distinguish "empty locator list" from "no locator list".
140716a8771bSdholland  * XXX gross.
140816a8771bSdholland  */
140916a8771bSdholland static struct loclist *
present_loclist(struct loclist * ll)141016a8771bSdholland present_loclist(struct loclist *ll)
14115ecc953bSthorpej {
141216a8771bSdholland 	struct loclist *ret;
141316a8771bSdholland 
141416a8771bSdholland 	ret = MK3(loc, "", NULL, 0);
141516a8771bSdholland 	ret->ll_next = ll;
141616a8771bSdholland 	return ret;
14175ecc953bSthorpej }
14185ecc953bSthorpej 
141916a8771bSdholland static void
app(struct loclist * p,struct loclist * q)142016a8771bSdholland app(struct loclist *p, struct loclist *q)
14215ecc953bSthorpej {
142216a8771bSdholland 	while (p->ll_next)
142316a8771bSdholland 		p = p->ll_next;
142416a8771bSdholland 	p->ll_next = q;
142516a8771bSdholland }
142616a8771bSdholland 
142716a8771bSdholland static struct loclist *
locarray(const char * name,int count,struct loclist * adefs,int opt)142816a8771bSdholland locarray(const char *name, int count, struct loclist *adefs, int opt)
142916a8771bSdholland {
143016a8771bSdholland 	struct loclist *defs = adefs;
143116a8771bSdholland 	struct loclist **p;
14325ecc953bSthorpej 	char buf[200];
14335ecc953bSthorpej 	int i;
14345ecc953bSthorpej 
14355ecc953bSthorpej 	if (count <= 0) {
14365ecc953bSthorpej 		fprintf(stderr, "config: array with <= 0 size: %s\n", name);
14375ecc953bSthorpej 		exit(1);
14385ecc953bSthorpej 	}
14395ecc953bSthorpej 	p = &defs;
14405ecc953bSthorpej 	for(i = 0; i < count; i++) {
14415ecc953bSthorpej 		if (*p == NULL)
144216a8771bSdholland 			*p = MK3(loc, NULL, "0", 0);
14435ecc953bSthorpej 		snprintf(buf, sizeof(buf), "%s%c%d", name, ARRCHR, i);
144416a8771bSdholland 		(*p)->ll_name = i == 0 ? name : intern(buf);
144516a8771bSdholland 		(*p)->ll_num = i > 0 || opt;
144616a8771bSdholland 		p = &(*p)->ll_next;
14475ecc953bSthorpej 	}
14485ecc953bSthorpej 	*p = 0;
14495ecc953bSthorpej 	return defs;
14505ecc953bSthorpej }
14515ecc953bSthorpej 
14525ecc953bSthorpej 
145316a8771bSdholland static struct loclist *
namelocvals(const char * name,struct loclist * vals)145416a8771bSdholland namelocvals(const char *name, struct loclist *vals)
14555ecc953bSthorpej {
145616a8771bSdholland 	struct loclist *p;
14575ecc953bSthorpej 	char buf[200];
14585ecc953bSthorpej 	int i;
14595ecc953bSthorpej 
146016a8771bSdholland 	for (i = 0, p = vals; p; i++, p = p->ll_next) {
14615ecc953bSthorpej 		snprintf(buf, sizeof(buf), "%s%c%d", name, ARRCHR, i);
146216a8771bSdholland 		p->ll_name = i == 0 ? name : intern(buf);
14635ecc953bSthorpej 	}
14645ecc953bSthorpej 	return vals;
14655ecc953bSthorpej }
14665ecc953bSthorpej 
1467