xref: /netbsd/usr.bin/config/gram.y (revision 9a7f4bba)
15ecc953bSthorpej %{
2*9a7f4bbaSchristos /*	$NetBSD: gram.y,v 1.44 2014/10/29 17:14:50 christos 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 
44*9a7f4bbaSchristos #include <sys/cdefs.h>
45*9a7f4bbaSchristos __RCSID("$NetBSD: gram.y,v 1.44 2014/10/29 17:14:50 christos Exp $");
46*9a7f4bbaSchristos 
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 */
635ecc953bSthorpej 
642839b938Sdholland 
652839b938Sdholland /*
662839b938Sdholland  * Allocation wrapper functions
672839b938Sdholland  */
682839b938Sdholland static void wrap_alloc(void *ptr, unsigned code);
692839b938Sdholland static void wrap_continue(void);
702839b938Sdholland static void wrap_cleanup(void);
712839b938Sdholland 
722839b938Sdholland /*
732839b938Sdholland  * Allocation wrapper type codes
742839b938Sdholland  */
752839b938Sdholland #define WRAP_CODE_nvlist	1
76d74eb995Sdholland #define WRAP_CODE_defoptlist	2
77d74eb995Sdholland #define WRAP_CODE_loclist	3
78d74eb995Sdholland #define WRAP_CODE_attrlist	4
79d74eb995Sdholland #define WRAP_CODE_condexpr	5
802839b938Sdholland 
812839b938Sdholland /*
822839b938Sdholland  * The allocation wrappers themselves
832839b938Sdholland  */
842839b938Sdholland #define DECL_ALLOCWRAP(t)	static struct t *wrap_mk_##t(struct t *arg)
852839b938Sdholland 
862839b938Sdholland DECL_ALLOCWRAP(nvlist);
87d74eb995Sdholland DECL_ALLOCWRAP(defoptlist);
8816a8771bSdholland DECL_ALLOCWRAP(loclist);
894caf067bSdholland DECL_ALLOCWRAP(attrlist);
909483bda7Sdholland DECL_ALLOCWRAP(condexpr);
919483bda7Sdholland 
929483bda7Sdholland /* allow shorter names */
9316a8771bSdholland #define wrap_mk_loc(p) wrap_mk_loclist(p)
949483bda7Sdholland #define wrap_mk_cx(p) wrap_mk_condexpr(p)
952839b938Sdholland 
962839b938Sdholland /*
972839b938Sdholland  * Macros for allocating new objects
982839b938Sdholland  */
992839b938Sdholland 
1004caf067bSdholland /* old-style for struct nvlist */
1012839b938Sdholland #define	new0(n,s,p,i,x)	wrap_mk_nvlist(newnv(n, s, p, i, x))
1025ecc953bSthorpej #define	new_n(n)	new0(n, NULL, NULL, 0, NULL)
1035ecc953bSthorpej #define	new_nx(n, x)	new0(n, NULL, NULL, 0, x)
1045ecc953bSthorpej #define	new_ns(n, s)	new0(n, s, NULL, 0, NULL)
1055ecc953bSthorpej #define	new_si(s, i)	new0(NULL, s, NULL, i, NULL)
1065ecc953bSthorpej #define	new_nsi(n,s,i)	new0(n, s, NULL, i, NULL)
1075ecc953bSthorpej #define	new_np(n, p)	new0(n, NULL, p, 0, NULL)
1085ecc953bSthorpej #define	new_s(s)	new0(NULL, s, NULL, 0, NULL)
1095ecc953bSthorpej #define	new_p(p)	new0(NULL, NULL, p, 0, NULL)
1105ecc953bSthorpej #define	new_px(p, x)	new0(NULL, NULL, p, 0, x)
1115ecc953bSthorpej #define	new_sx(s, x)	new0(NULL, s, NULL, 0, x)
11290426267Scube #define	new_nsx(n,s,x)	new0(n, s, NULL, 0, x)
1133da3ab25Spooka #define	new_i(i)	new0(NULL, NULL, NULL, i, NULL)
1145ecc953bSthorpej 
1159483bda7Sdholland /* new style, type-polymorphic; ordinary and for types with multiple flavors */
1164caf067bSdholland #define MK0(t)		wrap_mk_##t(mk_##t())
1174caf067bSdholland #define MK1(t, a0)	wrap_mk_##t(mk_##t(a0))
1184caf067bSdholland #define MK2(t, a0, a1)	wrap_mk_##t(mk_##t(a0, a1))
11916a8771bSdholland #define MK3(t, a0, a1, a2)	wrap_mk_##t(mk_##t(a0, a1, a2))
1204caf067bSdholland 
1219483bda7Sdholland #define MKF0(t, f)		wrap_mk_##t(mk_##t##_##f())
1229483bda7Sdholland #define MKF1(t, f, a0)		wrap_mk_##t(mk_##t##_##f(a0))
1239483bda7Sdholland #define MKF2(t, f, a0, a1)	wrap_mk_##t(mk_##t##_##f(a0, a1))
1249483bda7Sdholland 
1254caf067bSdholland /*
1264caf067bSdholland  * Data constructors
1274caf067bSdholland  */
1284caf067bSdholland 
129d74eb995Sdholland static struct defoptlist *mk_defoptlist(const char *, const char *,
130d74eb995Sdholland 					const char *);
13116a8771bSdholland static struct loclist *mk_loc(const char *, const char *, long long);
13216a8771bSdholland static struct loclist *mk_loc_val(const char *, struct loclist *);
1334caf067bSdholland static struct attrlist *mk_attrlist(struct attrlist *, struct attr *);
1349483bda7Sdholland static struct condexpr *mk_cx_atom(const char *);
1359483bda7Sdholland static struct condexpr *mk_cx_not(struct condexpr *);
1369483bda7Sdholland static struct condexpr *mk_cx_and(struct condexpr *, struct condexpr *);
1379483bda7Sdholland static struct condexpr *mk_cx_or(struct condexpr *, struct condexpr *);
1384caf067bSdholland 
1392839b938Sdholland /*
1402839b938Sdholland  * Other private functions
1412839b938Sdholland  */
1422839b938Sdholland 
143e239742fSpooka static	void	setmachine(const char *, const char *, struct nvlist *, int);
1445ecc953bSthorpej static	void	check_maxpart(void);
1455ecc953bSthorpej 
14616a8771bSdholland static struct loclist *present_loclist(struct loclist *ll);
14716a8771bSdholland static void app(struct loclist *, struct loclist *);
14816a8771bSdholland static struct loclist *locarray(const char *, int, struct loclist *, int);
14916a8771bSdholland static struct loclist *namelocvals(const char *, struct loclist *);
1505ecc953bSthorpej 
1515ecc953bSthorpej %}
1525ecc953bSthorpej 
1535ecc953bSthorpej %union {
1545ecc953bSthorpej 	struct	attr *attr;
1555ecc953bSthorpej 	struct	devbase *devb;
1565ecc953bSthorpej 	struct	deva *deva;
1575ecc953bSthorpej 	struct	nvlist *list;
158d74eb995Sdholland 	struct defoptlist *defoptlist;
15916a8771bSdholland 	struct loclist *loclist;
1604caf067bSdholland 	struct attrlist *attrlist;
1619483bda7Sdholland 	struct condexpr *condexpr;
1625ecc953bSthorpej 	const char *str;
1635ecc953bSthorpej 	struct	numconst num;
1645ecc953bSthorpej 	int64_t	val;
165*9a7f4bbaSchristos 	u_char	flag;
166*9a7f4bbaSchristos 	devmajor_t devmajor;
167*9a7f4bbaSchristos 	int32_t i32;
1685ecc953bSthorpej }
1695ecc953bSthorpej 
1705ecc953bSthorpej %token	AND AT ATTACH
1715ecc953bSthorpej %token	BLOCK BUILD
17290426267Scube %token	CHAR COLONEQ COMPILE_WITH CONFIG
1738456b350Sdrochner %token	DEFFS DEFINE DEFOPT DEFPARAM DEFFLAG DEFPSEUDO DEFPSEUDODEV
1748456b350Sdrochner %token	DEVICE DEVCLASS DUMPS DEVICE_MAJOR
1755ecc953bSthorpej %token	ENDFILE
1765ecc953bSthorpej %token	XFILE FILE_SYSTEM FLAGS
177e239742fSpooka %token	IDENT IOCONF
1783da3ab25Spooka %token	LINKZERO
1795ecc953bSthorpej %token	XMACHINE MAJOR MAKEOPTIONS MAXUSERS MAXPARTITIONS MINOR
1805ecc953bSthorpej %token	NEEDS_COUNT NEEDS_FLAG NO
181ac24e161Scube %token	XOBJECT OBSOLETE ON OPTIONS
18290ac64deSpooka %token	PACKAGE PLUSEQ PREFIX PSEUDO_DEVICE PSEUDO_ROOT
1835ecc953bSthorpej %token	ROOT
1843da3ab25Spooka %token	SINGLE SOURCE
1855ecc953bSthorpej %token	TYPE
1863da3ab25Spooka %token	VECTOR VERSION
1875ecc953bSthorpej %token	WITH
1885ecc953bSthorpej %token	<num> NUMBER
189d0fb8901Schristos %token	<str> PATHNAME QSTRING WORD EMPTYSTRING
1905ecc953bSthorpej %token	ENDDEFS
1915ecc953bSthorpej 
1929483bda7Sdholland %type	<condexpr>	fopts condexpr condatom
1939483bda7Sdholland %type	<condexpr>	cond_or_expr cond_and_expr cond_prefix_expr
1949483bda7Sdholland %type	<condexpr>	 cond_base_expr
1955ecc953bSthorpej %type	<str>	fs_spec
196*9a7f4bbaSchristos %type	<flag>	fflags fflag oflags oflag
1975ecc953bSthorpej %type	<str>	rule
1984e34eebcSdholland %type	<attr>	depend
1995ecc953bSthorpej %type	<devb>	devbase
2005ecc953bSthorpej %type	<deva>	devattach_opt
20116a8771bSdholland %type	<list>	atlist
20216a8771bSdholland %type	<loclist> interface_opt
2035ecc953bSthorpej %type	<str>	atname
20416a8771bSdholland %type	<loclist>	loclist locdef
2055ecc953bSthorpej %type	<str>	locdefault
20616a8771bSdholland %type	<loclist>	values locdefaults
2074e34eebcSdholland %type	<attrlist>	depend_list depends
20816a8771bSdholland %type	<loclist>	locators locator
2095ecc953bSthorpej %type	<list>	dev_spec
2105ecc953bSthorpej %type	<str>	device_instance
2115ecc953bSthorpej %type	<str>	attachment
2125ecc953bSthorpej %type	<str>	value
213*9a7f4bbaSchristos %type	<val>	major_minor
2145ecc953bSthorpej %type	<num>	signed_number
215*9a7f4bbaSchristos %type	<i32>	int32 npseudo device_flags
2165ecc953bSthorpej %type	<str>	deffs
2175ecc953bSthorpej %type	<list>	deffses
218d74eb995Sdholland %type	<defoptlist>	defopt
219d74eb995Sdholland %type	<defoptlist>	defopts
220ebd45116Sdholland %type	<str>	optdepend
221ebd45116Sdholland %type	<list>	optdepends
222ebd45116Sdholland %type	<list>	optdepend_list
2235ecc953bSthorpej %type	<str>	optfile_opt
2244c38d3adSdholland %type	<list>	subarches
2255ecc953bSthorpej %type	<str>	filename stringvalue locname mkvarname
226*9a7f4bbaSchristos %type	<devmajor>	device_major_block device_major_char
2273da3ab25Spooka %type	<list>	devnodes devnodetype devnodeflags devnode_dims
2285ecc953bSthorpej 
2295ecc953bSthorpej %%
2305ecc953bSthorpej 
2315ecc953bSthorpej /*
23287ef93d9Suebayasi  * A complete configuration consists of both the selection part (a
233682f0402Sdholland  * kernel config such as GENERIC or SKYNET, plus also the various
234682f0402Sdholland  * std.* files), which selects the material to be in the kernel, and
235682f0402Sdholland  * also the definition part (files, files.*, etc.) that declares what
236682f0402Sdholland  * material is available to be placed in kernels.
237682f0402Sdholland  *
238682f0402Sdholland  * The two parts have almost entirely separate syntaxes. This grammar
239682f0402Sdholland  * covers both of them. When config is run on a kernel configuration
240682f0402Sdholland  * file, the std.* file for the port is included explicitly. The
241682f0402Sdholland  * files.* files are included implicitly when the std.* file declares
242682f0402Sdholland  * the machine type.
243682f0402Sdholland  *
244682f0402Sdholland  * The machine spec, which brings in the definition part, must appear
245682f0402Sdholland  * before all configuration material except for the "topthings"; these
246682f0402Sdholland  * are the "source" and "build" declarations that tell config where
247682f0402Sdholland  * things are. These are not used by default.
248682f0402Sdholland  *
249682f0402Sdholland  * A previous version of this comment contained the following text:
250682f0402Sdholland  *
251682f0402Sdholland  *       Note that we do not have sufficient keywords to enforce any
252682f0402Sdholland  *       order between elements of "topthings" without introducing
253682f0402Sdholland  *       shift/reduce conflicts.  Instead, check order requirements in
254682f0402Sdholland  *       the C code.
255682f0402Sdholland  *
256682f0402Sdholland  * As of March 2012 this comment makes no sense, as there are only two
257682f0402Sdholland  * topthings and no reason for them to be forcibly ordered.
258682f0402Sdholland  * Furthermore, the statement about conflicts is false.
2595ecc953bSthorpej  */
2605ecc953bSthorpej 
261682f0402Sdholland /* Complete configuration. */
2624c38d3adSdholland configuration:
26387ef93d9Suebayasi 	topthings machine_spec definition_part selection_part
264c1e3ceeaSdholland ;
265682f0402Sdholland 
266682f0402Sdholland /* Sequence of zero or more topthings. */
2675ecc953bSthorpej topthings:
268c1e3ceeaSdholland 	  /* empty */
269c1e3ceeaSdholland 	| topthings topthing
270c1e3ceeaSdholland ;
2715ecc953bSthorpej 
272682f0402Sdholland /* Directory specification. */
2735ecc953bSthorpej topthing:
274244ef363Sdholland 	                  '\n'
275244ef363Sdholland 	| SOURCE filename '\n'		{ if (!srcdir) srcdir = $2; }
276c1e3ceeaSdholland 	| BUILD  filename '\n'		{ if (!builddir) builddir = $2; }
277c1e3ceeaSdholland ;
2785ecc953bSthorpej 
279682f0402Sdholland /* "machine foo" from std.whatever */
2805ecc953bSthorpej machine_spec:
281c1e3ceeaSdholland 	  XMACHINE WORD '\n'			{ setmachine($2,NULL,NULL,0); }
2824c38d3adSdholland 	| XMACHINE WORD WORD '\n'		{ setmachine($2,$3,NULL,0); }
2834c38d3adSdholland 	| XMACHINE WORD WORD subarches '\n'	{ setmachine($2,$3,$4,0); }
284c1e3ceeaSdholland 	| IOCONF WORD '\n'			{ setmachine($2,NULL,NULL,1); }
285c1e3ceeaSdholland 	| error { stop("cannot proceed without machine or ioconf specifier"); }
286c1e3ceeaSdholland ;
2875ecc953bSthorpej 
2884c38d3adSdholland /* One or more sub-arches. */
2895ecc953bSthorpej subarches:
290244ef363Sdholland 	  WORD				{ $$ = new_n($1); }
291244ef363Sdholland 	| subarches WORD		{ $$ = new_nx($2, $1); }
292c1e3ceeaSdholland ;
2935ecc953bSthorpej 
294682f0402Sdholland /************************************************************/
295682f0402Sdholland 
2965ecc953bSthorpej /*
2975ecc953bSthorpej  * The machine definitions grammar.
2985ecc953bSthorpej  */
299682f0402Sdholland 
300682f0402Sdholland /* Complete definition part: the contents of all files.* files. */
3014c38d3adSdholland definition_part:
3024c38d3adSdholland 	definitions ENDDEFS		{ check_maxpart(); check_version(); }
303c1e3ceeaSdholland ;
3045ecc953bSthorpej 
3054c38d3adSdholland /* Zero or more definitions. Trap errors. */
3064c38d3adSdholland definitions:
3074c38d3adSdholland 	  /* empty */
3084c38d3adSdholland 	| definitions '\n'
3092839b938Sdholland 	| definitions definition '\n'	{ wrap_continue(); }
3102839b938Sdholland 	| definitions error '\n'	{ wrap_cleanup(); }
3114c38d3adSdholland 	| definitions ENDFILE		{ enddefs(); checkfiles(); }
312c1e3ceeaSdholland ;
3135ecc953bSthorpej 
314682f0402Sdholland /* A single definition. */
3154c38d3adSdholland definition:
31638146c24Suebayasi 	  define_file
31738146c24Suebayasi 	| define_object
31838146c24Suebayasi 	| define_device_major
31938146c24Suebayasi 	| define_prefix
32038146c24Suebayasi 	| define_devclass
32138146c24Suebayasi 	| define_filesystems
32238146c24Suebayasi 	| define_attribute
32338146c24Suebayasi 	| define_option
32438146c24Suebayasi 	| define_flag
32538146c24Suebayasi 	| define_obsolete_flag
32638146c24Suebayasi 	| define_param
32738146c24Suebayasi 	| define_obsolete_param
32838146c24Suebayasi 	| define_device
32938146c24Suebayasi 	| define_device_attachment
33038146c24Suebayasi 	| define_maxpartitions
33138146c24Suebayasi 	| define_maxusers
33238146c24Suebayasi 	| define_makeoptions
33338146c24Suebayasi 	| define_pseudo
33438146c24Suebayasi 	| define_pseudodev
33538146c24Suebayasi 	| define_major
33638146c24Suebayasi 	| define_version
337c1e3ceeaSdholland ;
3385ecc953bSthorpej 
33982d86132Sdholland /* source file: file foo/bar.c bar|baz needs-flag compile-with blah */
34038146c24Suebayasi define_file:
341ebd45116Sdholland 	XFILE filename fopts fflags rule	{ addfile($2, $3, $4, $5); }
342c1e3ceeaSdholland ;
3435ecc953bSthorpej 
34438146c24Suebayasi /* object file: object zot.o foo|zot needs-flag */
34538146c24Suebayasi define_object:
34638146c24Suebayasi 	XOBJECT filename fopts oflags	{ addobject($2, $3, $4); }
34738146c24Suebayasi ;
34838146c24Suebayasi 
34938146c24Suebayasi /* device major declaration */
35038146c24Suebayasi define_device_major:
35138146c24Suebayasi 	DEVICE_MAJOR WORD device_major_char device_major_block fopts devnodes
35238146c24Suebayasi 					{
35338146c24Suebayasi 		adddevm($2, $3, $4, $5, $6);
35438146c24Suebayasi 		do_devsw = 1;
35538146c24Suebayasi 	}
35638146c24Suebayasi ;
35738146c24Suebayasi 
35838146c24Suebayasi /* prefix delimiter */
35938146c24Suebayasi define_prefix:
36038146c24Suebayasi 	  PREFIX filename		{ prefix_push($2); }
36138146c24Suebayasi 	| PREFIX			{ prefix_pop(); }
36238146c24Suebayasi ;
36338146c24Suebayasi 
36438146c24Suebayasi define_devclass:
365bb4307a6Suebayasi 	DEVCLASS WORD			{ (void)defdevclass($2, NULL, NULL, 1); }
36638146c24Suebayasi ;
36738146c24Suebayasi 
36838146c24Suebayasi define_filesystems:
36938146c24Suebayasi 	DEFFS deffses optdepend_list	{ deffilesystem($2, $3); }
37038146c24Suebayasi ;
37138146c24Suebayasi 
37238146c24Suebayasi define_attribute:
37338146c24Suebayasi 	DEFINE WORD interface_opt depend_list
374bb4307a6Suebayasi 					{ (void)defattr0($2, $3, $4, 0); }
37538146c24Suebayasi ;
37638146c24Suebayasi 
37738146c24Suebayasi define_option:
37838146c24Suebayasi 	DEFOPT optfile_opt defopts optdepend_list
37938146c24Suebayasi 					{ defoption($2, $3, $4); }
38038146c24Suebayasi ;
38138146c24Suebayasi 
38238146c24Suebayasi define_flag:
38338146c24Suebayasi 	DEFFLAG optfile_opt defopts optdepend_list
38438146c24Suebayasi 					{ defflag($2, $3, $4, 0); }
38538146c24Suebayasi ;
38638146c24Suebayasi 
38738146c24Suebayasi define_obsolete_flag:
38838146c24Suebayasi 	OBSOLETE DEFFLAG optfile_opt defopts
38938146c24Suebayasi 					{ defflag($3, $4, NULL, 1); }
39038146c24Suebayasi ;
39138146c24Suebayasi 
39238146c24Suebayasi define_param:
39338146c24Suebayasi 	DEFPARAM optfile_opt defopts optdepend_list
39438146c24Suebayasi 					{ defparam($2, $3, $4, 0); }
39538146c24Suebayasi ;
39638146c24Suebayasi 
39738146c24Suebayasi define_obsolete_param:
39838146c24Suebayasi 	OBSOLETE DEFPARAM optfile_opt defopts
39938146c24Suebayasi 					{ defparam($3, $4, NULL, 1); }
40038146c24Suebayasi ;
40138146c24Suebayasi 
40238146c24Suebayasi define_device:
40338146c24Suebayasi 	DEVICE devbase interface_opt depend_list
40438146c24Suebayasi 					{ defdev($2, $3, $4, 0); }
40538146c24Suebayasi ;
40638146c24Suebayasi 
40738146c24Suebayasi define_device_attachment:
40838146c24Suebayasi 	ATTACH devbase AT atlist devattach_opt depend_list
40938146c24Suebayasi 					{ defdevattach($5, $2, $4, $6); }
41038146c24Suebayasi ;
41138146c24Suebayasi 
41238146c24Suebayasi define_maxpartitions:
413*9a7f4bbaSchristos 	MAXPARTITIONS int32		{ maxpartitions = $2; }
41438146c24Suebayasi ;
41538146c24Suebayasi 
41638146c24Suebayasi define_maxusers:
417*9a7f4bbaSchristos 	MAXUSERS int32 int32 int32
418*9a7f4bbaSchristos 					{ setdefmaxusers($2, $3, $4); }
41938146c24Suebayasi ;
42038146c24Suebayasi 
42138146c24Suebayasi define_makeoptions:
42238146c24Suebayasi 	MAKEOPTIONS condmkopt_list
42338146c24Suebayasi ;
42438146c24Suebayasi 
42538146c24Suebayasi define_pseudo:
42638146c24Suebayasi 	/* interface_opt in DEFPSEUDO is for backwards compatibility */
42738146c24Suebayasi 	DEFPSEUDO devbase interface_opt depend_list
42838146c24Suebayasi 					{ defdev($2, $3, $4, 1); }
42938146c24Suebayasi ;
43038146c24Suebayasi 
43138146c24Suebayasi define_pseudodev:
43238146c24Suebayasi 	DEFPSEUDODEV devbase interface_opt depend_list
43338146c24Suebayasi 					{ defdev($2, $3, $4, 2); }
43438146c24Suebayasi ;
43538146c24Suebayasi 
43638146c24Suebayasi define_major:
43738146c24Suebayasi 	MAJOR '{' majorlist '}'
43838146c24Suebayasi ;
43938146c24Suebayasi 
44038146c24Suebayasi define_version:
441*9a7f4bbaSchristos 	VERSION int32		{ setversion($2); }
44238146c24Suebayasi ;
44338146c24Suebayasi 
4444e34eebcSdholland /* file options: optional expression of conditions */
44582d86132Sdholland fopts:
44682d86132Sdholland 	  /* empty */			{ $$ = NULL; }
4474e34eebcSdholland 	| condexpr			{ $$ = $1; }
44882d86132Sdholland ;
44982d86132Sdholland 
45082d86132Sdholland /* zero or more flags for a file */
451ebd45116Sdholland fflags:
45282d86132Sdholland 	  /* empty */			{ $$ = 0; }
453ebd45116Sdholland 	| fflags fflag			{ $$ = $1 | $2; }
45482d86132Sdholland ;
45582d86132Sdholland 
45682d86132Sdholland /* one flag for a file */
45782d86132Sdholland fflag:
45882d86132Sdholland 	  NEEDS_COUNT			{ $$ = FI_NEEDSCOUNT; }
45982d86132Sdholland 	| NEEDS_FLAG			{ $$ = FI_NEEDSFLAG; }
46082d86132Sdholland ;
46182d86132Sdholland 
46282d86132Sdholland /* extra compile directive for a source file */
46382d86132Sdholland rule:
46482d86132Sdholland 	  /* empty */			{ $$ = NULL; }
46582d86132Sdholland 	| COMPILE_WITH stringvalue	{ $$ = $2; }
46682d86132Sdholland ;
46782d86132Sdholland 
46882d86132Sdholland /* zero or more flags for an object file */
469ebd45116Sdholland oflags:
47082d86132Sdholland 	  /* empty */			{ $$ = 0; }
471ebd45116Sdholland 	| oflags oflag			{ $$ = $1 | $2; }
47282d86132Sdholland ;
47382d86132Sdholland 
47482d86132Sdholland /* a single flag for an object file */
47582d86132Sdholland oflag:
47682d86132Sdholland 	NEEDS_FLAG			{ $$ = OI_NEEDSFLAG; }
47782d86132Sdholland ;
47882d86132Sdholland 
47982d86132Sdholland /* char 55 */
48082d86132Sdholland device_major_char:
48182d86132Sdholland 	  /* empty */			{ $$ = -1; }
482*9a7f4bbaSchristos 	| CHAR int32			{ $$ = $2; }
48382d86132Sdholland ;
48482d86132Sdholland 
48582d86132Sdholland /* block 33 */
48682d86132Sdholland device_major_block:
48782d86132Sdholland 	  /* empty */			{ $$ = -1; }
488*9a7f4bbaSchristos 	| BLOCK int32			{ $$ = $2; }
48982d86132Sdholland ;
49082d86132Sdholland 
49182d86132Sdholland /* device node specification */
49282d86132Sdholland devnodes:
49382d86132Sdholland 	  /* empty */			{ $$ = new_s("DEVNODE_DONTBOTHER"); }
49482d86132Sdholland 	| devnodetype ',' devnodeflags	{ $$ = nvcat($1, $3); }
49582d86132Sdholland 	| devnodetype			{ $$ = $1; }
49682d86132Sdholland ;
49782d86132Sdholland 
49882d86132Sdholland /* device nodes without flags */
49982d86132Sdholland devnodetype:
50082d86132Sdholland 	  SINGLE			{ $$ = new_s("DEVNODE_SINGLE"); }
50182d86132Sdholland 	| VECTOR '=' devnode_dims  { $$ = nvcat(new_s("DEVNODE_VECTOR"), $3); }
50282d86132Sdholland ;
50382d86132Sdholland 
50482d86132Sdholland /* dimensions (?) */
50582d86132Sdholland devnode_dims:
50682d86132Sdholland 	  NUMBER			{ $$ = new_i($1.val); }
50782d86132Sdholland 	| NUMBER ':' NUMBER		{
50882d86132Sdholland 		struct nvlist *__nv1, *__nv2;
50982d86132Sdholland 
51082d86132Sdholland 		__nv1 = new_i($1.val);
51182d86132Sdholland 		__nv2 = new_i($3.val);
51282d86132Sdholland 		$$ = nvcat(__nv1, __nv2);
51382d86132Sdholland 	  }
51482d86132Sdholland ;
51582d86132Sdholland 
51682d86132Sdholland /* flags for device nodes */
51782d86132Sdholland devnodeflags:
51882d86132Sdholland 	LINKZERO			{ $$ = new_s("DEVNODE_FLAG_LINKZERO");}
51982d86132Sdholland ;
52082d86132Sdholland 
521682f0402Sdholland /* one or more file system names */
5225ecc953bSthorpej deffses:
523c1e3ceeaSdholland 	  deffs				{ $$ = new_n($1); }
524c1e3ceeaSdholland 	| deffses deffs			{ $$ = new_nx($2, $1); }
525c1e3ceeaSdholland ;
5265ecc953bSthorpej 
527682f0402Sdholland /* a single file system name */
5285ecc953bSthorpej deffs:
529c1e3ceeaSdholland 	WORD				{ $$ = $1; }
530c1e3ceeaSdholland ;
5315ecc953bSthorpej 
5324c38d3adSdholland /* optional locator specification */
5335ecc953bSthorpej interface_opt:
534c1e3ceeaSdholland 	  /* empty */			{ $$ = NULL; }
53516a8771bSdholland 	| '{' '}'			{ $$ = present_loclist(NULL); }
53616a8771bSdholland 	| '{' loclist '}'		{ $$ = present_loclist($2); }
537c1e3ceeaSdholland ;
5385ecc953bSthorpej 
539682f0402Sdholland /*
540682f0402Sdholland  * loclist order matters, must use right recursion
541682f0402Sdholland  * XXX wot?
542682f0402Sdholland  */
543682f0402Sdholland 
544682f0402Sdholland /* list of locator definitions */
5455ecc953bSthorpej loclist:
546c1e3ceeaSdholland 	  locdef			{ $$ = $1; }
547c1e3ceeaSdholland 	| locdef ',' loclist		{ $$ = $1; app($1, $3); }
548c1e3ceeaSdholland ;
5495ecc953bSthorpej 
550682f0402Sdholland /*
551682f0402Sdholland  * "[ WORD locdefault ]" syntax may be unnecessary...
552682f0402Sdholland  */
553682f0402Sdholland 
554682f0402Sdholland /* one locator definition */
5555ecc953bSthorpej locdef:
55616a8771bSdholland 	  locname locdefault 		{ $$ = MK3(loc, $1, $2, 0); }
55716a8771bSdholland 	| locname			{ $$ = MK3(loc, $1, NULL, 0); }
55816a8771bSdholland 	| '[' locname locdefault ']'	{ $$ = MK3(loc, $2, $3, 1); }
559*9a7f4bbaSchristos 	| locname '[' int32 ']'	{ $$ = locarray($1, $3, NULL, 0); }
560*9a7f4bbaSchristos 	| locname '[' int32 ']' locdefaults
561*9a7f4bbaSchristos 					{ $$ = locarray($1, $3, $5, 0); }
562*9a7f4bbaSchristos 	| '[' locname '[' int32 ']' locdefaults ']'
563*9a7f4bbaSchristos 					{ $$ = locarray($2, $4, $6, 1); }
564c1e3ceeaSdholland ;
5655ecc953bSthorpej 
566682f0402Sdholland /* locator name */
5675ecc953bSthorpej locname:
568c1e3ceeaSdholland 	  WORD				{ $$ = $1; }
569c1e3ceeaSdholland 	| QSTRING			{ $$ = $1; }
570c1e3ceeaSdholland ;
5715ecc953bSthorpej 
572682f0402Sdholland /* locator default value */
5735ecc953bSthorpej locdefault:
574c1e3ceeaSdholland 	'=' value			{ $$ = $2; }
575c1e3ceeaSdholland ;
5765ecc953bSthorpej 
577682f0402Sdholland /* multiple locator default values */
5785ecc953bSthorpej locdefaults:
579c1e3ceeaSdholland 	'=' '{' values '}'		{ $$ = $3; }
580c1e3ceeaSdholland ;
5815ecc953bSthorpej 
5824e34eebcSdholland /* list of depends, may be empty */
5834e34eebcSdholland depend_list:
584c1e3ceeaSdholland 	  /* empty */			{ $$ = NULL; }
5854e34eebcSdholland 	| ':' depends			{ $$ = $2; }
586c1e3ceeaSdholland ;
5875ecc953bSthorpej 
5884e34eebcSdholland /* one or more depend items */
5894e34eebcSdholland depends:
5904e34eebcSdholland 	  depend			{ $$ = MK2(attrlist, NULL, $1); }
5914e34eebcSdholland 	| depends ',' depend		{ $$ = MK2(attrlist, $1, $3); }
592c1e3ceeaSdholland ;
5935ecc953bSthorpej 
5944e34eebcSdholland /* one depend item (which is an attribute) */
5954e34eebcSdholland depend:
59651deed3eSuebayasi 	WORD				{ $$ = refattr($1); }
597c1e3ceeaSdholland ;
5985ecc953bSthorpej 
599ebd45116Sdholland /* list of option depends, may be empty */
600ebd45116Sdholland optdepend_list:
601ebd45116Sdholland 	  /* empty */			{ $$ = NULL; }
602ebd45116Sdholland 	| ':' optdepends		{ $$ = $2; }
603ebd45116Sdholland ;
604ebd45116Sdholland 
605ebd45116Sdholland /* a list of option dependencies */
606ebd45116Sdholland optdepends:
607ebd45116Sdholland 	  optdepend			{ $$ = new_n($1); }
608ebd45116Sdholland 	| optdepends ',' optdepend	{ $$ = new_nx($3, $1); }
609ebd45116Sdholland ;
610ebd45116Sdholland 
611ebd45116Sdholland /* one option depend, which is an option name */
612ebd45116Sdholland optdepend:
613ebd45116Sdholland 	WORD				{ $$ = $1; }
614ebd45116Sdholland ;
615ebd45116Sdholland 
616ebd45116Sdholland 
61782d86132Sdholland /* list of places to attach: attach blah at ... */
61882d86132Sdholland atlist:
61982d86132Sdholland 	  atname			{ $$ = new_n($1); }
62082d86132Sdholland 	| atlist ',' atname		{ $$ = new_nx($3, $1); }
62182d86132Sdholland ;
62282d86132Sdholland 
62382d86132Sdholland /* a place to attach a device */
62482d86132Sdholland atname:
62582d86132Sdholland 	  WORD				{ $$ = $1; }
62682d86132Sdholland 	| ROOT				{ $$ = NULL; }
62782d86132Sdholland ;
62882d86132Sdholland 
62982d86132Sdholland /* one or more defined options */
63082d86132Sdholland defopts:
63182d86132Sdholland 	  defopt			{ $$ = $1; }
632d74eb995Sdholland 	| defopts defopt		{ $$ = defoptlist_append($2, $1); }
63382d86132Sdholland ;
63482d86132Sdholland 
63582d86132Sdholland /* one defined option */
63682d86132Sdholland defopt:
637d74eb995Sdholland 	  WORD				{ $$ = MK3(defoptlist, $1, NULL, NULL); }
638d74eb995Sdholland 	| WORD '=' value		{ $$ = MK3(defoptlist, $1, $3, NULL); }
639d74eb995Sdholland 	| WORD COLONEQ value		{ $$ = MK3(defoptlist, $1, NULL, $3); }
640d74eb995Sdholland 	| WORD '=' value COLONEQ value	{ $$ = MK3(defoptlist, $1, $3, $5); }
64182d86132Sdholland ;
64282d86132Sdholland 
64382d86132Sdholland /* list of conditional makeoptions */
64482d86132Sdholland condmkopt_list:
64582d86132Sdholland 	  condmkoption
64682d86132Sdholland 	| condmkopt_list ',' condmkoption
64782d86132Sdholland ;
64882d86132Sdholland 
64982d86132Sdholland /* one conditional make option */
65082d86132Sdholland condmkoption:
6514e34eebcSdholland 	condexpr mkvarname PLUSEQ value	{ appendcondmkoption($1, $2, $4); }
65282d86132Sdholland ;
65382d86132Sdholland 
65482d86132Sdholland /* device name */
65582d86132Sdholland devbase:
65682d86132Sdholland 	WORD				{ $$ = getdevbase($1); }
65782d86132Sdholland ;
65882d86132Sdholland 
65982d86132Sdholland /* optional attachment: with foo */
66082d86132Sdholland devattach_opt:
66182d86132Sdholland 	  /* empty */			{ $$ = NULL; }
66282d86132Sdholland 	| WITH WORD			{ $$ = getdevattach($2); }
66382d86132Sdholland ;
66482d86132Sdholland 
665682f0402Sdholland /* list of major numbers */
666682f0402Sdholland /* XXX why is this right-recursive? */
6675ecc953bSthorpej majorlist:
668c1e3ceeaSdholland 	  majordef
669c1e3ceeaSdholland 	| majorlist ',' majordef
670c1e3ceeaSdholland ;
6715ecc953bSthorpej 
672682f0402Sdholland /* one major number */
6735ecc953bSthorpej majordef:
674*9a7f4bbaSchristos 	devbase '=' int32		{ setmajor($1, $3); }
675*9a7f4bbaSchristos ;
676*9a7f4bbaSchristos 
677*9a7f4bbaSchristos int32:
678*9a7f4bbaSchristos 	NUMBER	{
679*9a7f4bbaSchristos 		if ($1.val > INT_MAX || $1.val < INT_MIN)
680*9a7f4bbaSchristos 			cfgerror("overflow %" PRId64, $1.val);
681*9a7f4bbaSchristos 		else
682*9a7f4bbaSchristos 			$$ = (int32_t)$1.val;
683*9a7f4bbaSchristos 	}
684c1e3ceeaSdholland ;
6855ecc953bSthorpej 
686682f0402Sdholland /************************************************************/
6875ecc953bSthorpej 
6885ecc953bSthorpej /*
68987ef93d9Suebayasi  * The selection grammar.
6905ecc953bSthorpej  */
691682f0402Sdholland 
69287ef93d9Suebayasi /* Complete selection part: all std.* files plus selected config. */
69387ef93d9Suebayasi selection_part:
69487ef93d9Suebayasi 	selections
695c1e3ceeaSdholland ;
6965ecc953bSthorpej 
6974c38d3adSdholland /* Zero or more config items. Trap errors. */
69887ef93d9Suebayasi selections:
6994c38d3adSdholland 	  /* empty */
70087ef93d9Suebayasi 	| selections '\n'
70187ef93d9Suebayasi 	| selections selection '\n'	{ wrap_continue(); }
70287ef93d9Suebayasi 	| selections error '\n'		{ wrap_cleanup(); }
703c1e3ceeaSdholland ;
7045ecc953bSthorpej 
705682f0402Sdholland /* One config item. */
70687ef93d9Suebayasi selection:
7074c38d3adSdholland 	  definition
70838146c24Suebayasi 	| select_no_filesystems
70938146c24Suebayasi 	| select_filesystems
71038146c24Suebayasi 	| select_no_makeoptions
71138146c24Suebayasi 	| select_makeoptions
71238146c24Suebayasi 	| select_no_options
71338146c24Suebayasi 	| select_options
71438146c24Suebayasi 	| select_maxusers
71538146c24Suebayasi 	| select_ident
71638146c24Suebayasi 	| select_no_ident
71738146c24Suebayasi 	| select_config
71838146c24Suebayasi 	| select_no_config
71938146c24Suebayasi 	| select_no_pseudodev
72038146c24Suebayasi 	| select_pseudodev
72138146c24Suebayasi 	| select_pseudoroot
72238146c24Suebayasi 	| select_no_device_instance_attachment
72338146c24Suebayasi 	| select_no_device_attachment
72438146c24Suebayasi 	| select_no_device_instance
72538146c24Suebayasi 	| select_device_instance
72638146c24Suebayasi ;
72738146c24Suebayasi 
72838146c24Suebayasi select_no_filesystems:
72938146c24Suebayasi 	NO FILE_SYSTEM no_fs_list
73038146c24Suebayasi ;
73138146c24Suebayasi 
73238146c24Suebayasi select_filesystems:
73338146c24Suebayasi 	FILE_SYSTEM fs_list
73438146c24Suebayasi ;
73538146c24Suebayasi 
73638146c24Suebayasi select_no_makeoptions:
73738146c24Suebayasi 	NO MAKEOPTIONS no_mkopt_list
73838146c24Suebayasi ;
73938146c24Suebayasi 
74038146c24Suebayasi select_makeoptions:
74138146c24Suebayasi 	MAKEOPTIONS mkopt_list
74238146c24Suebayasi ;
74338146c24Suebayasi 
74438146c24Suebayasi select_no_options:
74538146c24Suebayasi 	NO OPTIONS no_opt_list
74638146c24Suebayasi ;
74738146c24Suebayasi 
74838146c24Suebayasi select_options:
74938146c24Suebayasi 	OPTIONS opt_list
75038146c24Suebayasi ;
75138146c24Suebayasi 
75238146c24Suebayasi select_maxusers:
753*9a7f4bbaSchristos 	MAXUSERS int32			{ setmaxusers($2); }
75438146c24Suebayasi ;
75538146c24Suebayasi 
75638146c24Suebayasi select_ident:
75738146c24Suebayasi 	IDENT stringvalue		{ setident($2); }
75838146c24Suebayasi ;
75938146c24Suebayasi 
76038146c24Suebayasi select_no_ident:
76138146c24Suebayasi 	NO IDENT			{ setident(NULL); }
76238146c24Suebayasi ;
76338146c24Suebayasi 
76438146c24Suebayasi select_config:
76538146c24Suebayasi 	CONFIG conf root_spec sysparam_list
766c1e3ceeaSdholland 					{ addconf(&conf); }
76738146c24Suebayasi ;
76838146c24Suebayasi 
76938146c24Suebayasi select_no_config:
77038146c24Suebayasi 	NO CONFIG WORD			{ delconf($3); }
77138146c24Suebayasi ;
77238146c24Suebayasi 
77338146c24Suebayasi select_no_pseudodev:
77438146c24Suebayasi 	NO PSEUDO_DEVICE WORD		{ delpseudo($3); }
77538146c24Suebayasi ;
77638146c24Suebayasi 
77738146c24Suebayasi select_pseudodev:
77838146c24Suebayasi 	PSEUDO_DEVICE WORD npseudo	{ addpseudo($2, $3); }
77938146c24Suebayasi ;
78038146c24Suebayasi 
78138146c24Suebayasi select_pseudoroot:
78238146c24Suebayasi 	PSEUDO_ROOT device_instance	{ addpseudoroot($2); }
78338146c24Suebayasi ;
78438146c24Suebayasi 
78538146c24Suebayasi select_no_device_instance_attachment:
78638146c24Suebayasi 	NO device_instance AT attachment
787c1e3ceeaSdholland 					{ deldevi($2, $4); }
78838146c24Suebayasi ;
78938146c24Suebayasi 
79038146c24Suebayasi select_no_device_attachment:
79138146c24Suebayasi 	NO DEVICE AT attachment		{ deldeva($4); }
79238146c24Suebayasi ;
79338146c24Suebayasi 
79438146c24Suebayasi select_no_device_instance:
79538146c24Suebayasi 	NO device_instance		{ deldev($2); }
79638146c24Suebayasi ;
79738146c24Suebayasi 
79838146c24Suebayasi select_device_instance:
79938146c24Suebayasi 	device_instance AT attachment locators device_flags
800c1e3ceeaSdholland 					{ adddev($1, $3, $4, $5); }
801c1e3ceeaSdholland ;
8025ecc953bSthorpej 
803682f0402Sdholland /* list of filesystems */
8045ecc953bSthorpej fs_list:
805c1e3ceeaSdholland 	  fsoption
806c1e3ceeaSdholland 	| fs_list ',' fsoption
807c1e3ceeaSdholland ;
8085ecc953bSthorpej 
809682f0402Sdholland /* one filesystem */
8105ecc953bSthorpej fsoption:
811c1e3ceeaSdholland 	WORD				{ addfsoption($1); }
812c1e3ceeaSdholland ;
8135ecc953bSthorpej 
814682f0402Sdholland /* list of filesystems that had NO in front */
8155ecc953bSthorpej no_fs_list:
816c1e3ceeaSdholland 	  no_fsoption
817c1e3ceeaSdholland 	| no_fs_list ',' no_fsoption
818c1e3ceeaSdholland ;
8195ecc953bSthorpej 
820682f0402Sdholland /* one filesystem that had NO in front */
8215ecc953bSthorpej no_fsoption:
822c1e3ceeaSdholland 	WORD				{ delfsoption($1); }
823c1e3ceeaSdholland ;
8245ecc953bSthorpej 
825682f0402Sdholland /* list of make options */
826682f0402Sdholland /* XXX why is this right-recursive? */
8275ecc953bSthorpej mkopt_list:
828c1e3ceeaSdholland 	  mkoption
829c1e3ceeaSdholland 	| mkopt_list ',' mkoption
830c1e3ceeaSdholland ;
8315ecc953bSthorpej 
832682f0402Sdholland /* one make option */
8335ecc953bSthorpej mkoption:
834c1e3ceeaSdholland 	  mkvarname '=' value		{ addmkoption($1, $3); }
835c1e3ceeaSdholland 	| mkvarname PLUSEQ value	{ appendmkoption($1, $3); }
836c1e3ceeaSdholland ;
8375ecc953bSthorpej 
838682f0402Sdholland /* list of make options that had NO in front */
8395ecc953bSthorpej no_mkopt_list:
840c1e3ceeaSdholland 	  no_mkoption
841c1e3ceeaSdholland 	| no_mkopt_list ',' no_mkoption
842c1e3ceeaSdholland ;
8435ecc953bSthorpej 
844682f0402Sdholland /* one make option that had NO in front */
84582d86132Sdholland /* XXX shouldn't this be mkvarname rather than WORD? */
8465ecc953bSthorpej no_mkoption:
8475ecc953bSthorpej 	WORD				{ delmkoption($1); }
848c1e3ceeaSdholland ;
8495ecc953bSthorpej 
850682f0402Sdholland /* list of options */
8515ecc953bSthorpej opt_list:
852c1e3ceeaSdholland 	  option
853c1e3ceeaSdholland 	| opt_list ',' option
854c1e3ceeaSdholland ;
8555ecc953bSthorpej 
856682f0402Sdholland /* one option */
8575ecc953bSthorpej option:
858c1e3ceeaSdholland 	  WORD				{ addoption($1, NULL); }
859c1e3ceeaSdholland 	| WORD '=' value		{ addoption($1, $3); }
860c1e3ceeaSdholland ;
8615ecc953bSthorpej 
862682f0402Sdholland /* list of options that had NO in front */
8635ecc953bSthorpej no_opt_list:
864c1e3ceeaSdholland 	  no_option
865c1e3ceeaSdholland 	| no_opt_list ',' no_option
866c1e3ceeaSdholland ;
8675ecc953bSthorpej 
868682f0402Sdholland /* one option that had NO in front */
8695ecc953bSthorpej no_option:
870c1e3ceeaSdholland 	WORD				{ deloption($1); }
871c1e3ceeaSdholland ;
8725ecc953bSthorpej 
873682f0402Sdholland /* the name in "config name root on ..." */
8745ecc953bSthorpej conf:
875c1e3ceeaSdholland 	WORD				{
876c1e3ceeaSdholland 		conf.cf_name = $1;
8775ecc953bSthorpej 		conf.cf_lineno = currentline();
8785ecc953bSthorpej 		conf.cf_fstype = NULL;
8795ecc953bSthorpej 		conf.cf_root = NULL;
880c1e3ceeaSdholland 		conf.cf_dump = NULL;
881c1e3ceeaSdholland 	}
882c1e3ceeaSdholland ;
8835ecc953bSthorpej 
884682f0402Sdholland /* root fs specification */
8855ecc953bSthorpej root_spec:
8864c38d3adSdholland 	  ROOT on_opt dev_spec		{ setconf(&conf.cf_root, "root", $3); }
8874c38d3adSdholland 	| ROOT on_opt dev_spec fs_spec	{ setconf(&conf.cf_root, "root", $3); }
888c1e3ceeaSdholland ;
8895ecc953bSthorpej 
89082d86132Sdholland /* device for root fs or dump */
89182d86132Sdholland dev_spec:
892*9a7f4bbaSchristos 	  '?'				{ $$ = new_si(intern("?"),
893*9a7f4bbaSchristos 					    (long long)NODEV); }
894*9a7f4bbaSchristos 	| WORD				{ $$ = new_si($1,
895*9a7f4bbaSchristos 					    (long long)NODEV); }
89682d86132Sdholland 	| major_minor			{ $$ = new_si(NULL, $1); }
89782d86132Sdholland ;
89882d86132Sdholland 
89982d86132Sdholland /* major and minor device number */
90082d86132Sdholland major_minor:
90182d86132Sdholland 	MAJOR NUMBER MINOR NUMBER	{ $$ = makedev($2.val, $4.val); }
90282d86132Sdholland ;
90382d86132Sdholland 
904682f0402Sdholland /* filesystem type for root fs specification */
9055ecc953bSthorpej fs_spec:
9064c38d3adSdholland 	  TYPE '?'		   { setfstype(&conf.cf_fstype, intern("?")); }
9074c38d3adSdholland 	| TYPE WORD			{ setfstype(&conf.cf_fstype, $2); }
908c1e3ceeaSdholland ;
9095ecc953bSthorpej 
910682f0402Sdholland /* zero or more additional system parameters */
9115ecc953bSthorpej sysparam_list:
912c1e3ceeaSdholland 	  /* empty */
913c1e3ceeaSdholland 	| sysparam_list sysparam
914c1e3ceeaSdholland ;
9155ecc953bSthorpej 
916682f0402Sdholland /* one additional system parameter (there's only one: dumps) */
9175ecc953bSthorpej sysparam:
918c1e3ceeaSdholland 	DUMPS on_opt dev_spec	       { setconf(&conf.cf_dump, "dumps", $3); }
919c1e3ceeaSdholland ;
9205ecc953bSthorpej 
921682f0402Sdholland /* number of pseudo devices to configure (which is optional) */
9225ecc953bSthorpej npseudo:
923c1e3ceeaSdholland 	  /* empty */			{ $$ = 1; }
924*9a7f4bbaSchristos 	| int32				{ $$ = $1; }
925c1e3ceeaSdholland ;
9265ecc953bSthorpej 
927682f0402Sdholland /* name of a device to configure */
9285ecc953bSthorpej device_instance:
929c1e3ceeaSdholland 	  WORD				{ $$ = $1; }
930c1e3ceeaSdholland 	| WORD '*'			{ $$ = starref($1); }
931c1e3ceeaSdholland ;
9325ecc953bSthorpej 
933682f0402Sdholland /* name of a device to configure an attachment to */
9345ecc953bSthorpej attachment:
935c1e3ceeaSdholland 	  ROOT				{ $$ = NULL; }
936c1e3ceeaSdholland 	| WORD				{ $$ = $1; }
937c1e3ceeaSdholland 	| WORD '?'			{ $$ = wildref($1); }
938c1e3ceeaSdholland ;
9395ecc953bSthorpej 
940682f0402Sdholland /* zero or more locators */
9415ecc953bSthorpej locators:
942c1e3ceeaSdholland 	  /* empty */			{ $$ = NULL; }
943c1e3ceeaSdholland 	| locators locator		{ $$ = $2; app($2, $1); }
944c1e3ceeaSdholland ;
9455ecc953bSthorpej 
946682f0402Sdholland /* one locator */
9475ecc953bSthorpej locator:
94816a8771bSdholland 	  WORD '?'			{ $$ = MK3(loc, $1, NULL, 0); }
94916a8771bSdholland 	| WORD values			{ $$ = namelocvals($1, $2); }
950c1e3ceeaSdholland ;
9515ecc953bSthorpej 
952682f0402Sdholland /* optional device flags */
9534c38d3adSdholland device_flags:
954c1e3ceeaSdholland 	  /* empty */			{ $$ = 0; }
955*9a7f4bbaSchristos 	| FLAGS int32			{ $$ = $2; }
956c1e3ceeaSdholland ;
9575ecc953bSthorpej 
95882d86132Sdholland /************************************************************/
95982d86132Sdholland 
96082d86132Sdholland /*
9614e34eebcSdholland  * conditions
96282d86132Sdholland  */
96382d86132Sdholland 
96482d86132Sdholland 
96582d86132Sdholland /*
96682d86132Sdholland  * order of options is important, must use right recursion
96782d86132Sdholland  *
96882d86132Sdholland  * dholland 20120310: wut?
96982d86132Sdholland  */
97082d86132Sdholland 
9714e34eebcSdholland /* expression of conditions */
9724e34eebcSdholland condexpr:
9734e34eebcSdholland 	cond_or_expr
9742b9f70f8Sdholland ;
9752b9f70f8Sdholland 
9764e34eebcSdholland cond_or_expr:
9774e34eebcSdholland 	  cond_and_expr
9789483bda7Sdholland 	| cond_or_expr '|' cond_and_expr	{ $$ = MKF2(cx, or, $1, $3); }
9792b9f70f8Sdholland ;
9802b9f70f8Sdholland 
9814e34eebcSdholland cond_and_expr:
9824e34eebcSdholland 	  cond_prefix_expr
9839483bda7Sdholland 	| cond_and_expr '&' cond_prefix_expr	{ $$ = MKF2(cx, and, $1, $3); }
9842b9f70f8Sdholland ;
9852b9f70f8Sdholland 
9864e34eebcSdholland cond_prefix_expr:
9874e34eebcSdholland 	  cond_base_expr
9882b9f70f8Sdholland /* XXX notyet - need to strengthen downstream first */
9899483bda7Sdholland /*	| '!' cond_prefix_expr			{ $$ = MKF1(cx, not, $2); } */
9902b9f70f8Sdholland ;
9912b9f70f8Sdholland 
9924e34eebcSdholland cond_base_expr:
9934e34eebcSdholland 	  condatom			{ $$ = $1; }
9949483bda7Sdholland 	| '!' condatom			{ $$ = MKF1(cx, not, $2); }
9954e34eebcSdholland 	| '(' condexpr ')'		{ $$ = $2; }
99682d86132Sdholland ;
99782d86132Sdholland 
99882d86132Sdholland /* basic element of config element expression: a config element */
9994e34eebcSdholland condatom:
10009483bda7Sdholland 	WORD				{ $$ = MKF1(cx, atom, $1); }
100182d86132Sdholland ;
100282d86132Sdholland 
100382d86132Sdholland /************************************************************/
100482d86132Sdholland 
100582d86132Sdholland /*
100682d86132Sdholland  * Various nonterminals shared between the grammars.
100782d86132Sdholland  */
100882d86132Sdholland 
100982d86132Sdholland /* variable name for make option */
101082d86132Sdholland mkvarname:
101182d86132Sdholland 	  QSTRING			{ $$ = $1; }
101282d86132Sdholland 	| WORD				{ $$ = $1; }
101382d86132Sdholland ;
101482d86132Sdholland 
101582d86132Sdholland /* optional file for an option */
101682d86132Sdholland optfile_opt:
101782d86132Sdholland 	  /* empty */			{ $$ = NULL; }
101882d86132Sdholland 	| filename			{ $$ = $1; }
101982d86132Sdholland ;
102082d86132Sdholland 
102182d86132Sdholland /* filename. */
102282d86132Sdholland filename:
102382d86132Sdholland 	  QSTRING			{ $$ = $1; }
102482d86132Sdholland 	| PATHNAME			{ $$ = $1; }
102582d86132Sdholland ;
102682d86132Sdholland 
102782d86132Sdholland /* constant value */
102882d86132Sdholland value:
102982d86132Sdholland 	  QSTRING			{ $$ = $1; }
103082d86132Sdholland 	| WORD				{ $$ = $1; }
103182d86132Sdholland 	| EMPTYSTRING			{ $$ = $1; }
103282d86132Sdholland 	| signed_number			{
103382d86132Sdholland 		char bf[40];
103482d86132Sdholland 
103582d86132Sdholland 		(void)snprintf(bf, sizeof(bf), FORMAT($1), (long long)$1.val);
103682d86132Sdholland 		$$ = intern(bf);
103782d86132Sdholland 	  }
103882d86132Sdholland ;
103982d86132Sdholland 
104082d86132Sdholland /* constant value that is a string */
104182d86132Sdholland stringvalue:
104282d86132Sdholland 	  QSTRING			{ $$ = $1; }
104382d86132Sdholland 	| WORD				{ $$ = $1; }
104482d86132Sdholland ;
104582d86132Sdholland 
104682d86132Sdholland /* comma-separated list of values */
104782d86132Sdholland /* XXX why right-recursive? */
104882d86132Sdholland values:
104916a8771bSdholland 	  value				{ $$ = MKF2(loc, val, $1, NULL); }
105016a8771bSdholland 	| value ',' values		{ $$ = MKF2(loc, val, $1, $3); }
105182d86132Sdholland ;
105282d86132Sdholland 
105382d86132Sdholland /* possibly negative number */
105482d86132Sdholland signed_number:
105582d86132Sdholland 	  NUMBER			{ $$ = $1; }
105682d86132Sdholland 	| '-' NUMBER			{ $$.fmt = $2.fmt; $$.val = -$2.val; }
105782d86132Sdholland ;
105882d86132Sdholland 
105982d86132Sdholland /* optional ON keyword */
106082d86132Sdholland on_opt:
106182d86132Sdholland 	  /* empty */
106282d86132Sdholland 	| ON
106382d86132Sdholland ;
106482d86132Sdholland 
10655ecc953bSthorpej %%
10665ecc953bSthorpej 
10675ecc953bSthorpej void
10685ecc953bSthorpej yyerror(const char *s)
10695ecc953bSthorpej {
10705ecc953bSthorpej 
1071c7295a4cSchristos 	cfgerror("%s", s);
10725ecc953bSthorpej }
10735ecc953bSthorpej 
10742839b938Sdholland /************************************************************/
10752839b938Sdholland 
10765ecc953bSthorpej /*
10772839b938Sdholland  * Wrap allocations that live on the parser stack so that we can free
10782839b938Sdholland  * them again on error instead of leaking.
10792839b938Sdholland  */
10802839b938Sdholland 
10812839b938Sdholland #define MAX_WRAP 1000
10822839b938Sdholland 
10832839b938Sdholland struct wrap_entry {
10842839b938Sdholland 	void *ptr;
10852839b938Sdholland 	unsigned typecode;
10862839b938Sdholland };
10872839b938Sdholland 
10882839b938Sdholland static struct wrap_entry wrapstack[MAX_WRAP];
10892839b938Sdholland static unsigned wrap_depth;
10902839b938Sdholland 
10912839b938Sdholland /*
10922839b938Sdholland  * Remember pointer PTR with type-code CODE.
10935ecc953bSthorpej  */
10945ecc953bSthorpej static void
10952839b938Sdholland wrap_alloc(void *ptr, unsigned code)
10965ecc953bSthorpej {
10972839b938Sdholland 	unsigned pos;
10985ecc953bSthorpej 
10992839b938Sdholland 	if (wrap_depth >= MAX_WRAP) {
11002839b938Sdholland 		panic("allocation wrapper stack overflow");
11015ecc953bSthorpej 	}
11022839b938Sdholland 	pos = wrap_depth++;
11032839b938Sdholland 	wrapstack[pos].ptr = ptr;
11042839b938Sdholland 	wrapstack[pos].typecode = code;
11052839b938Sdholland }
11062839b938Sdholland 
11072839b938Sdholland /*
11082839b938Sdholland  * We succeeded; commit to keeping everything that's been allocated so
11092839b938Sdholland  * far and clear the stack.
11102839b938Sdholland  */
11112839b938Sdholland static void
11122839b938Sdholland wrap_continue(void)
11132839b938Sdholland {
11142839b938Sdholland 	wrap_depth = 0;
11152839b938Sdholland }
11162839b938Sdholland 
11172839b938Sdholland /*
11182839b938Sdholland  * We failed; destroy all the objects allocated.
11192839b938Sdholland  */
11202839b938Sdholland static void
11212839b938Sdholland wrap_cleanup(void)
11222839b938Sdholland {
11232839b938Sdholland 	unsigned i;
11242839b938Sdholland 
112516a8771bSdholland 	/*
112616a8771bSdholland 	 * Destroy each item. Note that because everything allocated
112716a8771bSdholland 	 * is entered on the list separately, lists and trees need to
112816a8771bSdholland 	 * have their links blanked before being destroyed. Also note
112916a8771bSdholland 	 * that strings are interned elsewhere and not handled by this
113016a8771bSdholland 	 * mechanism.
113116a8771bSdholland 	 */
113216a8771bSdholland 
11332839b938Sdholland 	for (i=0; i<wrap_depth; i++) {
11342839b938Sdholland 		switch (wrapstack[i].typecode) {
11352839b938Sdholland 		    case WRAP_CODE_nvlist:
11362839b938Sdholland 			nvfree(wrapstack[i].ptr);
11372839b938Sdholland 			break;
1138d74eb995Sdholland 		    case WRAP_CODE_defoptlist:
1139d74eb995Sdholland 			{
1140d74eb995Sdholland 				struct defoptlist *dl = wrapstack[i].ptr;
1141d74eb995Sdholland 
1142d74eb995Sdholland 				dl->dl_next = NULL;
1143d74eb995Sdholland 				defoptlist_destroy(dl);
1144d74eb995Sdholland 			}
1145d74eb995Sdholland 			break;
114616a8771bSdholland 		    case WRAP_CODE_loclist:
114716a8771bSdholland 			{
114816a8771bSdholland 				struct loclist *ll = wrapstack[i].ptr;
114916a8771bSdholland 
115016a8771bSdholland 				ll->ll_next = NULL;
115116a8771bSdholland 				loclist_destroy(ll);
115216a8771bSdholland 			}
115316a8771bSdholland 			break;
11544caf067bSdholland 		    case WRAP_CODE_attrlist:
11554caf067bSdholland 			{
11564caf067bSdholland 				struct attrlist *al = wrapstack[i].ptr;
11574caf067bSdholland 
11584caf067bSdholland 				al->al_next = NULL;
11594caf067bSdholland 				al->al_this = NULL;
11604caf067bSdholland 				attrlist_destroy(al);
11614caf067bSdholland 			}
11624caf067bSdholland 			break;
116316a8771bSdholland 		    case WRAP_CODE_condexpr:
116416a8771bSdholland 			{
116516a8771bSdholland 				struct condexpr *cx = wrapstack[i].ptr;
116616a8771bSdholland 
116716a8771bSdholland 				cx->cx_type = CX_ATOM;
116816a8771bSdholland 				cx->cx_atom = NULL;
116916a8771bSdholland 				condexpr_destroy(cx);
117016a8771bSdholland 			}
117116a8771bSdholland 			break;
11722839b938Sdholland 		    default:
11732839b938Sdholland 			panic("invalid code %u on allocation wrapper stack",
11742839b938Sdholland 			      wrapstack[i].typecode);
11752839b938Sdholland 		}
11762839b938Sdholland 	}
11774caf067bSdholland 
11782839b938Sdholland 	wrap_depth = 0;
11792839b938Sdholland }
11802839b938Sdholland 
11812839b938Sdholland /*
11822839b938Sdholland  * Instantiate the wrapper functions.
11832839b938Sdholland  *
11842839b938Sdholland  * Each one calls wrap_alloc to save the pointer and then returns the
11852839b938Sdholland  * pointer again; these need to be generated with the preprocessor in
11862839b938Sdholland  * order to be typesafe.
11872839b938Sdholland  */
11882839b938Sdholland #define DEF_ALLOCWRAP(t) \
11892839b938Sdholland 	static struct t *				\
11902839b938Sdholland 	wrap_mk_##t(struct t *arg)			\
11912839b938Sdholland 	{						\
11922839b938Sdholland 		wrap_alloc(arg, WRAP_CODE_##t);		\
11932839b938Sdholland 		return arg;				\
11942839b938Sdholland 	}
11952839b938Sdholland 
11962839b938Sdholland DEF_ALLOCWRAP(nvlist);
1197d74eb995Sdholland DEF_ALLOCWRAP(defoptlist);
119816a8771bSdholland DEF_ALLOCWRAP(loclist);
11994caf067bSdholland DEF_ALLOCWRAP(attrlist);
12009483bda7Sdholland DEF_ALLOCWRAP(condexpr);
12014caf067bSdholland 
12024caf067bSdholland /************************************************************/
12034caf067bSdholland 
12044caf067bSdholland /*
12054caf067bSdholland  * Data constructors
120616a8771bSdholland  *
120716a8771bSdholland  * (These are *beneath* the allocation wrappers.)
12084caf067bSdholland  */
12094caf067bSdholland 
1210d74eb995Sdholland static struct defoptlist *
1211d74eb995Sdholland mk_defoptlist(const char *name, const char *val, const char *lintval)
1212d74eb995Sdholland {
1213d74eb995Sdholland 	return defoptlist_create(name, val, lintval);
1214d74eb995Sdholland }
1215d74eb995Sdholland 
121616a8771bSdholland static struct loclist *
121716a8771bSdholland mk_loc(const char *name, const char *str, long long num)
121816a8771bSdholland {
121916a8771bSdholland 	return loclist_create(name, str, num);
122016a8771bSdholland }
122116a8771bSdholland 
122216a8771bSdholland static struct loclist *
122316a8771bSdholland mk_loc_val(const char *str, struct loclist *next)
122416a8771bSdholland {
122516a8771bSdholland 	struct loclist *ll;
122616a8771bSdholland 
122716a8771bSdholland 	ll = mk_loc(NULL, str, 0);
122816a8771bSdholland 	ll->ll_next = next;
122916a8771bSdholland 	return ll;
123016a8771bSdholland }
123116a8771bSdholland 
12324caf067bSdholland static struct attrlist *
12334caf067bSdholland mk_attrlist(struct attrlist *next, struct attr *a)
12344caf067bSdholland {
12354caf067bSdholland 	return attrlist_cons(next, a);
12364caf067bSdholland }
12372839b938Sdholland 
12389483bda7Sdholland static struct condexpr *
12399483bda7Sdholland mk_cx_atom(const char *s)
12409483bda7Sdholland {
12419483bda7Sdholland 	struct condexpr *cx;
12429483bda7Sdholland 
12439483bda7Sdholland 	cx = condexpr_create(CX_ATOM);
12449483bda7Sdholland 	cx->cx_atom = s;
12459483bda7Sdholland 	return cx;
12469483bda7Sdholland }
12479483bda7Sdholland 
12489483bda7Sdholland static struct condexpr *
12499483bda7Sdholland mk_cx_not(struct condexpr *sub)
12509483bda7Sdholland {
12519483bda7Sdholland 	struct condexpr *cx;
12529483bda7Sdholland 
12539483bda7Sdholland 	cx = condexpr_create(CX_NOT);
12549483bda7Sdholland 	cx->cx_not = sub;
12559483bda7Sdholland 	return cx;
12569483bda7Sdholland }
12579483bda7Sdholland 
12589483bda7Sdholland static struct condexpr *
12599483bda7Sdholland mk_cx_and(struct condexpr *left, struct condexpr *right)
12609483bda7Sdholland {
12619483bda7Sdholland 	struct condexpr *cx;
12629483bda7Sdholland 
12639483bda7Sdholland 	cx = condexpr_create(CX_AND);
12649483bda7Sdholland 	cx->cx_and.left = left;
12659483bda7Sdholland 	cx->cx_and.right = right;
12669483bda7Sdholland 	return cx;
12679483bda7Sdholland }
12689483bda7Sdholland 
12699483bda7Sdholland static struct condexpr *
12709483bda7Sdholland mk_cx_or(struct condexpr *left, struct condexpr *right)
12719483bda7Sdholland {
12729483bda7Sdholland 	struct condexpr *cx;
12739483bda7Sdholland 
12749483bda7Sdholland 	cx = condexpr_create(CX_OR);
12759483bda7Sdholland 	cx->cx_or.left = left;
12769483bda7Sdholland 	cx->cx_or.right = right;
12779483bda7Sdholland 	return cx;
12789483bda7Sdholland }
12799483bda7Sdholland 
12802839b938Sdholland /************************************************************/
12815ecc953bSthorpej 
12825ecc953bSthorpej static void
1283e239742fSpooka setmachine(const char *mch, const char *mcharch, struct nvlist *mchsubarches,
1284e239742fSpooka 	int isioconf)
12855ecc953bSthorpej {
12865ecc953bSthorpej 	char buf[MAXPATHLEN];
12875ecc953bSthorpej 	struct nvlist *nv;
12885ecc953bSthorpej 
1289e239742fSpooka 	if (isioconf) {
1290e239742fSpooka 		if (include(_PATH_DEVNULL, ENDDEFS, 0, 0) != 0)
1291e239742fSpooka 			exit(1);
1292e239742fSpooka 		ioconfname = mch;
1293e239742fSpooka 		return;
1294e239742fSpooka 	}
1295e239742fSpooka 
12965ecc953bSthorpej 	machine = mch;
12975ecc953bSthorpej 	machinearch = mcharch;
12985ecc953bSthorpej 	machinesubarches = mchsubarches;
12995ecc953bSthorpej 
13005ecc953bSthorpej 	/*
130166796c65Scube 	 * Define attributes for all the given names
130266796c65Scube 	 */
130366a59dccScube 	if (defattr(machine, NULL, NULL, 0) != 0 ||
130466a59dccScube 	    (machinearch != NULL &&
130566a59dccScube 	     defattr(machinearch, NULL, NULL, 0) != 0))
130666796c65Scube 		exit(1);
130766796c65Scube 	for (nv = machinesubarches; nv != NULL; nv = nv->nv_next) {
130866796c65Scube 		if (defattr(nv->nv_name, NULL, NULL, 0) != 0)
130966796c65Scube 			exit(1);
131066796c65Scube 	}
131166796c65Scube 
131266796c65Scube 	/*
13135ecc953bSthorpej 	 * Set up the file inclusion stack.  This empty include tells
13145ecc953bSthorpej 	 * the parser there are no more device definitions coming.
13155ecc953bSthorpej 	 */
1316e239742fSpooka 	if (include(_PATH_DEVNULL, ENDDEFS, 0, 0) != 0)
13175ecc953bSthorpej 		exit(1);
13185ecc953bSthorpej 
13195ecc953bSthorpej 	/* Include arch/${MACHINE}/conf/files.${MACHINE} */
13205ecc953bSthorpej 	(void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s",
13215ecc953bSthorpej 	    machine, machine);
13225ecc953bSthorpej 	if (include(buf, ENDFILE, 0, 0) != 0)
13235ecc953bSthorpej 		exit(1);
13245ecc953bSthorpej 
13255ecc953bSthorpej 	/* Include any arch/${MACHINE_SUBARCH}/conf/files.${MACHINE_SUBARCH} */
13265ecc953bSthorpej 	for (nv = machinesubarches; nv != NULL; nv = nv->nv_next) {
13275ecc953bSthorpej 		(void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s",
13285ecc953bSthorpej 		    nv->nv_name, nv->nv_name);
13295ecc953bSthorpej 		if (include(buf, ENDFILE, 0, 0) != 0)
13305ecc953bSthorpej 			exit(1);
13315ecc953bSthorpej 	}
13325ecc953bSthorpej 
13335ecc953bSthorpej 	/* Include any arch/${MACHINE_ARCH}/conf/files.${MACHINE_ARCH} */
13345ecc953bSthorpej 	if (machinearch != NULL)
13355ecc953bSthorpej 		(void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s",
13365ecc953bSthorpej 		    machinearch, machinearch);
13375ecc953bSthorpej 	else
13385ecc953bSthorpej 		strlcpy(buf, _PATH_DEVNULL, sizeof(buf));
13395ecc953bSthorpej 	if (include(buf, ENDFILE, 0, 0) != 0)
13405ecc953bSthorpej 		exit(1);
13415ecc953bSthorpej 
13425ecc953bSthorpej 	/*
13435ecc953bSthorpej 	 * Include the global conf/files.  As the last thing
13445ecc953bSthorpej 	 * pushed on the stack, it will be processed first.
13455ecc953bSthorpej 	 */
13465ecc953bSthorpej 	if (include("conf/files", ENDFILE, 0, 0) != 0)
13475ecc953bSthorpej 		exit(1);
13486fd5c015Smartin 
13496fd5c015Smartin 	oktopackage = 1;
13505ecc953bSthorpej }
13515ecc953bSthorpej 
13525ecc953bSthorpej static void
13535ecc953bSthorpej check_maxpart(void)
13545ecc953bSthorpej {
13555ecc953bSthorpej 
1356e239742fSpooka 	if (maxpartitions <= 0 && ioconfname == NULL) {
13575ecc953bSthorpej 		stop("cannot proceed without maxpartitions specifier");
13585ecc953bSthorpej 	}
13595ecc953bSthorpej }
13605ecc953bSthorpej 
13615ecc953bSthorpej static void
1362437f8925Scube check_version(void)
1363437f8925Scube {
1364437f8925Scube 	/*
1365437f8925Scube 	 * In essence, version is 0 and is not supported anymore
1366437f8925Scube 	 */
1367437f8925Scube 	if (version < CONFIG_MINVERSION)
1368437f8925Scube 		stop("your sources are out of date -- please update.");
1369437f8925Scube }
1370437f8925Scube 
137116a8771bSdholland /*
137216a8771bSdholland  * Prepend a blank entry to the locator definitions so the code in
137316a8771bSdholland  * sem.c can distinguish "empty locator list" from "no locator list".
137416a8771bSdholland  * XXX gross.
137516a8771bSdholland  */
137616a8771bSdholland static struct loclist *
137716a8771bSdholland present_loclist(struct loclist *ll)
13785ecc953bSthorpej {
137916a8771bSdholland 	struct loclist *ret;
138016a8771bSdholland 
138116a8771bSdholland 	ret = MK3(loc, "", NULL, 0);
138216a8771bSdholland 	ret->ll_next = ll;
138316a8771bSdholland 	return ret;
13845ecc953bSthorpej }
13855ecc953bSthorpej 
138616a8771bSdholland static void
138716a8771bSdholland app(struct loclist *p, struct loclist *q)
13885ecc953bSthorpej {
138916a8771bSdholland 	while (p->ll_next)
139016a8771bSdholland 		p = p->ll_next;
139116a8771bSdholland 	p->ll_next = q;
139216a8771bSdholland }
139316a8771bSdholland 
139416a8771bSdholland static struct loclist *
139516a8771bSdholland locarray(const char *name, int count, struct loclist *adefs, int opt)
139616a8771bSdholland {
139716a8771bSdholland 	struct loclist *defs = adefs;
139816a8771bSdholland 	struct loclist **p;
13995ecc953bSthorpej 	char buf[200];
14005ecc953bSthorpej 	int i;
14015ecc953bSthorpej 
14025ecc953bSthorpej 	if (count <= 0) {
14035ecc953bSthorpej 		fprintf(stderr, "config: array with <= 0 size: %s\n", name);
14045ecc953bSthorpej 		exit(1);
14055ecc953bSthorpej 	}
14065ecc953bSthorpej 	p = &defs;
14075ecc953bSthorpej 	for(i = 0; i < count; i++) {
14085ecc953bSthorpej 		if (*p == NULL)
140916a8771bSdholland 			*p = MK3(loc, NULL, "0", 0);
14105ecc953bSthorpej 		snprintf(buf, sizeof(buf), "%s%c%d", name, ARRCHR, i);
141116a8771bSdholland 		(*p)->ll_name = i == 0 ? name : intern(buf);
141216a8771bSdholland 		(*p)->ll_num = i > 0 || opt;
141316a8771bSdholland 		p = &(*p)->ll_next;
14145ecc953bSthorpej 	}
14155ecc953bSthorpej 	*p = 0;
14165ecc953bSthorpej 	return defs;
14175ecc953bSthorpej }
14185ecc953bSthorpej 
14195ecc953bSthorpej 
142016a8771bSdholland static struct loclist *
142116a8771bSdholland namelocvals(const char *name, struct loclist *vals)
14225ecc953bSthorpej {
142316a8771bSdholland 	struct loclist *p;
14245ecc953bSthorpej 	char buf[200];
14255ecc953bSthorpej 	int i;
14265ecc953bSthorpej 
142716a8771bSdholland 	for (i = 0, p = vals; p; i++, p = p->ll_next) {
14285ecc953bSthorpej 		snprintf(buf, sizeof(buf), "%s%c%d", name, ARRCHR, i);
142916a8771bSdholland 		p->ll_name = i == 0 ? name : intern(buf);
14305ecc953bSthorpej 	}
14315ecc953bSthorpej 	return vals;
14325ecc953bSthorpej }
14335ecc953bSthorpej 
1434