1995-04-28 10:54:58 +04:00
|
|
|
%{
|
2020-07-27 01:40:52 +03:00
|
|
|
/* $NetBSD: gram.y,v 1.56 2020/07/26 22:40:52 uwe Exp $ */
|
1995-04-28 10:54:58 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 1992, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* This software was developed by the Computer Systems Engineering group
|
|
|
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
|
|
|
* contributed to Berkeley.
|
|
|
|
*
|
|
|
|
* All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by the University of
|
|
|
|
* California, Lawrence Berkeley Laboratories.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2003-08-07 15:25:11 +04:00
|
|
|
* 3. Neither the name of the University nor the names of its contributors
|
1995-04-28 10:54:58 +04:00
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
* from: @(#)gram.y 8.1 (Berkeley) 6/6/93
|
|
|
|
*/
|
|
|
|
|
2014-10-29 20:14:50 +03:00
|
|
|
#include <sys/cdefs.h>
|
2020-07-27 01:40:52 +03:00
|
|
|
__RCSID("$NetBSD: gram.y,v 1.56 2020/07/26 22:40:52 uwe Exp $");
|
2014-10-29 20:14:50 +03:00
|
|
|
|
1996-09-01 00:58:16 +04:00
|
|
|
#include <sys/types.h>
|
1996-11-12 02:54:17 +03:00
|
|
|
#include <sys/param.h>
|
1995-04-28 10:54:58 +04:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
1996-09-01 00:58:16 +04:00
|
|
|
#include <errno.h>
|
2002-01-29 13:20:28 +03:00
|
|
|
#include "defs.h"
|
1995-04-28 10:54:58 +04:00
|
|
|
#include "sem.h"
|
|
|
|
|
2003-11-19 21:06:13 +03:00
|
|
|
#define FORMAT(n) (((n).fmt == 8 && (n).val != 0) ? "0%llo" : \
|
|
|
|
((n).fmt == 16) ? "0x%llx" : "%lld")
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2007-01-14 02:47:36 +03:00
|
|
|
#define stop(s) cfgerror(s), exit(1)
|
1995-04-28 10:54:58 +04:00
|
|
|
|
|
|
|
static struct config conf; /* at most one active at a time */
|
2016-08-07 13:37:24 +03:00
|
|
|
static int nowarn; /* if warning suppression is on */
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 11:27:02 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocation wrapper functions
|
|
|
|
*/
|
|
|
|
static void wrap_alloc(void *ptr, unsigned code);
|
|
|
|
static void wrap_continue(void);
|
|
|
|
static void wrap_cleanup(void);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocation wrapper type codes
|
|
|
|
*/
|
|
|
|
#define WRAP_CODE_nvlist 1
|
2012-03-12 06:58:55 +04:00
|
|
|
#define WRAP_CODE_defoptlist 2
|
|
|
|
#define WRAP_CODE_loclist 3
|
|
|
|
#define WRAP_CODE_attrlist 4
|
|
|
|
#define WRAP_CODE_condexpr 5
|
2012-03-11 11:27:02 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The allocation wrappers themselves
|
|
|
|
*/
|
|
|
|
#define DECL_ALLOCWRAP(t) static struct t *wrap_mk_##t(struct t *arg)
|
|
|
|
|
|
|
|
DECL_ALLOCWRAP(nvlist);
|
2012-03-12 06:58:55 +04:00
|
|
|
DECL_ALLOCWRAP(defoptlist);
|
2012-03-12 01:16:07 +04:00
|
|
|
DECL_ALLOCWRAP(loclist);
|
2012-03-11 11:32:41 +04:00
|
|
|
DECL_ALLOCWRAP(attrlist);
|
2012-03-11 12:21:53 +04:00
|
|
|
DECL_ALLOCWRAP(condexpr);
|
|
|
|
|
|
|
|
/* allow shorter names */
|
2012-03-12 01:16:07 +04:00
|
|
|
#define wrap_mk_loc(p) wrap_mk_loclist(p)
|
2012-03-11 12:21:53 +04:00
|
|
|
#define wrap_mk_cx(p) wrap_mk_condexpr(p)
|
2012-03-11 11:27:02 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Macros for allocating new objects
|
|
|
|
*/
|
|
|
|
|
2012-03-11 11:32:41 +04:00
|
|
|
/* old-style for struct nvlist */
|
2012-03-11 11:27:02 +04:00
|
|
|
#define new0(n,s,p,i,x) wrap_mk_nvlist(newnv(n, s, p, i, x))
|
1996-03-17 14:50:09 +03:00
|
|
|
#define new_n(n) new0(n, NULL, NULL, 0, NULL)
|
|
|
|
#define new_nx(n, x) new0(n, NULL, NULL, 0, x)
|
|
|
|
#define new_ns(n, s) new0(n, s, NULL, 0, NULL)
|
|
|
|
#define new_si(s, i) new0(NULL, s, NULL, i, NULL)
|
2016-04-29 21:18:22 +03:00
|
|
|
#define new_spi(s, p, i) new0(NULL, s, p, i, NULL)
|
1996-03-17 14:50:09 +03:00
|
|
|
#define new_nsi(n,s,i) new0(n, s, NULL, i, NULL)
|
|
|
|
#define new_np(n, p) new0(n, NULL, p, 0, NULL)
|
|
|
|
#define new_s(s) new0(NULL, s, NULL, 0, NULL)
|
|
|
|
#define new_p(p) new0(NULL, NULL, p, 0, NULL)
|
|
|
|
#define new_px(p, x) new0(NULL, NULL, p, 0, x)
|
1999-01-21 16:10:08 +03:00
|
|
|
#define new_sx(s, x) new0(NULL, s, NULL, 0, x)
|
2007-01-09 16:03:47 +03:00
|
|
|
#define new_nsx(n,s,x) new0(n, s, NULL, 0, x)
|
2010-05-01 00:47:17 +04:00
|
|
|
#define new_i(i) new0(NULL, NULL, NULL, i, NULL)
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 12:21:53 +04:00
|
|
|
/* new style, type-polymorphic; ordinary and for types with multiple flavors */
|
2012-03-11 11:32:41 +04:00
|
|
|
#define MK0(t) wrap_mk_##t(mk_##t())
|
|
|
|
#define MK1(t, a0) wrap_mk_##t(mk_##t(a0))
|
|
|
|
#define MK2(t, a0, a1) wrap_mk_##t(mk_##t(a0, a1))
|
2012-03-12 01:16:07 +04:00
|
|
|
#define MK3(t, a0, a1, a2) wrap_mk_##t(mk_##t(a0, a1, a2))
|
2012-03-11 11:32:41 +04:00
|
|
|
|
2012-03-11 12:21:53 +04:00
|
|
|
#define MKF0(t, f) wrap_mk_##t(mk_##t##_##f())
|
|
|
|
#define MKF1(t, f, a0) wrap_mk_##t(mk_##t##_##f(a0))
|
|
|
|
#define MKF2(t, f, a0, a1) wrap_mk_##t(mk_##t##_##f(a0, a1))
|
|
|
|
|
2012-03-11 11:32:41 +04:00
|
|
|
/*
|
|
|
|
* Data constructors
|
|
|
|
*/
|
|
|
|
|
2012-03-12 06:58:55 +04:00
|
|
|
static struct defoptlist *mk_defoptlist(const char *, const char *,
|
|
|
|
const char *);
|
2012-03-12 01:16:07 +04:00
|
|
|
static struct loclist *mk_loc(const char *, const char *, long long);
|
|
|
|
static struct loclist *mk_loc_val(const char *, struct loclist *);
|
2012-03-11 11:32:41 +04:00
|
|
|
static struct attrlist *mk_attrlist(struct attrlist *, struct attr *);
|
2012-03-11 12:21:53 +04:00
|
|
|
static struct condexpr *mk_cx_atom(const char *);
|
|
|
|
static struct condexpr *mk_cx_not(struct condexpr *);
|
|
|
|
static struct condexpr *mk_cx_and(struct condexpr *, struct condexpr *);
|
|
|
|
static struct condexpr *mk_cx_or(struct condexpr *, struct condexpr *);
|
2012-03-11 11:32:41 +04:00
|
|
|
|
2012-03-11 11:27:02 +04:00
|
|
|
/*
|
|
|
|
* Other private functions
|
|
|
|
*/
|
|
|
|
|
2010-02-04 00:00:49 +03:00
|
|
|
static void setmachine(const char *, const char *, struct nvlist *, int);
|
2000-10-02 23:48:34 +04:00
|
|
|
static void check_maxpart(void);
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-12 01:16:07 +04:00
|
|
|
static struct loclist *present_loclist(struct loclist *ll);
|
|
|
|
static void app(struct loclist *, struct loclist *);
|
|
|
|
static struct loclist *locarray(const char *, int, struct loclist *, int);
|
|
|
|
static struct loclist *namelocvals(const char *, struct loclist *);
|
1999-01-21 16:10:08 +03:00
|
|
|
|
1995-04-28 10:54:58 +04:00
|
|
|
%}
|
|
|
|
|
|
|
|
%union {
|
|
|
|
struct attr *attr;
|
|
|
|
struct devbase *devb;
|
1996-03-17 05:08:22 +03:00
|
|
|
struct deva *deva;
|
1995-04-28 10:54:58 +04:00
|
|
|
struct nvlist *list;
|
2012-03-12 06:58:55 +04:00
|
|
|
struct defoptlist *defoptlist;
|
2012-03-12 01:16:07 +04:00
|
|
|
struct loclist *loclist;
|
2012-03-11 11:32:41 +04:00
|
|
|
struct attrlist *attrlist;
|
2012-03-11 12:21:53 +04:00
|
|
|
struct condexpr *condexpr;
|
1995-04-28 10:54:58 +04:00
|
|
|
const char *str;
|
2003-11-19 21:06:13 +03:00
|
|
|
struct numconst num;
|
2003-11-18 21:47:36 +03:00
|
|
|
int64_t val;
|
2014-10-29 20:14:50 +03:00
|
|
|
u_char flag;
|
|
|
|
devmajor_t devmajor;
|
|
|
|
int32_t i32;
|
1995-04-28 10:54:58 +04:00
|
|
|
}
|
|
|
|
|
2004-06-03 22:37:59 +04:00
|
|
|
%token AND AT ATTACH
|
|
|
|
%token BLOCK BUILD
|
2007-01-09 16:03:47 +03:00
|
|
|
%token CHAR COLONEQ COMPILE_WITH CONFIG
|
2008-06-10 16:35:32 +04:00
|
|
|
%token DEFFS DEFINE DEFOPT DEFPARAM DEFFLAG DEFPSEUDO DEFPSEUDODEV
|
|
|
|
%token DEVICE DEVCLASS DUMPS DEVICE_MAJOR
|
2004-06-03 22:37:59 +04:00
|
|
|
%token ENDFILE
|
|
|
|
%token XFILE FILE_SYSTEM FLAGS
|
2010-02-04 00:00:49 +03:00
|
|
|
%token IDENT IOCONF
|
2010-05-01 00:47:17 +04:00
|
|
|
%token LINKZERO
|
2004-06-03 22:37:59 +04:00
|
|
|
%token XMACHINE MAJOR MAKEOPTIONS MAXUSERS MAXPARTITIONS MINOR
|
2016-08-07 13:37:24 +03:00
|
|
|
%token NEEDS_COUNT NEEDS_FLAG NO CNO
|
Introduce two new statements:
obsolete defflag <option> [, <option> [, ...]]
obsolete defparam <option> [, <option> [, ...]]
The two statements actually do the same thing (there could be only one),
but it makes things less cryptic that way. The optional ": deps" part of
a 'defflag' or 'defparam' still has to be dropped when it gets obsoleted.
When the user has 'options OBSOLETE_OPTION' in his configuration file, it
is ignored (that is, opt_*.h files are generated as if it wasn't there),
and the user gets a warning about it.
Bump version to 20060525.
When someone first uses that syntax in the tree, a "version 20060525"
statement should be added before its occurrence, preferably at the top
of sys/conf/files.
Suggested by Matt Thomas a few months ago.
2006-05-26 02:28:38 +04:00
|
|
|
%token XOBJECT OBSOLETE ON OPTIONS
|
2015-09-01 16:42:48 +03:00
|
|
|
%token PACKAGE PLUSEQ PREFIX BUILDPREFIX PSEUDO_DEVICE PSEUDO_ROOT
|
2004-06-03 22:37:59 +04:00
|
|
|
%token ROOT
|
2014-10-31 10:38:36 +03:00
|
|
|
%token SELECT SINGLE SOURCE
|
2004-06-03 22:37:59 +04:00
|
|
|
%token TYPE
|
2010-05-01 00:47:17 +04:00
|
|
|
%token VECTOR VERSION
|
2004-06-03 22:37:59 +04:00
|
|
|
%token WITH
|
2003-11-19 21:06:13 +03:00
|
|
|
%token <num> NUMBER
|
2006-08-26 22:17:13 +04:00
|
|
|
%token <str> PATHNAME QSTRING WORD EMPTYSTRING
|
2001-06-08 16:47:06 +04:00
|
|
|
%token ENDDEFS
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 12:21:53 +04:00
|
|
|
%type <condexpr> fopts condexpr condatom
|
|
|
|
%type <condexpr> cond_or_expr cond_and_expr cond_prefix_expr
|
|
|
|
%type <condexpr> cond_base_expr
|
1997-01-31 06:12:30 +03:00
|
|
|
%type <str> fs_spec
|
2014-10-29 20:14:50 +03:00
|
|
|
%type <flag> fflags fflag oflags oflag
|
2015-08-29 05:54:07 +03:00
|
|
|
%type <str> rule
|
2012-03-11 11:46:47 +04:00
|
|
|
%type <attr> depend
|
1995-04-28 10:54:58 +04:00
|
|
|
%type <devb> devbase
|
1996-03-17 05:08:22 +03:00
|
|
|
%type <deva> devattach_opt
|
2012-03-12 01:16:07 +04:00
|
|
|
%type <list> atlist
|
|
|
|
%type <loclist> interface_opt
|
1995-04-28 10:54:58 +04:00
|
|
|
%type <str> atname
|
2012-03-12 01:16:07 +04:00
|
|
|
%type <loclist> loclist locdef
|
1995-04-28 10:54:58 +04:00
|
|
|
%type <str> locdefault
|
2012-03-12 01:16:07 +04:00
|
|
|
%type <loclist> values locdefaults
|
2012-03-11 11:46:47 +04:00
|
|
|
%type <attrlist> depend_list depends
|
2012-03-12 01:16:07 +04:00
|
|
|
%type <loclist> locators locator
|
1997-06-12 19:03:09 +04:00
|
|
|
%type <list> dev_spec
|
1995-04-28 10:54:58 +04:00
|
|
|
%type <str> device_instance
|
|
|
|
%type <str> attachment
|
|
|
|
%type <str> value
|
2014-10-29 20:14:50 +03:00
|
|
|
%type <val> major_minor
|
2003-11-19 21:06:13 +03:00
|
|
|
%type <num> signed_number
|
2016-08-07 13:37:24 +03:00
|
|
|
%type <i32> int32 npseudo device_flags no
|
1998-02-19 03:27:00 +03:00
|
|
|
%type <str> deffs
|
|
|
|
%type <list> deffses
|
2012-03-12 06:58:55 +04:00
|
|
|
%type <defoptlist> defopt
|
|
|
|
%type <defoptlist> defopts
|
2012-03-11 23:27:26 +04:00
|
|
|
%type <str> optdepend
|
|
|
|
%type <list> optdepends
|
|
|
|
%type <list> optdepend_list
|
1998-01-12 10:37:40 +03:00
|
|
|
%type <str> optfile_opt
|
2012-03-11 06:21:04 +04:00
|
|
|
%type <list> subarches
|
2005-06-01 16:32:57 +04:00
|
|
|
%type <str> filename stringvalue locname mkvarname
|
2014-10-29 20:14:50 +03:00
|
|
|
%type <devmajor> device_major_block device_major_char
|
2010-05-01 00:47:17 +04:00
|
|
|
%type <list> devnodes devnodetype devnodeflags devnode_dims
|
1995-04-28 10:54:58 +04:00
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
/*
|
2014-10-09 11:05:01 +04:00
|
|
|
* A complete configuration consists of both the selection part (a
|
2012-03-11 04:14:20 +04:00
|
|
|
* kernel config such as GENERIC or SKYNET, plus also the various
|
|
|
|
* std.* files), which selects the material to be in the kernel, and
|
|
|
|
* also the definition part (files, files.*, etc.) that declares what
|
|
|
|
* material is available to be placed in kernels.
|
|
|
|
*
|
|
|
|
* The two parts have almost entirely separate syntaxes. This grammar
|
|
|
|
* covers both of them. When config is run on a kernel configuration
|
|
|
|
* file, the std.* file for the port is included explicitly. The
|
|
|
|
* files.* files are included implicitly when the std.* file declares
|
|
|
|
* the machine type.
|
|
|
|
*
|
|
|
|
* The machine spec, which brings in the definition part, must appear
|
|
|
|
* before all configuration material except for the "topthings"; these
|
|
|
|
* are the "source" and "build" declarations that tell config where
|
|
|
|
* things are. These are not used by default.
|
|
|
|
*
|
|
|
|
* A previous version of this comment contained the following text:
|
|
|
|
*
|
|
|
|
* Note that we do not have sufficient keywords to enforce any
|
|
|
|
* order between elements of "topthings" without introducing
|
|
|
|
* shift/reduce conflicts. Instead, check order requirements in
|
|
|
|
* the C code.
|
|
|
|
*
|
|
|
|
* As of March 2012 this comment makes no sense, as there are only two
|
|
|
|
* topthings and no reason for them to be forcibly ordered.
|
|
|
|
* Furthermore, the statement about conflicts is false.
|
1995-04-28 10:54:58 +04:00
|
|
|
*/
|
2012-03-11 04:14:20 +04:00
|
|
|
|
|
|
|
/* Complete configuration. */
|
2012-03-11 06:21:04 +04:00
|
|
|
configuration:
|
2014-10-09 11:05:01 +04:00
|
|
|
topthings machine_spec definition_part selection_part
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* Sequence of zero or more topthings. */
|
1996-11-12 02:54:17 +03:00
|
|
|
topthings:
|
2012-03-11 04:57:44 +04:00
|
|
|
/* empty */
|
|
|
|
| topthings topthing
|
|
|
|
;
|
1996-09-01 00:58:16 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* Directory specification. */
|
1996-11-12 02:54:17 +03:00
|
|
|
topthing:
|
2012-03-11 05:09:42 +04:00
|
|
|
'\n'
|
|
|
|
| SOURCE filename '\n' { if (!srcdir) srcdir = $2; }
|
2012-03-11 04:57:44 +04:00
|
|
|
| BUILD filename '\n' { if (!builddir) builddir = $2; }
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* "machine foo" from std.whatever */
|
1995-04-28 10:54:58 +04:00
|
|
|
machine_spec:
|
2012-03-11 04:57:44 +04:00
|
|
|
XMACHINE WORD '\n' { setmachine($2,NULL,NULL,0); }
|
2012-03-11 06:21:04 +04:00
|
|
|
| XMACHINE WORD WORD '\n' { setmachine($2,$3,NULL,0); }
|
|
|
|
| XMACHINE WORD WORD subarches '\n' { setmachine($2,$3,$4,0); }
|
2012-03-11 04:57:44 +04:00
|
|
|
| IOCONF WORD '\n' { setmachine($2,NULL,NULL,1); }
|
|
|
|
| error { stop("cannot proceed without machine or ioconf specifier"); }
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 06:21:04 +04:00
|
|
|
/* One or more sub-arches. */
|
2001-06-08 16:47:06 +04:00
|
|
|
subarches:
|
2012-03-11 05:09:42 +04:00
|
|
|
WORD { $$ = new_n($1); }
|
|
|
|
| subarches WORD { $$ = new_nx($2, $1); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2016-08-07 13:37:24 +03:00
|
|
|
no:
|
|
|
|
NO { $$ = 0; }
|
|
|
|
| CNO { $$ = 1; }
|
|
|
|
;
|
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/************************************************************/
|
|
|
|
|
1995-04-28 10:54:58 +04:00
|
|
|
/*
|
|
|
|
* The machine definitions grammar.
|
|
|
|
*/
|
2012-03-11 04:14:20 +04:00
|
|
|
|
|
|
|
/* Complete definition part: the contents of all files.* files. */
|
2012-03-11 06:21:04 +04:00
|
|
|
definition_part:
|
2020-07-27 01:40:52 +03:00
|
|
|
definitions ENDDEFS {
|
|
|
|
CFGDBG(1, "ENDDEFS");
|
|
|
|
check_maxpart();
|
|
|
|
check_version();
|
|
|
|
}
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 06:21:04 +04:00
|
|
|
/* Zero or more definitions. Trap errors. */
|
|
|
|
definitions:
|
|
|
|
/* empty */
|
|
|
|
| definitions '\n'
|
2012-03-11 11:27:02 +04:00
|
|
|
| definitions definition '\n' { wrap_continue(); }
|
|
|
|
| definitions error '\n' { wrap_cleanup(); }
|
2012-03-11 06:21:04 +04:00
|
|
|
| definitions ENDFILE { enddefs(); checkfiles(); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* A single definition. */
|
2012-03-11 06:21:04 +04:00
|
|
|
definition:
|
2014-10-09 13:39:24 +04:00
|
|
|
define_file
|
|
|
|
| define_object
|
|
|
|
| define_device_major
|
|
|
|
| define_prefix
|
2015-09-01 16:42:48 +03:00
|
|
|
| define_buildprefix
|
2014-10-09 13:39:24 +04:00
|
|
|
| define_devclass
|
|
|
|
| define_filesystems
|
|
|
|
| define_attribute
|
|
|
|
| define_option
|
|
|
|
| define_flag
|
|
|
|
| define_obsolete_flag
|
|
|
|
| define_param
|
|
|
|
| define_obsolete_param
|
|
|
|
| define_device
|
|
|
|
| define_device_attachment
|
|
|
|
| define_maxpartitions
|
|
|
|
| define_maxusers
|
|
|
|
| define_makeoptions
|
|
|
|
| define_pseudo
|
|
|
|
| define_pseudodev
|
|
|
|
| define_major
|
|
|
|
| define_version
|
|
|
|
;
|
|
|
|
|
|
|
|
/* source file: file foo/bar.c bar|baz needs-flag compile-with blah */
|
|
|
|
define_file:
|
2015-08-29 05:54:07 +03:00
|
|
|
XFILE filename fopts fflags rule { addfile($2, $3, $4, $5); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
/* object file: object zot.o foo|zot needs-flag */
|
|
|
|
define_object:
|
2015-09-01 14:22:59 +03:00
|
|
|
XOBJECT filename fopts oflags { addfile($2, $3, $4, NULL); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
/* device major declaration */
|
|
|
|
define_device_major:
|
|
|
|
DEVICE_MAJOR WORD device_major_char device_major_block fopts devnodes
|
|
|
|
{
|
|
|
|
adddevm($2, $3, $4, $5, $6);
|
|
|
|
do_devsw = 1;
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
/* prefix delimiter */
|
|
|
|
define_prefix:
|
|
|
|
PREFIX filename { prefix_push($2); }
|
|
|
|
| PREFIX { prefix_pop(); }
|
|
|
|
;
|
|
|
|
|
2015-09-01 16:42:48 +03:00
|
|
|
define_buildprefix:
|
|
|
|
BUILDPREFIX filename { buildprefix_push($2); }
|
|
|
|
| BUILDPREFIX WORD { buildprefix_push($2); }
|
|
|
|
| BUILDPREFIX { buildprefix_pop(); }
|
|
|
|
;
|
|
|
|
|
2014-10-09 13:39:24 +04:00
|
|
|
define_devclass:
|
2014-10-10 10:13:30 +04:00
|
|
|
DEVCLASS WORD { (void)defdevclass($2, NULL, NULL, 1); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_filesystems:
|
|
|
|
DEFFS deffses optdepend_list { deffilesystem($2, $3); }
|
|
|
|
;
|
|
|
|
|
|
|
|
define_attribute:
|
|
|
|
DEFINE WORD interface_opt depend_list
|
2014-10-10 10:13:30 +04:00
|
|
|
{ (void)defattr0($2, $3, $4, 0); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_option:
|
|
|
|
DEFOPT optfile_opt defopts optdepend_list
|
2012-03-11 04:57:44 +04:00
|
|
|
{ defoption($2, $3, $4); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_flag:
|
|
|
|
DEFFLAG optfile_opt defopts optdepend_list
|
2012-03-11 04:57:44 +04:00
|
|
|
{ defflag($2, $3, $4, 0); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_obsolete_flag:
|
|
|
|
OBSOLETE DEFFLAG optfile_opt defopts
|
2012-03-11 04:57:44 +04:00
|
|
|
{ defflag($3, $4, NULL, 1); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_param:
|
|
|
|
DEFPARAM optfile_opt defopts optdepend_list
|
2012-03-11 04:57:44 +04:00
|
|
|
{ defparam($2, $3, $4, 0); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_obsolete_param:
|
|
|
|
OBSOLETE DEFPARAM optfile_opt defopts
|
2012-03-11 04:57:44 +04:00
|
|
|
{ defparam($3, $4, NULL, 1); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_device:
|
|
|
|
DEVICE devbase interface_opt depend_list
|
2012-03-11 04:57:44 +04:00
|
|
|
{ defdev($2, $3, $4, 0); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_device_attachment:
|
|
|
|
ATTACH devbase AT atlist devattach_opt depend_list
|
2012-03-11 04:57:44 +04:00
|
|
|
{ defdevattach($5, $2, $4, $6); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_maxpartitions:
|
2014-10-29 20:14:50 +03:00
|
|
|
MAXPARTITIONS int32 { maxpartitions = $2; }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_maxusers:
|
2014-10-29 20:14:50 +03:00
|
|
|
MAXUSERS int32 int32 int32
|
|
|
|
{ setdefmaxusers($2, $3, $4); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_makeoptions:
|
|
|
|
MAKEOPTIONS condmkopt_list
|
|
|
|
;
|
|
|
|
|
|
|
|
define_pseudo:
|
2008-06-10 22:11:31 +04:00
|
|
|
/* interface_opt in DEFPSEUDO is for backwards compatibility */
|
2014-10-09 13:39:24 +04:00
|
|
|
DEFPSEUDO devbase interface_opt depend_list
|
2012-03-11 04:57:44 +04:00
|
|
|
{ defdev($2, $3, $4, 1); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
define_pseudodev:
|
|
|
|
DEFPSEUDODEV devbase interface_opt depend_list
|
2012-03-11 04:57:44 +04:00
|
|
|
{ defdev($2, $3, $4, 2); }
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2014-10-09 13:39:24 +04:00
|
|
|
define_major:
|
|
|
|
MAJOR '{' majorlist '}'
|
|
|
|
;
|
|
|
|
|
|
|
|
define_version:
|
2014-10-29 20:14:50 +03:00
|
|
|
VERSION int32 { setversion($2); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 11:46:47 +04:00
|
|
|
/* file options: optional expression of conditions */
|
2012-03-11 06:43:33 +04:00
|
|
|
fopts:
|
|
|
|
/* empty */ { $$ = NULL; }
|
2012-03-11 11:46:47 +04:00
|
|
|
| condexpr { $$ = $1; }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* zero or more flags for a file */
|
2012-03-11 23:27:26 +04:00
|
|
|
fflags:
|
2012-03-11 06:43:33 +04:00
|
|
|
/* empty */ { $$ = 0; }
|
2012-03-11 23:27:26 +04:00
|
|
|
| fflags fflag { $$ = $1 | $2; }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1998-02-19 03:27:00 +03:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* one flag for a file */
|
|
|
|
fflag:
|
|
|
|
NEEDS_COUNT { $$ = FI_NEEDSCOUNT; }
|
|
|
|
| NEEDS_FLAG { $$ = FI_NEEDSFLAG; }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1998-02-19 03:27:00 +03:00
|
|
|
|
2015-08-29 05:54:07 +03:00
|
|
|
/* extra compile directive for a source file */
|
|
|
|
rule:
|
|
|
|
/* empty */ { $$ = NULL; }
|
|
|
|
| COMPILE_WITH stringvalue { $$ = $2; }
|
|
|
|
;
|
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* zero or more flags for an object file */
|
2012-03-11 23:27:26 +04:00
|
|
|
oflags:
|
2012-03-11 06:43:33 +04:00
|
|
|
/* empty */ { $$ = 0; }
|
2012-03-11 23:27:26 +04:00
|
|
|
| oflags oflag { $$ = $1 | $2; }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
2002-10-11 05:48:25 +04:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* a single flag for an object file */
|
|
|
|
oflag:
|
2015-09-01 14:22:59 +03:00
|
|
|
NEEDS_FLAG { $$ = FI_NEEDSFLAG; }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1998-01-12 10:37:40 +03:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* char 55 */
|
|
|
|
device_major_char:
|
|
|
|
/* empty */ { $$ = -1; }
|
2014-10-29 20:14:50 +03:00
|
|
|
| CHAR int32 { $$ = $2; }
|
2012-03-11 06:43:33 +04:00
|
|
|
;
|
2012-03-11 04:57:44 +04:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* block 33 */
|
|
|
|
device_major_block:
|
|
|
|
/* empty */ { $$ = -1; }
|
2014-10-29 20:14:50 +03:00
|
|
|
| BLOCK int32 { $$ = $2; }
|
2012-03-11 06:43:33 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
/* device node specification */
|
|
|
|
devnodes:
|
|
|
|
/* empty */ { $$ = new_s("DEVNODE_DONTBOTHER"); }
|
|
|
|
| devnodetype ',' devnodeflags { $$ = nvcat($1, $3); }
|
|
|
|
| devnodetype { $$ = $1; }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* device nodes without flags */
|
|
|
|
devnodetype:
|
|
|
|
SINGLE { $$ = new_s("DEVNODE_SINGLE"); }
|
|
|
|
| VECTOR '=' devnode_dims { $$ = nvcat(new_s("DEVNODE_VECTOR"), $3); }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* dimensions (?) */
|
|
|
|
devnode_dims:
|
|
|
|
NUMBER { $$ = new_i($1.val); }
|
|
|
|
| NUMBER ':' NUMBER {
|
|
|
|
struct nvlist *__nv1, *__nv2;
|
|
|
|
|
|
|
|
__nv1 = new_i($1.val);
|
|
|
|
__nv2 = new_i($3.val);
|
|
|
|
$$ = nvcat(__nv1, __nv2);
|
2012-03-11 04:57:44 +04:00
|
|
|
}
|
|
|
|
;
|
1998-01-12 10:37:40 +03:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* flags for device nodes */
|
|
|
|
devnodeflags:
|
|
|
|
LINKZERO { $$ = new_s("DEVNODE_FLAG_LINKZERO");}
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* one or more file system names */
|
|
|
|
deffses:
|
|
|
|
deffs { $$ = new_n($1); }
|
|
|
|
| deffses deffs { $$ = new_nx($2, $1); }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* a single file system name */
|
|
|
|
deffs:
|
|
|
|
WORD { $$ = $1; }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1996-03-17 05:08:22 +03:00
|
|
|
|
2012-03-11 06:21:04 +04:00
|
|
|
/* optional locator specification */
|
1995-04-28 10:54:58 +04:00
|
|
|
interface_opt:
|
2012-03-11 04:57:44 +04:00
|
|
|
/* empty */ { $$ = NULL; }
|
2012-03-12 01:16:07 +04:00
|
|
|
| '{' '}' { $$ = present_loclist(NULL); }
|
|
|
|
| '{' loclist '}' { $$ = present_loclist($2); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/*
|
|
|
|
* loclist order matters, must use right recursion
|
|
|
|
* XXX wot?
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* list of locator definitions */
|
1995-04-28 10:54:58 +04:00
|
|
|
loclist:
|
2012-03-11 04:57:44 +04:00
|
|
|
locdef { $$ = $1; }
|
|
|
|
| locdef ',' loclist { $$ = $1; app($1, $3); }
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/*
|
|
|
|
* "[ WORD locdefault ]" syntax may be unnecessary...
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* one locator definition */
|
1995-04-28 10:54:58 +04:00
|
|
|
locdef:
|
2012-03-12 01:16:07 +04:00
|
|
|
locname locdefault { $$ = MK3(loc, $1, $2, 0); }
|
|
|
|
| locname { $$ = MK3(loc, $1, NULL, 0); }
|
|
|
|
| '[' locname locdefault ']' { $$ = MK3(loc, $2, $3, 1); }
|
2014-10-29 20:14:50 +03:00
|
|
|
| locname '[' int32 ']' { $$ = locarray($1, $3, NULL, 0); }
|
|
|
|
| locname '[' int32 ']' locdefaults
|
|
|
|
{ $$ = locarray($1, $3, $5, 0); }
|
|
|
|
| '[' locname '[' int32 ']' locdefaults ']'
|
|
|
|
{ $$ = locarray($2, $4, $6, 1); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* locator name */
|
Revise handling of pathnames and quoted strings. Previously, some
filenames had to be unquoted and also had to contain a / or .,
while others had to have no / and no . or be quoted, whereas
arbitrary machine symbols could always be optionally quoted,
which was kind of backwards.
Now, all filesnames use the same rules: quoted, or with a / or .
Arbitrary words can no longer be quoted unless the grammar specifically
allows it, which it now does for filenames, locator values, locator
defaults, compile-with, ident, makeoptions, and options.
Also, locator name symbols can be quoted, so mac68k's "no drq" locator
still works. ("no drq" doesn't appear in any machine description so I
presume it's just for the dmesg. )
2002-06-22 06:09:12 +04:00
|
|
|
locname:
|
2012-03-11 04:57:44 +04:00
|
|
|
WORD { $$ = $1; }
|
|
|
|
| QSTRING { $$ = $1; }
|
|
|
|
;
|
Revise handling of pathnames and quoted strings. Previously, some
filenames had to be unquoted and also had to contain a / or .,
while others had to have no / and no . or be quoted, whereas
arbitrary machine symbols could always be optionally quoted,
which was kind of backwards.
Now, all filesnames use the same rules: quoted, or with a / or .
Arbitrary words can no longer be quoted unless the grammar specifically
allows it, which it now does for filenames, locator values, locator
defaults, compile-with, ident, makeoptions, and options.
Also, locator name symbols can be quoted, so mac68k's "no drq" locator
still works. ("no drq" doesn't appear in any machine description so I
presume it's just for the dmesg. )
2002-06-22 06:09:12 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* locator default value */
|
1995-04-28 10:54:58 +04:00
|
|
|
locdefault:
|
2012-03-11 04:57:44 +04:00
|
|
|
'=' value { $$ = $2; }
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* multiple locator default values */
|
1999-01-21 16:10:08 +03:00
|
|
|
locdefaults:
|
2012-03-11 04:57:44 +04:00
|
|
|
'=' '{' values '}' { $$ = $3; }
|
|
|
|
;
|
1999-01-21 16:10:08 +03:00
|
|
|
|
2012-03-11 11:46:47 +04:00
|
|
|
/* list of depends, may be empty */
|
|
|
|
depend_list:
|
2012-03-11 04:57:44 +04:00
|
|
|
/* empty */ { $$ = NULL; }
|
2012-03-11 11:46:47 +04:00
|
|
|
| ':' depends { $$ = $2; }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1998-01-12 10:37:40 +03:00
|
|
|
|
2012-03-11 11:46:47 +04:00
|
|
|
/* one or more depend items */
|
|
|
|
depends:
|
|
|
|
depend { $$ = MK2(attrlist, NULL, $1); }
|
|
|
|
| depends ',' depend { $$ = MK2(attrlist, $1, $3); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
Revise handling of pathnames and quoted strings. Previously, some
filenames had to be unquoted and also had to contain a / or .,
while others had to have no / and no . or be quoted, whereas
arbitrary machine symbols could always be optionally quoted,
which was kind of backwards.
Now, all filesnames use the same rules: quoted, or with a / or .
Arbitrary words can no longer be quoted unless the grammar specifically
allows it, which it now does for filenames, locator values, locator
defaults, compile-with, ident, makeoptions, and options.
Also, locator name symbols can be quoted, so mac68k's "no drq" locator
still works. ("no drq" doesn't appear in any machine description so I
presume it's just for the dmesg. )
2002-06-22 06:09:12 +04:00
|
|
|
|
2012-03-11 11:46:47 +04:00
|
|
|
/* one depend item (which is an attribute) */
|
|
|
|
depend:
|
2014-10-10 15:09:50 +04:00
|
|
|
WORD { $$ = refattr($1); }
|
2012-03-11 06:43:33 +04:00
|
|
|
;
|
2012-03-11 04:57:44 +04:00
|
|
|
|
2012-03-11 23:27:26 +04:00
|
|
|
/* list of option depends, may be empty */
|
|
|
|
optdepend_list:
|
|
|
|
/* empty */ { $$ = NULL; }
|
|
|
|
| ':' optdepends { $$ = $2; }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* a list of option dependencies */
|
|
|
|
optdepends:
|
|
|
|
optdepend { $$ = new_n($1); }
|
|
|
|
| optdepends ',' optdepend { $$ = new_nx($3, $1); }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* one option depend, which is an option name */
|
|
|
|
optdepend:
|
|
|
|
WORD { $$ = $1; }
|
|
|
|
;
|
|
|
|
|
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* list of places to attach: attach blah at ... */
|
|
|
|
atlist:
|
|
|
|
atname { $$ = new_n($1); }
|
|
|
|
| atlist ',' atname { $$ = new_nx($3, $1); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* a place to attach a device */
|
|
|
|
atname:
|
|
|
|
WORD { $$ = $1; }
|
|
|
|
| ROOT { $$ = NULL; }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
Revise handling of pathnames and quoted strings. Previously, some
filenames had to be unquoted and also had to contain a / or .,
while others had to have no / and no . or be quoted, whereas
arbitrary machine symbols could always be optionally quoted,
which was kind of backwards.
Now, all filesnames use the same rules: quoted, or with a / or .
Arbitrary words can no longer be quoted unless the grammar specifically
allows it, which it now does for filenames, locator values, locator
defaults, compile-with, ident, makeoptions, and options.
Also, locator name symbols can be quoted, so mac68k's "no drq" locator
still works. ("no drq" doesn't appear in any machine description so I
presume it's just for the dmesg. )
2002-06-22 06:09:12 +04:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* one or more defined options */
|
|
|
|
defopts:
|
|
|
|
defopt { $$ = $1; }
|
2012-03-12 06:58:55 +04:00
|
|
|
| defopts defopt { $$ = defoptlist_append($2, $1); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1999-01-21 16:10:08 +03:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* one defined option */
|
|
|
|
defopt:
|
2012-03-12 06:58:55 +04:00
|
|
|
WORD { $$ = MK3(defoptlist, $1, NULL, NULL); }
|
|
|
|
| WORD '=' value { $$ = MK3(defoptlist, $1, $3, NULL); }
|
|
|
|
| WORD COLONEQ value { $$ = MK3(defoptlist, $1, NULL, $3); }
|
|
|
|
| WORD '=' value COLONEQ value { $$ = MK3(defoptlist, $1, $3, $5); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* list of conditional makeoptions */
|
|
|
|
condmkopt_list:
|
|
|
|
condmkoption
|
|
|
|
| condmkopt_list ',' condmkoption
|
|
|
|
;
|
|
|
|
|
|
|
|
/* one conditional make option */
|
|
|
|
condmkoption:
|
2012-03-11 11:46:47 +04:00
|
|
|
condexpr mkvarname PLUSEQ value { appendcondmkoption($1, $2, $4); }
|
2012-03-11 06:43:33 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
/* device name */
|
|
|
|
devbase:
|
|
|
|
WORD { $$ = getdevbase($1); }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* optional attachment: with foo */
|
|
|
|
devattach_opt:
|
|
|
|
/* empty */ { $$ = NULL; }
|
|
|
|
| WITH WORD { $$ = getdevattach($2); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* list of major numbers */
|
|
|
|
/* XXX why is this right-recursive? */
|
1995-04-28 10:54:58 +04:00
|
|
|
majorlist:
|
2012-03-11 04:57:44 +04:00
|
|
|
majordef
|
|
|
|
| majorlist ',' majordef
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* one major number */
|
1995-04-28 10:54:58 +04:00
|
|
|
majordef:
|
2014-10-29 20:14:50 +03:00
|
|
|
devbase '=' int32 { setmajor($1, $3); }
|
|
|
|
;
|
|
|
|
|
|
|
|
int32:
|
|
|
|
NUMBER {
|
|
|
|
if ($1.val > INT_MAX || $1.val < INT_MIN)
|
|
|
|
cfgerror("overflow %" PRId64, $1.val);
|
|
|
|
else
|
|
|
|
$$ = (int32_t)$1.val;
|
|
|
|
}
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/************************************************************/
|
1995-04-28 10:54:58 +04:00
|
|
|
|
|
|
|
/*
|
2014-10-09 11:05:01 +04:00
|
|
|
* The selection grammar.
|
1995-04-28 10:54:58 +04:00
|
|
|
*/
|
2012-03-11 04:14:20 +04:00
|
|
|
|
2014-10-09 11:05:01 +04:00
|
|
|
/* Complete selection part: all std.* files plus selected config. */
|
|
|
|
selection_part:
|
|
|
|
selections
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 06:21:04 +04:00
|
|
|
/* Zero or more config items. Trap errors. */
|
2014-10-09 11:05:01 +04:00
|
|
|
selections:
|
2012-03-11 06:21:04 +04:00
|
|
|
/* empty */
|
2014-10-09 11:05:01 +04:00
|
|
|
| selections '\n'
|
|
|
|
| selections selection '\n' { wrap_continue(); }
|
2014-10-09 13:39:24 +04:00
|
|
|
| selections error '\n' { wrap_cleanup(); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* One config item. */
|
2014-10-09 11:05:01 +04:00
|
|
|
selection:
|
2012-03-11 06:21:04 +04:00
|
|
|
definition
|
2014-10-31 10:38:36 +03:00
|
|
|
| select_attr
|
|
|
|
| select_no_attr
|
2014-10-09 13:39:24 +04:00
|
|
|
| select_no_filesystems
|
|
|
|
| select_filesystems
|
|
|
|
| select_no_makeoptions
|
|
|
|
| select_makeoptions
|
|
|
|
| select_no_options
|
|
|
|
| select_options
|
|
|
|
| select_maxusers
|
|
|
|
| select_ident
|
|
|
|
| select_no_ident
|
|
|
|
| select_config
|
|
|
|
| select_no_config
|
|
|
|
| select_no_pseudodev
|
|
|
|
| select_pseudodev
|
|
|
|
| select_pseudoroot
|
|
|
|
| select_no_device_instance_attachment
|
|
|
|
| select_no_device_attachment
|
|
|
|
| select_no_device_instance
|
|
|
|
| select_device_instance
|
|
|
|
;
|
|
|
|
|
2014-10-31 10:38:36 +03:00
|
|
|
select_attr:
|
|
|
|
SELECT WORD { addattr($2); }
|
|
|
|
;
|
|
|
|
|
|
|
|
select_no_attr:
|
2016-08-07 13:37:24 +03:00
|
|
|
no SELECT WORD { delattr($3, $1); }
|
2014-10-31 10:38:36 +03:00
|
|
|
;
|
|
|
|
|
2014-10-09 13:39:24 +04:00
|
|
|
select_no_filesystems:
|
2016-08-07 13:37:24 +03:00
|
|
|
no FILE_SYSTEM { nowarn = $1; } no_fs_list { nowarn = 0; }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
select_filesystems:
|
|
|
|
FILE_SYSTEM fs_list
|
|
|
|
;
|
|
|
|
|
|
|
|
select_no_makeoptions:
|
2016-08-07 13:37:24 +03:00
|
|
|
no MAKEOPTIONS { nowarn = $1; } no_mkopt_list { nowarn = 0; }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
select_makeoptions:
|
|
|
|
MAKEOPTIONS mkopt_list
|
|
|
|
;
|
|
|
|
|
|
|
|
select_no_options:
|
2016-08-07 13:37:24 +03:00
|
|
|
no OPTIONS { nowarn = $1; } no_opt_list { nowarn = 0; }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
select_options:
|
|
|
|
OPTIONS opt_list
|
|
|
|
;
|
|
|
|
|
|
|
|
select_maxusers:
|
2015-08-31 05:58:25 +03:00
|
|
|
MAXUSERS int32 { setmaxusers($2); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
select_ident:
|
|
|
|
IDENT stringvalue { setident($2); }
|
|
|
|
;
|
|
|
|
|
|
|
|
select_no_ident:
|
2016-08-07 13:37:24 +03:00
|
|
|
no IDENT { setident(NULL); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
select_config:
|
|
|
|
CONFIG conf root_spec sysparam_list
|
2012-03-11 04:57:44 +04:00
|
|
|
{ addconf(&conf); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
select_no_config:
|
2016-08-07 13:37:24 +03:00
|
|
|
no CONFIG WORD { delconf($3, $1); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
select_no_pseudodev:
|
2016-08-07 13:37:24 +03:00
|
|
|
no PSEUDO_DEVICE WORD { delpseudo($3, $1); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
select_pseudodev:
|
|
|
|
PSEUDO_DEVICE WORD npseudo { addpseudo($2, $3); }
|
|
|
|
;
|
|
|
|
|
|
|
|
select_pseudoroot:
|
|
|
|
PSEUDO_ROOT device_instance { addpseudoroot($2); }
|
|
|
|
;
|
|
|
|
|
|
|
|
select_no_device_instance_attachment:
|
2016-08-07 13:37:24 +03:00
|
|
|
no device_instance AT attachment
|
|
|
|
{ deldevi($2, $4, $1); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
select_no_device_attachment:
|
2016-08-07 13:37:24 +03:00
|
|
|
no DEVICE AT attachment { deldeva($4, $1); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
select_no_device_instance:
|
2016-08-07 13:37:24 +03:00
|
|
|
no device_instance { deldev($2, $1); }
|
2014-10-09 13:39:24 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
select_device_instance:
|
|
|
|
device_instance AT attachment locators device_flags
|
2012-03-11 04:57:44 +04:00
|
|
|
{ adddev($1, $3, $4, $5); }
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* list of filesystems */
|
2002-06-05 14:56:17 +04:00
|
|
|
fs_list:
|
2012-03-11 04:57:44 +04:00
|
|
|
fsoption
|
|
|
|
| fs_list ',' fsoption
|
|
|
|
;
|
2002-06-05 14:56:17 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* one filesystem */
|
2002-06-05 14:56:17 +04:00
|
|
|
fsoption:
|
2012-03-11 04:57:44 +04:00
|
|
|
WORD { addfsoption($1); }
|
|
|
|
;
|
2002-06-05 14:56:17 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* list of filesystems that had NO in front */
|
2002-06-05 14:56:17 +04:00
|
|
|
no_fs_list:
|
2012-03-11 04:57:44 +04:00
|
|
|
no_fsoption
|
|
|
|
| no_fs_list ',' no_fsoption
|
|
|
|
;
|
2002-06-05 14:56:17 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* one filesystem that had NO in front */
|
2002-06-05 14:56:17 +04:00
|
|
|
no_fsoption:
|
2016-08-07 13:37:24 +03:00
|
|
|
WORD { delfsoption($1, nowarn); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
2002-06-05 14:56:17 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* list of make options */
|
|
|
|
/* XXX why is this right-recursive? */
|
1995-04-28 10:54:58 +04:00
|
|
|
mkopt_list:
|
2012-03-11 04:57:44 +04:00
|
|
|
mkoption
|
|
|
|
| mkopt_list ',' mkoption
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* one make option */
|
1995-04-28 10:54:58 +04:00
|
|
|
mkoption:
|
2012-03-11 04:57:44 +04:00
|
|
|
mkvarname '=' value { addmkoption($1, $3); }
|
|
|
|
| mkvarname PLUSEQ value { appendmkoption($1, $3); }
|
|
|
|
;
|
2004-06-05 07:21:53 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* list of make options that had NO in front */
|
2002-06-05 14:56:17 +04:00
|
|
|
no_mkopt_list:
|
2012-03-11 04:57:44 +04:00
|
|
|
no_mkoption
|
|
|
|
| no_mkopt_list ',' no_mkoption
|
|
|
|
;
|
2002-06-05 14:56:17 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* one make option that had NO in front */
|
2012-03-11 06:43:33 +04:00
|
|
|
/* XXX shouldn't this be mkvarname rather than WORD? */
|
2002-06-05 14:56:17 +04:00
|
|
|
no_mkoption:
|
2016-08-07 13:37:24 +03:00
|
|
|
WORD { delmkoption($1, nowarn); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
2002-06-05 14:56:17 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* list of options */
|
1995-04-28 10:54:58 +04:00
|
|
|
opt_list:
|
2012-03-11 04:57:44 +04:00
|
|
|
option
|
|
|
|
| opt_list ',' option
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* one option */
|
1995-04-28 10:54:58 +04:00
|
|
|
option:
|
2012-03-11 04:57:44 +04:00
|
|
|
WORD { addoption($1, NULL); }
|
|
|
|
| WORD '=' value { addoption($1, $3); }
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* list of options that had NO in front */
|
2002-06-05 14:56:17 +04:00
|
|
|
no_opt_list:
|
2012-03-11 04:57:44 +04:00
|
|
|
no_option
|
|
|
|
| no_opt_list ',' no_option
|
|
|
|
;
|
1997-01-31 06:12:30 +03:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* one option that had NO in front */
|
2002-06-05 14:56:17 +04:00
|
|
|
no_option:
|
2016-08-07 13:37:24 +03:00
|
|
|
WORD { deloption($1, nowarn); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1997-01-31 06:12:30 +03:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* the name in "config name root on ..." */
|
1995-04-28 10:54:58 +04:00
|
|
|
conf:
|
2012-03-11 04:57:44 +04:00
|
|
|
WORD {
|
|
|
|
conf.cf_name = $1;
|
2020-03-07 22:26:13 +03:00
|
|
|
conf.cf_where.w_srcline = currentline();
|
2012-03-11 04:57:44 +04:00
|
|
|
conf.cf_fstype = NULL;
|
|
|
|
conf.cf_root = NULL;
|
|
|
|
conf.cf_dump = NULL;
|
|
|
|
}
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* root fs specification */
|
1997-01-31 06:12:30 +03:00
|
|
|
root_spec:
|
2012-03-11 06:21:04 +04:00
|
|
|
ROOT on_opt dev_spec { setconf(&conf.cf_root, "root", $3); }
|
|
|
|
| ROOT on_opt dev_spec fs_spec { setconf(&conf.cf_root, "root", $3); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1997-01-31 06:12:30 +03:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/* device for root fs or dump */
|
|
|
|
dev_spec:
|
2016-04-29 21:18:22 +03:00
|
|
|
'?' { $$ = new_spi(intern("?"),
|
|
|
|
NULL,
|
2014-10-29 20:14:50 +03:00
|
|
|
(long long)NODEV); }
|
2016-04-29 21:18:22 +03:00
|
|
|
| QSTRING { $$ = new_spi($1,
|
|
|
|
__UNCONST("spec"),
|
|
|
|
(long long)NODEV); }
|
|
|
|
| WORD { $$ = new_spi($1,
|
|
|
|
NULL,
|
2014-10-29 20:14:50 +03:00
|
|
|
(long long)NODEV); }
|
2012-03-11 06:43:33 +04:00
|
|
|
| major_minor { $$ = new_si(NULL, $1); }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* major and minor device number */
|
|
|
|
major_minor:
|
2014-11-05 02:01:23 +03:00
|
|
|
MAJOR NUMBER MINOR NUMBER { $$ = (int64_t)makedev($2.val, $4.val); }
|
2012-03-11 06:43:33 +04:00
|
|
|
;
|
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* filesystem type for root fs specification */
|
1997-01-31 06:12:30 +03:00
|
|
|
fs_spec:
|
2012-03-11 06:21:04 +04:00
|
|
|
TYPE '?' { setfstype(&conf.cf_fstype, intern("?")); }
|
|
|
|
| TYPE WORD { setfstype(&conf.cf_fstype, $2); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1997-01-31 06:12:30 +03:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* zero or more additional system parameters */
|
1995-04-28 10:54:58 +04:00
|
|
|
sysparam_list:
|
2012-03-11 04:57:44 +04:00
|
|
|
/* empty */
|
|
|
|
| sysparam_list sysparam
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* one additional system parameter (there's only one: dumps) */
|
1995-04-28 10:54:58 +04:00
|
|
|
sysparam:
|
2012-03-11 04:57:44 +04:00
|
|
|
DUMPS on_opt dev_spec { setconf(&conf.cf_dump, "dumps", $3); }
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* number of pseudo devices to configure (which is optional) */
|
1995-04-28 10:54:58 +04:00
|
|
|
npseudo:
|
2012-03-11 04:57:44 +04:00
|
|
|
/* empty */ { $$ = 1; }
|
2014-10-29 20:14:50 +03:00
|
|
|
| int32 { $$ = $1; }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* name of a device to configure */
|
1995-04-28 10:54:58 +04:00
|
|
|
device_instance:
|
2012-03-11 04:57:44 +04:00
|
|
|
WORD { $$ = $1; }
|
|
|
|
| WORD '*' { $$ = starref($1); }
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* name of a device to configure an attachment to */
|
1995-04-28 10:54:58 +04:00
|
|
|
attachment:
|
2012-03-11 04:57:44 +04:00
|
|
|
ROOT { $$ = NULL; }
|
|
|
|
| WORD { $$ = $1; }
|
|
|
|
| WORD '?' { $$ = wildref($1); }
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* zero or more locators */
|
1995-04-28 10:54:58 +04:00
|
|
|
locators:
|
2012-03-11 04:57:44 +04:00
|
|
|
/* empty */ { $$ = NULL; }
|
|
|
|
| locators locator { $$ = $2; app($2, $1); }
|
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* one locator */
|
1995-04-28 10:54:58 +04:00
|
|
|
locator:
|
2012-03-12 01:16:07 +04:00
|
|
|
WORD '?' { $$ = MK3(loc, $1, NULL, 0); }
|
|
|
|
| WORD values { $$ = namelocvals($1, $2); }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 04:14:20 +04:00
|
|
|
/* optional device flags */
|
2012-03-11 06:21:04 +04:00
|
|
|
device_flags:
|
2012-03-11 04:57:44 +04:00
|
|
|
/* empty */ { $$ = 0; }
|
2014-10-29 20:14:50 +03:00
|
|
|
| FLAGS int32 { $$ = $2; }
|
2012-03-11 04:57:44 +04:00
|
|
|
;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 06:43:33 +04:00
|
|
|
/************************************************************/
|
|
|
|
|
|
|
|
/*
|
2012-03-11 11:46:47 +04:00
|
|
|
* conditions
|
2012-03-11 06:43:33 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* order of options is important, must use right recursion
|
|
|
|
*
|
|
|
|
* dholland 20120310: wut?
|
|
|
|
*/
|
|
|
|
|
2012-03-11 11:46:47 +04:00
|
|
|
/* expression of conditions */
|
|
|
|
condexpr:
|
|
|
|
cond_or_expr
|
2012-03-11 06:56:25 +04:00
|
|
|
;
|
|
|
|
|
2012-03-11 11:46:47 +04:00
|
|
|
cond_or_expr:
|
|
|
|
cond_and_expr
|
2012-03-11 12:21:53 +04:00
|
|
|
| cond_or_expr '|' cond_and_expr { $$ = MKF2(cx, or, $1, $3); }
|
2012-03-11 06:56:25 +04:00
|
|
|
;
|
|
|
|
|
2012-03-11 11:46:47 +04:00
|
|
|
cond_and_expr:
|
|
|
|
cond_prefix_expr
|
2012-03-11 12:21:53 +04:00
|
|
|
| cond_and_expr '&' cond_prefix_expr { $$ = MKF2(cx, and, $1, $3); }
|
2012-03-11 06:56:25 +04:00
|
|
|
;
|
|
|
|
|
2012-03-11 11:46:47 +04:00
|
|
|
cond_prefix_expr:
|
|
|
|
cond_base_expr
|
2012-03-11 06:56:25 +04:00
|
|
|
/* XXX notyet - need to strengthen downstream first */
|
2012-03-11 12:21:53 +04:00
|
|
|
/* | '!' cond_prefix_expr { $$ = MKF1(cx, not, $2); } */
|
2012-03-11 06:56:25 +04:00
|
|
|
;
|
|
|
|
|
2012-03-11 11:46:47 +04:00
|
|
|
cond_base_expr:
|
|
|
|
condatom { $$ = $1; }
|
2012-03-11 12:21:53 +04:00
|
|
|
| '!' condatom { $$ = MKF1(cx, not, $2); }
|
2012-03-11 11:46:47 +04:00
|
|
|
| '(' condexpr ')' { $$ = $2; }
|
2012-03-11 06:43:33 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
/* basic element of config element expression: a config element */
|
2012-03-11 11:46:47 +04:00
|
|
|
condatom:
|
2012-03-11 12:21:53 +04:00
|
|
|
WORD { $$ = MKF1(cx, atom, $1); }
|
2012-03-11 06:43:33 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
/************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Various nonterminals shared between the grammars.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* variable name for make option */
|
|
|
|
mkvarname:
|
|
|
|
QSTRING { $$ = $1; }
|
|
|
|
| WORD { $$ = $1; }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* optional file for an option */
|
|
|
|
optfile_opt:
|
|
|
|
/* empty */ { $$ = NULL; }
|
|
|
|
| filename { $$ = $1; }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* filename. */
|
|
|
|
filename:
|
|
|
|
QSTRING { $$ = $1; }
|
|
|
|
| PATHNAME { $$ = $1; }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* constant value */
|
|
|
|
value:
|
|
|
|
QSTRING { $$ = $1; }
|
|
|
|
| WORD { $$ = $1; }
|
|
|
|
| EMPTYSTRING { $$ = $1; }
|
|
|
|
| signed_number {
|
|
|
|
char bf[40];
|
|
|
|
|
|
|
|
(void)snprintf(bf, sizeof(bf), FORMAT($1), (long long)$1.val);
|
|
|
|
$$ = intern(bf);
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
/* constant value that is a string */
|
|
|
|
stringvalue:
|
|
|
|
QSTRING { $$ = $1; }
|
|
|
|
| WORD { $$ = $1; }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* comma-separated list of values */
|
|
|
|
/* XXX why right-recursive? */
|
|
|
|
values:
|
2012-03-12 01:16:07 +04:00
|
|
|
value { $$ = MKF2(loc, val, $1, NULL); }
|
|
|
|
| value ',' values { $$ = MKF2(loc, val, $1, $3); }
|
2012-03-11 06:43:33 +04:00
|
|
|
;
|
|
|
|
|
|
|
|
/* possibly negative number */
|
|
|
|
signed_number:
|
|
|
|
NUMBER { $$ = $1; }
|
|
|
|
| '-' NUMBER { $$.fmt = $2.fmt; $$.val = -$2.val; }
|
|
|
|
;
|
|
|
|
|
|
|
|
/* optional ON keyword */
|
|
|
|
on_opt:
|
|
|
|
/* empty */
|
|
|
|
| ON
|
|
|
|
;
|
|
|
|
|
1995-04-28 10:54:58 +04:00
|
|
|
%%
|
|
|
|
|
|
|
|
void
|
2000-10-02 23:48:34 +04:00
|
|
|
yyerror(const char *s)
|
1995-04-28 10:54:58 +04:00
|
|
|
{
|
|
|
|
|
2007-01-14 02:47:36 +03:00
|
|
|
cfgerror("%s", s);
|
1995-04-28 10:54:58 +04:00
|
|
|
}
|
|
|
|
|
2012-03-11 11:27:02 +04:00
|
|
|
/************************************************************/
|
|
|
|
|
1995-04-28 10:54:58 +04:00
|
|
|
/*
|
2012-03-11 11:27:02 +04:00
|
|
|
* Wrap allocations that live on the parser stack so that we can free
|
|
|
|
* them again on error instead of leaking.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define MAX_WRAP 1000
|
|
|
|
|
|
|
|
struct wrap_entry {
|
|
|
|
void *ptr;
|
|
|
|
unsigned typecode;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct wrap_entry wrapstack[MAX_WRAP];
|
|
|
|
static unsigned wrap_depth;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remember pointer PTR with type-code CODE.
|
1995-04-28 10:54:58 +04:00
|
|
|
*/
|
|
|
|
static void
|
2012-03-11 11:27:02 +04:00
|
|
|
wrap_alloc(void *ptr, unsigned code)
|
1995-04-28 10:54:58 +04:00
|
|
|
{
|
2012-03-11 11:27:02 +04:00
|
|
|
unsigned pos;
|
|
|
|
|
|
|
|
if (wrap_depth >= MAX_WRAP) {
|
|
|
|
panic("allocation wrapper stack overflow");
|
|
|
|
}
|
|
|
|
pos = wrap_depth++;
|
|
|
|
wrapstack[pos].ptr = ptr;
|
|
|
|
wrapstack[pos].typecode = code;
|
|
|
|
}
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2012-03-11 11:27:02 +04:00
|
|
|
/*
|
|
|
|
* We succeeded; commit to keeping everything that's been allocated so
|
|
|
|
* far and clear the stack.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
wrap_continue(void)
|
|
|
|
{
|
|
|
|
wrap_depth = 0;
|
1995-04-28 10:54:58 +04:00
|
|
|
}
|
|
|
|
|
2012-03-11 11:27:02 +04:00
|
|
|
/*
|
|
|
|
* We failed; destroy all the objects allocated.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
wrap_cleanup(void)
|
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
|
2012-03-12 01:16:07 +04:00
|
|
|
/*
|
|
|
|
* Destroy each item. Note that because everything allocated
|
|
|
|
* is entered on the list separately, lists and trees need to
|
|
|
|
* have their links blanked before being destroyed. Also note
|
|
|
|
* that strings are interned elsewhere and not handled by this
|
|
|
|
* mechanism.
|
|
|
|
*/
|
|
|
|
|
2012-03-11 11:27:02 +04:00
|
|
|
for (i=0; i<wrap_depth; i++) {
|
|
|
|
switch (wrapstack[i].typecode) {
|
|
|
|
case WRAP_CODE_nvlist:
|
|
|
|
nvfree(wrapstack[i].ptr);
|
|
|
|
break;
|
2012-03-12 06:58:55 +04:00
|
|
|
case WRAP_CODE_defoptlist:
|
|
|
|
{
|
|
|
|
struct defoptlist *dl = wrapstack[i].ptr;
|
|
|
|
|
|
|
|
dl->dl_next = NULL;
|
|
|
|
defoptlist_destroy(dl);
|
|
|
|
}
|
|
|
|
break;
|
2012-03-12 01:16:07 +04:00
|
|
|
case WRAP_CODE_loclist:
|
|
|
|
{
|
|
|
|
struct loclist *ll = wrapstack[i].ptr;
|
|
|
|
|
|
|
|
ll->ll_next = NULL;
|
|
|
|
loclist_destroy(ll);
|
|
|
|
}
|
|
|
|
break;
|
2012-03-11 11:32:41 +04:00
|
|
|
case WRAP_CODE_attrlist:
|
|
|
|
{
|
|
|
|
struct attrlist *al = wrapstack[i].ptr;
|
|
|
|
|
|
|
|
al->al_next = NULL;
|
|
|
|
al->al_this = NULL;
|
|
|
|
attrlist_destroy(al);
|
|
|
|
}
|
|
|
|
break;
|
2012-03-12 01:16:07 +04:00
|
|
|
case WRAP_CODE_condexpr:
|
|
|
|
{
|
|
|
|
struct condexpr *cx = wrapstack[i].ptr;
|
|
|
|
|
|
|
|
cx->cx_type = CX_ATOM;
|
|
|
|
cx->cx_atom = NULL;
|
|
|
|
condexpr_destroy(cx);
|
|
|
|
}
|
|
|
|
break;
|
2012-03-11 11:27:02 +04:00
|
|
|
default:
|
|
|
|
panic("invalid code %u on allocation wrapper stack",
|
|
|
|
wrapstack[i].typecode);
|
|
|
|
}
|
|
|
|
}
|
2012-03-11 11:32:41 +04:00
|
|
|
|
2012-03-11 11:27:02 +04:00
|
|
|
wrap_depth = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Instantiate the wrapper functions.
|
|
|
|
*
|
|
|
|
* Each one calls wrap_alloc to save the pointer and then returns the
|
|
|
|
* pointer again; these need to be generated with the preprocessor in
|
|
|
|
* order to be typesafe.
|
|
|
|
*/
|
|
|
|
#define DEF_ALLOCWRAP(t) \
|
|
|
|
static struct t * \
|
|
|
|
wrap_mk_##t(struct t *arg) \
|
|
|
|
{ \
|
|
|
|
wrap_alloc(arg, WRAP_CODE_##t); \
|
|
|
|
return arg; \
|
|
|
|
}
|
|
|
|
|
|
|
|
DEF_ALLOCWRAP(nvlist);
|
2012-03-12 06:58:55 +04:00
|
|
|
DEF_ALLOCWRAP(defoptlist);
|
2012-03-12 01:16:07 +04:00
|
|
|
DEF_ALLOCWRAP(loclist);
|
2012-03-11 11:32:41 +04:00
|
|
|
DEF_ALLOCWRAP(attrlist);
|
2012-03-11 12:21:53 +04:00
|
|
|
DEF_ALLOCWRAP(condexpr);
|
2012-03-11 11:32:41 +04:00
|
|
|
|
|
|
|
/************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Data constructors
|
2012-03-12 01:16:07 +04:00
|
|
|
*
|
|
|
|
* (These are *beneath* the allocation wrappers.)
|
2012-03-11 11:32:41 +04:00
|
|
|
*/
|
|
|
|
|
2012-03-12 06:58:55 +04:00
|
|
|
static struct defoptlist *
|
|
|
|
mk_defoptlist(const char *name, const char *val, const char *lintval)
|
|
|
|
{
|
|
|
|
return defoptlist_create(name, val, lintval);
|
|
|
|
}
|
|
|
|
|
2012-03-12 01:16:07 +04:00
|
|
|
static struct loclist *
|
|
|
|
mk_loc(const char *name, const char *str, long long num)
|
|
|
|
{
|
|
|
|
return loclist_create(name, str, num);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct loclist *
|
|
|
|
mk_loc_val(const char *str, struct loclist *next)
|
|
|
|
{
|
|
|
|
struct loclist *ll;
|
|
|
|
|
|
|
|
ll = mk_loc(NULL, str, 0);
|
|
|
|
ll->ll_next = next;
|
|
|
|
return ll;
|
|
|
|
}
|
|
|
|
|
2012-03-11 11:32:41 +04:00
|
|
|
static struct attrlist *
|
|
|
|
mk_attrlist(struct attrlist *next, struct attr *a)
|
|
|
|
{
|
|
|
|
return attrlist_cons(next, a);
|
|
|
|
}
|
2012-03-11 11:27:02 +04:00
|
|
|
|
2012-03-11 12:21:53 +04:00
|
|
|
static struct condexpr *
|
|
|
|
mk_cx_atom(const char *s)
|
|
|
|
{
|
|
|
|
struct condexpr *cx;
|
|
|
|
|
|
|
|
cx = condexpr_create(CX_ATOM);
|
|
|
|
cx->cx_atom = s;
|
|
|
|
return cx;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct condexpr *
|
|
|
|
mk_cx_not(struct condexpr *sub)
|
|
|
|
{
|
|
|
|
struct condexpr *cx;
|
|
|
|
|
|
|
|
cx = condexpr_create(CX_NOT);
|
|
|
|
cx->cx_not = sub;
|
|
|
|
return cx;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct condexpr *
|
|
|
|
mk_cx_and(struct condexpr *left, struct condexpr *right)
|
|
|
|
{
|
|
|
|
struct condexpr *cx;
|
|
|
|
|
|
|
|
cx = condexpr_create(CX_AND);
|
|
|
|
cx->cx_and.left = left;
|
|
|
|
cx->cx_and.right = right;
|
|
|
|
return cx;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct condexpr *
|
|
|
|
mk_cx_or(struct condexpr *left, struct condexpr *right)
|
|
|
|
{
|
|
|
|
struct condexpr *cx;
|
|
|
|
|
|
|
|
cx = condexpr_create(CX_OR);
|
|
|
|
cx->cx_or.left = left;
|
|
|
|
cx->cx_or.right = right;
|
|
|
|
return cx;
|
|
|
|
}
|
|
|
|
|
2012-03-11 11:27:02 +04:00
|
|
|
/************************************************************/
|
|
|
|
|
1995-04-28 10:54:58 +04:00
|
|
|
static void
|
2010-02-04 00:00:49 +03:00
|
|
|
setmachine(const char *mch, const char *mcharch, struct nvlist *mchsubarches,
|
|
|
|
int isioconf)
|
1995-04-28 10:54:58 +04:00
|
|
|
{
|
1996-09-01 00:58:16 +04:00
|
|
|
char buf[MAXPATHLEN];
|
2001-06-08 16:47:06 +04:00
|
|
|
struct nvlist *nv;
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2010-02-04 00:00:49 +03:00
|
|
|
if (isioconf) {
|
|
|
|
if (include(_PATH_DEVNULL, ENDDEFS, 0, 0) != 0)
|
|
|
|
exit(1);
|
|
|
|
ioconfname = mch;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1995-04-28 10:54:58 +04:00
|
|
|
machine = mch;
|
|
|
|
machinearch = mcharch;
|
2001-06-08 16:47:06 +04:00
|
|
|
machinesubarches = mchsubarches;
|
|
|
|
|
2007-11-10 03:15:43 +03:00
|
|
|
/*
|
|
|
|
* Define attributes for all the given names
|
|
|
|
*/
|
2007-11-11 20:35:27 +03:00
|
|
|
if (defattr(machine, NULL, NULL, 0) != 0 ||
|
|
|
|
(machinearch != NULL &&
|
|
|
|
defattr(machinearch, NULL, NULL, 0) != 0))
|
2007-11-10 03:15:43 +03:00
|
|
|
exit(1);
|
|
|
|
for (nv = machinesubarches; nv != NULL; nv = nv->nv_next) {
|
|
|
|
if (defattr(nv->nv_name, NULL, NULL, 0) != 0)
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2001-06-08 16:47:06 +04:00
|
|
|
/*
|
|
|
|
* Set up the file inclusion stack. This empty include tells
|
|
|
|
* the parser there are no more device definitions coming.
|
|
|
|
*/
|
2010-02-04 00:00:49 +03:00
|
|
|
if (include(_PATH_DEVNULL, ENDDEFS, 0, 0) != 0)
|
2001-06-08 16:47:06 +04:00
|
|
|
exit(1);
|
1996-09-01 00:58:16 +04:00
|
|
|
|
2001-06-08 16:47:06 +04:00
|
|
|
/* Include arch/${MACHINE}/conf/files.${MACHINE} */
|
2003-07-13 16:39:08 +04:00
|
|
|
(void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s",
|
|
|
|
machine, machine);
|
2001-12-17 18:39:43 +03:00
|
|
|
if (include(buf, ENDFILE, 0, 0) != 0)
|
1996-09-01 00:58:16 +04:00
|
|
|
exit(1);
|
|
|
|
|
2001-06-08 16:47:06 +04:00
|
|
|
/* Include any arch/${MACHINE_SUBARCH}/conf/files.${MACHINE_SUBARCH} */
|
|
|
|
for (nv = machinesubarches; nv != NULL; nv = nv->nv_next) {
|
2003-07-13 16:39:08 +04:00
|
|
|
(void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s",
|
2001-06-08 16:47:06 +04:00
|
|
|
nv->nv_name, nv->nv_name);
|
2001-12-17 18:39:43 +03:00
|
|
|
if (include(buf, ENDFILE, 0, 0) != 0)
|
2001-06-08 16:47:06 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Include any arch/${MACHINE_ARCH}/conf/files.${MACHINE_ARCH} */
|
1995-04-28 10:54:58 +04:00
|
|
|
if (machinearch != NULL)
|
2003-07-13 16:39:08 +04:00
|
|
|
(void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s",
|
1995-04-28 10:54:58 +04:00
|
|
|
machinearch, machinearch);
|
|
|
|
else
|
2003-07-13 16:29:20 +04:00
|
|
|
strlcpy(buf, _PATH_DEVNULL, sizeof(buf));
|
2001-12-17 18:39:43 +03:00
|
|
|
if (include(buf, ENDFILE, 0, 0) != 0)
|
1996-09-01 00:58:16 +04:00
|
|
|
exit(1);
|
1995-04-28 10:54:58 +04:00
|
|
|
|
2001-06-08 16:47:06 +04:00
|
|
|
/*
|
|
|
|
* Include the global conf/files. As the last thing
|
|
|
|
* pushed on the stack, it will be processed first.
|
|
|
|
*/
|
2001-12-17 18:39:43 +03:00
|
|
|
if (include("conf/files", ENDFILE, 0, 0) != 0)
|
1995-04-28 10:54:58 +04:00
|
|
|
exit(1);
|
2005-09-10 19:38:46 +04:00
|
|
|
|
|
|
|
oktopackage = 1;
|
1995-04-28 10:54:58 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2000-10-02 23:48:34 +04:00
|
|
|
check_maxpart(void)
|
1995-04-28 10:54:58 +04:00
|
|
|
{
|
2000-10-02 23:48:34 +04:00
|
|
|
|
2010-02-04 00:00:49 +03:00
|
|
|
if (maxpartitions <= 0 && ioconfname == NULL) {
|
1996-11-12 02:54:17 +03:00
|
|
|
stop("cannot proceed without maxpartitions specifier");
|
|
|
|
}
|
1995-04-28 10:54:58 +04:00
|
|
|
}
|
1999-01-21 16:10:08 +03:00
|
|
|
|
Introduce versioning to config(1). This will allow us to provide a way to
error out in a bit more friendly way when the user is trying to use
config(1) on a too old or too recent source tree.
To achieve that, introduce the "version NUMBER" statement which can be use
about anywhere in the config files. Also, use two defines, CONFIG_VERSION
(which is the actual version of binary), and CONFIG_MINVERSION, which is
the minimum version the binary supports.
Allowing a range of versions serves several purposes: first it allows me
to introduce the versioning without requiring it to be used right away in
the kernel tree, which means it will be possible to introduce new features
of config(1) rather progressively in the future. E.g., using 'no pci' in
a config file could only require the new version in that config file, so
that the rest remains compatible.
In the end, an actual bump of the main config system (i.e., in conf/files)
will only be required when e.g., ioconf.c semantics change.
(Mostly-)silently accepted on tech-kern. Error messages turned into
correct and meaningful English thanks to Tracy and Perry.
2005-10-12 05:17:43 +04:00
|
|
|
static void
|
|
|
|
check_version(void)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* In essence, version is 0 and is not supported anymore
|
|
|
|
*/
|
|
|
|
if (version < CONFIG_MINVERSION)
|
|
|
|
stop("your sources are out of date -- please update.");
|
|
|
|
}
|
|
|
|
|
2012-03-12 01:16:07 +04:00
|
|
|
/*
|
|
|
|
* Prepend a blank entry to the locator definitions so the code in
|
|
|
|
* sem.c can distinguish "empty locator list" from "no locator list".
|
|
|
|
* XXX gross.
|
|
|
|
*/
|
|
|
|
static struct loclist *
|
|
|
|
present_loclist(struct loclist *ll)
|
|
|
|
{
|
|
|
|
struct loclist *ret;
|
|
|
|
|
|
|
|
ret = MK3(loc, "", NULL, 0);
|
|
|
|
ret->ll_next = ll;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
1999-01-21 16:10:08 +03:00
|
|
|
static void
|
2012-03-12 01:16:07 +04:00
|
|
|
app(struct loclist *p, struct loclist *q)
|
1999-01-21 16:10:08 +03:00
|
|
|
{
|
2012-03-12 01:16:07 +04:00
|
|
|
while (p->ll_next)
|
|
|
|
p = p->ll_next;
|
|
|
|
p->ll_next = q;
|
1999-01-21 16:10:08 +03:00
|
|
|
}
|
|
|
|
|
2012-03-12 01:16:07 +04:00
|
|
|
static struct loclist *
|
|
|
|
locarray(const char *name, int count, struct loclist *adefs, int opt)
|
1999-01-21 16:10:08 +03:00
|
|
|
{
|
2012-03-12 01:16:07 +04:00
|
|
|
struct loclist *defs = adefs;
|
|
|
|
struct loclist **p;
|
1999-01-21 16:10:08 +03:00
|
|
|
char buf[200];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (count <= 0) {
|
|
|
|
fprintf(stderr, "config: array with <= 0 size: %s\n", name);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
p = &defs;
|
|
|
|
for(i = 0; i < count; i++) {
|
|
|
|
if (*p == NULL)
|
2012-03-12 01:16:07 +04:00
|
|
|
*p = MK3(loc, NULL, "0", 0);
|
2003-07-13 16:39:08 +04:00
|
|
|
snprintf(buf, sizeof(buf), "%s%c%d", name, ARRCHR, i);
|
2012-03-12 01:16:07 +04:00
|
|
|
(*p)->ll_name = i == 0 ? name : intern(buf);
|
|
|
|
(*p)->ll_num = i > 0 || opt;
|
|
|
|
p = &(*p)->ll_next;
|
1999-01-21 16:10:08 +03:00
|
|
|
}
|
|
|
|
*p = 0;
|
|
|
|
return defs;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-12 01:16:07 +04:00
|
|
|
static struct loclist *
|
|
|
|
namelocvals(const char *name, struct loclist *vals)
|
1999-01-21 16:10:08 +03:00
|
|
|
{
|
2012-03-12 01:16:07 +04:00
|
|
|
struct loclist *p;
|
1999-01-21 16:10:08 +03:00
|
|
|
char buf[200];
|
|
|
|
int i;
|
|
|
|
|
2012-03-12 01:16:07 +04:00
|
|
|
for (i = 0, p = vals; p; i++, p = p->ll_next) {
|
2003-07-13 16:39:08 +04:00
|
|
|
snprintf(buf, sizeof(buf), "%s%c%d", name, ARRCHR, i);
|
2012-03-12 01:16:07 +04:00
|
|
|
p->ll_name = i == 0 ? name : intern(buf);
|
1999-01-21 16:10:08 +03:00
|
|
|
}
|
|
|
|
return vals;
|
|
|
|
}
|
|
|
|
|