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