1 1.1 thorpej %{ 2 1.57 thorpej /* $NetBSD: gram.y,v 1.57 2024/01/18 04:41:37 thorpej Exp $ */ 3 1.1 thorpej 4 1.1 thorpej /* 5 1.1 thorpej * Copyright (c) 1992, 1993 6 1.1 thorpej * The Regents of the University of California. All rights reserved. 7 1.1 thorpej * 8 1.1 thorpej * This software was developed by the Computer Systems Engineering group 9 1.1 thorpej * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 10 1.1 thorpej * contributed to Berkeley. 11 1.1 thorpej * 12 1.1 thorpej * All advertising materials mentioning features or use of this software 13 1.1 thorpej * must display the following acknowledgement: 14 1.1 thorpej * This product includes software developed by the University of 15 1.1 thorpej * California, Lawrence Berkeley Laboratories. 16 1.1 thorpej * 17 1.1 thorpej * Redistribution and use in source and binary forms, with or without 18 1.1 thorpej * modification, are permitted provided that the following conditions 19 1.1 thorpej * are met: 20 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 21 1.1 thorpej * notice, this list of conditions and the following disclaimer. 22 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 23 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 24 1.1 thorpej * documentation and/or other materials provided with the distribution. 25 1.1 thorpej * 3. Neither the name of the University nor the names of its contributors 26 1.1 thorpej * may be used to endorse or promote products derived from this software 27 1.1 thorpej * without specific prior written permission. 28 1.1 thorpej * 29 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 1.1 thorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 1.1 thorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 1.1 thorpej * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 1.1 thorpej * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 1.1 thorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 1.1 thorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 1.1 thorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 1.1 thorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 1.1 thorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 1.1 thorpej * SUCH DAMAGE. 40 1.1 thorpej * 41 1.1 thorpej * from: @(#)gram.y 8.1 (Berkeley) 6/6/93 42 1.1 thorpej */ 43 1.1 thorpej 44 1.44 christos #include <sys/cdefs.h> 45 1.57 thorpej __RCSID("$NetBSD: gram.y,v 1.57 2024/01/18 04:41:37 thorpej Exp $"); 46 1.44 christos 47 1.1 thorpej #include <sys/types.h> 48 1.1 thorpej #include <sys/param.h> 49 1.1 thorpej #include <ctype.h> 50 1.1 thorpej #include <stdio.h> 51 1.1 thorpej #include <stdlib.h> 52 1.1 thorpej #include <string.h> 53 1.1 thorpej #include <errno.h> 54 1.1 thorpej #include "defs.h" 55 1.1 thorpej #include "sem.h" 56 1.1 thorpej 57 1.1 thorpej #define FORMAT(n) (((n).fmt == 8 && (n).val != 0) ? "0%llo" : \ 58 1.1 thorpej ((n).fmt == 16) ? "0x%llx" : "%lld") 59 1.1 thorpej 60 1.13 christos #define stop(s) cfgerror(s), exit(1) 61 1.1 thorpej 62 1.1 thorpej static struct config conf; /* at most one active at a time */ 63 1.54 christos static int nowarn; /* if warning suppression is on */ 64 1.1 thorpej 65 1.31 dholland 66 1.31 dholland /* 67 1.31 dholland * Allocation wrapper functions 68 1.31 dholland */ 69 1.31 dholland static void wrap_alloc(void *ptr, unsigned code); 70 1.31 dholland static void wrap_continue(void); 71 1.31 dholland static void wrap_cleanup(void); 72 1.31 dholland 73 1.31 dholland /* 74 1.31 dholland * Allocation wrapper type codes 75 1.31 dholland */ 76 1.31 dholland #define WRAP_CODE_nvlist 1 77 1.37 dholland #define WRAP_CODE_defoptlist 2 78 1.37 dholland #define WRAP_CODE_loclist 3 79 1.37 dholland #define WRAP_CODE_attrlist 4 80 1.37 dholland #define WRAP_CODE_condexpr 5 81 1.31 dholland 82 1.31 dholland /* 83 1.31 dholland * The allocation wrappers themselves 84 1.31 dholland */ 85 1.31 dholland #define DECL_ALLOCWRAP(t) static struct t *wrap_mk_##t(struct t *arg) 86 1.31 dholland 87 1.31 dholland DECL_ALLOCWRAP(nvlist); 88 1.37 dholland DECL_ALLOCWRAP(defoptlist); 89 1.36 dholland DECL_ALLOCWRAP(loclist); 90 1.32 dholland DECL_ALLOCWRAP(attrlist); 91 1.34 dholland DECL_ALLOCWRAP(condexpr); 92 1.34 dholland 93 1.34 dholland /* allow shorter names */ 94 1.36 dholland #define wrap_mk_loc(p) wrap_mk_loclist(p) 95 1.34 dholland #define wrap_mk_cx(p) wrap_mk_condexpr(p) 96 1.31 dholland 97 1.31 dholland /* 98 1.31 dholland * Macros for allocating new objects 99 1.31 dholland */ 100 1.31 dholland 101 1.32 dholland /* old-style for struct nvlist */ 102 1.31 dholland #define new0(n,s,p,i,x) wrap_mk_nvlist(newnv(n, s, p, i, x)) 103 1.1 thorpej #define new_n(n) new0(n, NULL, NULL, 0, NULL) 104 1.1 thorpej #define new_nx(n, x) new0(n, NULL, NULL, 0, x) 105 1.1 thorpej #define new_ns(n, s) new0(n, s, NULL, 0, NULL) 106 1.1 thorpej #define new_si(s, i) new0(NULL, s, NULL, i, NULL) 107 1.53 mlelstv #define new_spi(s, p, i) new0(NULL, s, p, i, NULL) 108 1.1 thorpej #define new_nsi(n,s,i) new0(n, s, NULL, i, NULL) 109 1.1 thorpej #define new_np(n, p) new0(n, NULL, p, 0, NULL) 110 1.1 thorpej #define new_s(s) new0(NULL, s, NULL, 0, NULL) 111 1.1 thorpej #define new_p(p) new0(NULL, NULL, p, 0, NULL) 112 1.1 thorpej #define new_px(p, x) new0(NULL, NULL, p, 0, x) 113 1.1 thorpej #define new_sx(s, x) new0(NULL, s, NULL, 0, x) 114 1.11 cube #define new_nsx(n,s,x) new0(n, s, NULL, 0, x) 115 1.24 pooka #define new_i(i) new0(NULL, NULL, NULL, i, NULL) 116 1.1 thorpej 117 1.34 dholland /* new style, type-polymorphic; ordinary and for types with multiple flavors */ 118 1.32 dholland #define MK0(t) wrap_mk_##t(mk_##t()) 119 1.32 dholland #define MK1(t, a0) wrap_mk_##t(mk_##t(a0)) 120 1.32 dholland #define MK2(t, a0, a1) wrap_mk_##t(mk_##t(a0, a1)) 121 1.36 dholland #define MK3(t, a0, a1, a2) wrap_mk_##t(mk_##t(a0, a1, a2)) 122 1.32 dholland 123 1.34 dholland #define MKF0(t, f) wrap_mk_##t(mk_##t##_##f()) 124 1.34 dholland #define MKF1(t, f, a0) wrap_mk_##t(mk_##t##_##f(a0)) 125 1.34 dholland #define MKF2(t, f, a0, a1) wrap_mk_##t(mk_##t##_##f(a0, a1)) 126 1.34 dholland 127 1.32 dholland /* 128 1.32 dholland * Data constructors 129 1.32 dholland */ 130 1.32 dholland 131 1.37 dholland static struct defoptlist *mk_defoptlist(const char *, const char *, 132 1.37 dholland const char *); 133 1.36 dholland static struct loclist *mk_loc(const char *, const char *, long long); 134 1.36 dholland static struct loclist *mk_loc_val(const char *, struct loclist *); 135 1.32 dholland static struct attrlist *mk_attrlist(struct attrlist *, struct attr *); 136 1.34 dholland static struct condexpr *mk_cx_atom(const char *); 137 1.34 dholland static struct condexpr *mk_cx_not(struct condexpr *); 138 1.34 dholland static struct condexpr *mk_cx_and(struct condexpr *, struct condexpr *); 139 1.34 dholland static struct condexpr *mk_cx_or(struct condexpr *, struct condexpr *); 140 1.32 dholland 141 1.31 dholland /* 142 1.31 dholland * Other private functions 143 1.31 dholland */ 144 1.31 dholland 145 1.20 pooka static void setmachine(const char *, const char *, struct nvlist *, int); 146 1.1 thorpej static void check_maxpart(void); 147 1.1 thorpej 148 1.36 dholland static struct loclist *present_loclist(struct loclist *ll); 149 1.36 dholland static void app(struct loclist *, struct loclist *); 150 1.36 dholland static struct loclist *locarray(const char *, int, struct loclist *, int); 151 1.36 dholland static struct loclist *namelocvals(const char *, struct loclist *); 152 1.1 thorpej 153 1.1 thorpej %} 154 1.1 thorpej 155 1.1 thorpej %union { 156 1.1 thorpej struct attr *attr; 157 1.1 thorpej struct devbase *devb; 158 1.1 thorpej struct deva *deva; 159 1.1 thorpej struct nvlist *list; 160 1.37 dholland struct defoptlist *defoptlist; 161 1.36 dholland struct loclist *loclist; 162 1.32 dholland struct attrlist *attrlist; 163 1.34 dholland struct condexpr *condexpr; 164 1.1 thorpej const char *str; 165 1.1 thorpej struct numconst num; 166 1.1 thorpej int64_t val; 167 1.44 christos u_char flag; 168 1.44 christos devmajor_t devmajor; 169 1.44 christos int32_t i32; 170 1.1 thorpej } 171 1.1 thorpej 172 1.1 thorpej %token AND AT ATTACH 173 1.1 thorpej %token BLOCK BUILD 174 1.11 cube %token CHAR COLONEQ COMPILE_WITH CONFIG 175 1.16 drochner %token DEFFS DEFINE DEFOPT DEFPARAM DEFFLAG DEFPSEUDO DEFPSEUDODEV 176 1.16 drochner %token DEVICE DEVCLASS DUMPS DEVICE_MAJOR 177 1.1 thorpej %token ENDFILE 178 1.1 thorpej %token XFILE FILE_SYSTEM FLAGS 179 1.20 pooka %token IDENT IOCONF 180 1.24 pooka %token LINKZERO 181 1.1 thorpej %token XMACHINE MAJOR MAKEOPTIONS MAXUSERS MAXPARTITIONS MINOR 182 1.57 thorpej %token MKFLAGVAR 183 1.54 christos %token NEEDS_COUNT NEEDS_FLAG NO CNO 184 1.6 cube %token XOBJECT OBSOLETE ON OPTIONS 185 1.52 uebayasi %token PACKAGE PLUSEQ PREFIX BUILDPREFIX PSEUDO_DEVICE PSEUDO_ROOT 186 1.1 thorpej %token ROOT 187 1.45 uebayasi %token SELECT SINGLE SOURCE 188 1.1 thorpej %token TYPE 189 1.24 pooka %token VECTOR VERSION 190 1.1 thorpej %token WITH 191 1.1 thorpej %token <num> NUMBER 192 1.8 christos %token <str> PATHNAME QSTRING WORD EMPTYSTRING 193 1.1 thorpej %token ENDDEFS 194 1.1 thorpej 195 1.34 dholland %type <condexpr> fopts condexpr condatom 196 1.34 dholland %type <condexpr> cond_or_expr cond_and_expr cond_prefix_expr 197 1.34 dholland %type <condexpr> cond_base_expr 198 1.1 thorpej %type <str> fs_spec 199 1.44 christos %type <flag> fflags fflag oflags oflag 200 1.48 uebayasi %type <str> rule 201 1.33 dholland %type <attr> depend 202 1.1 thorpej %type <devb> devbase 203 1.1 thorpej %type <deva> devattach_opt 204 1.36 dholland %type <list> atlist 205 1.36 dholland %type <loclist> interface_opt 206 1.1 thorpej %type <str> atname 207 1.36 dholland %type <loclist> loclist locdef 208 1.1 thorpej %type <str> locdefault 209 1.36 dholland %type <loclist> values locdefaults 210 1.33 dholland %type <attrlist> depend_list depends 211 1.36 dholland %type <loclist> locators locator 212 1.1 thorpej %type <list> dev_spec 213 1.1 thorpej %type <str> device_instance 214 1.1 thorpej %type <str> attachment 215 1.1 thorpej %type <str> value 216 1.44 christos %type <val> major_minor 217 1.1 thorpej %type <num> signed_number 218 1.54 christos %type <i32> int32 npseudo device_flags no 219 1.1 thorpej %type <str> deffs 220 1.1 thorpej %type <list> deffses 221 1.37 dholland %type <defoptlist> defopt 222 1.37 dholland %type <defoptlist> defopts 223 1.35 dholland %type <str> optdepend 224 1.35 dholland %type <list> optdepends 225 1.35 dholland %type <list> optdepend_list 226 1.1 thorpej %type <str> optfile_opt 227 1.28 dholland %type <list> subarches 228 1.1 thorpej %type <str> filename stringvalue locname mkvarname 229 1.44 christos %type <devmajor> device_major_block device_major_char 230 1.24 pooka %type <list> devnodes devnodetype devnodeflags devnode_dims 231 1.1 thorpej 232 1.1 thorpej %% 233 1.1 thorpej 234 1.1 thorpej /* 235 1.40 uebayasi * A complete configuration consists of both the selection part (a 236 1.25 dholland * kernel config such as GENERIC or SKYNET, plus also the various 237 1.25 dholland * std.* files), which selects the material to be in the kernel, and 238 1.25 dholland * also the definition part (files, files.*, etc.) that declares what 239 1.25 dholland * material is available to be placed in kernels. 240 1.25 dholland * 241 1.25 dholland * The two parts have almost entirely separate syntaxes. This grammar 242 1.25 dholland * covers both of them. When config is run on a kernel configuration 243 1.25 dholland * file, the std.* file for the port is included explicitly. The 244 1.25 dholland * files.* files are included implicitly when the std.* file declares 245 1.25 dholland * the machine type. 246 1.25 dholland * 247 1.25 dholland * The machine spec, which brings in the definition part, must appear 248 1.25 dholland * before all configuration material except for the "topthings"; these 249 1.25 dholland * are the "source" and "build" declarations that tell config where 250 1.25 dholland * things are. These are not used by default. 251 1.25 dholland * 252 1.25 dholland * A previous version of this comment contained the following text: 253 1.25 dholland * 254 1.25 dholland * Note that we do not have sufficient keywords to enforce any 255 1.25 dholland * order between elements of "topthings" without introducing 256 1.25 dholland * shift/reduce conflicts. Instead, check order requirements in 257 1.25 dholland * the C code. 258 1.25 dholland * 259 1.25 dholland * As of March 2012 this comment makes no sense, as there are only two 260 1.25 dholland * topthings and no reason for them to be forcibly ordered. 261 1.25 dholland * Furthermore, the statement about conflicts is false. 262 1.1 thorpej */ 263 1.25 dholland 264 1.25 dholland /* Complete configuration. */ 265 1.28 dholland configuration: 266 1.40 uebayasi topthings machine_spec definition_part selection_part 267 1.26 dholland ; 268 1.1 thorpej 269 1.25 dholland /* Sequence of zero or more topthings. */ 270 1.1 thorpej topthings: 271 1.26 dholland /* empty */ 272 1.26 dholland | topthings topthing 273 1.26 dholland ; 274 1.1 thorpej 275 1.25 dholland /* Directory specification. */ 276 1.1 thorpej topthing: 277 1.27 dholland '\n' 278 1.27 dholland | SOURCE filename '\n' { if (!srcdir) srcdir = $2; } 279 1.26 dholland | BUILD filename '\n' { if (!builddir) builddir = $2; } 280 1.26 dholland ; 281 1.1 thorpej 282 1.25 dholland /* "machine foo" from std.whatever */ 283 1.1 thorpej machine_spec: 284 1.26 dholland XMACHINE WORD '\n' { setmachine($2,NULL,NULL,0); } 285 1.28 dholland | XMACHINE WORD WORD '\n' { setmachine($2,$3,NULL,0); } 286 1.28 dholland | XMACHINE WORD WORD subarches '\n' { setmachine($2,$3,$4,0); } 287 1.26 dholland | IOCONF WORD '\n' { setmachine($2,NULL,NULL,1); } 288 1.26 dholland | error { stop("cannot proceed without machine or ioconf specifier"); } 289 1.26 dholland ; 290 1.1 thorpej 291 1.28 dholland /* One or more sub-arches. */ 292 1.1 thorpej subarches: 293 1.27 dholland WORD { $$ = new_n($1); } 294 1.27 dholland | subarches WORD { $$ = new_nx($2, $1); } 295 1.26 dholland ; 296 1.1 thorpej 297 1.54 christos no: 298 1.54 christos NO { $$ = 0; } 299 1.54 christos | CNO { $$ = 1; } 300 1.54 christos ; 301 1.54 christos 302 1.25 dholland /************************************************************/ 303 1.25 dholland 304 1.1 thorpej /* 305 1.1 thorpej * The machine definitions grammar. 306 1.1 thorpej */ 307 1.25 dholland 308 1.25 dholland /* Complete definition part: the contents of all files.* files. */ 309 1.28 dholland definition_part: 310 1.56 uwe definitions ENDDEFS { 311 1.56 uwe CFGDBG(1, "ENDDEFS"); 312 1.56 uwe check_maxpart(); 313 1.56 uwe check_version(); 314 1.56 uwe } 315 1.26 dholland ; 316 1.1 thorpej 317 1.28 dholland /* Zero or more definitions. Trap errors. */ 318 1.28 dholland definitions: 319 1.28 dholland /* empty */ 320 1.28 dholland | definitions '\n' 321 1.31 dholland | definitions definition '\n' { wrap_continue(); } 322 1.31 dholland | definitions error '\n' { wrap_cleanup(); } 323 1.28 dholland | definitions ENDFILE { enddefs(); checkfiles(); } 324 1.26 dholland ; 325 1.1 thorpej 326 1.25 dholland /* A single definition. */ 327 1.28 dholland definition: 328 1.41 uebayasi define_file 329 1.41 uebayasi | define_object 330 1.41 uebayasi | define_device_major 331 1.41 uebayasi | define_prefix 332 1.52 uebayasi | define_buildprefix 333 1.41 uebayasi | define_devclass 334 1.41 uebayasi | define_filesystems 335 1.41 uebayasi | define_attribute 336 1.41 uebayasi | define_option 337 1.41 uebayasi | define_flag 338 1.57 thorpej | define_flag_mkvar 339 1.41 uebayasi | define_obsolete_flag 340 1.41 uebayasi | define_param 341 1.41 uebayasi | define_obsolete_param 342 1.41 uebayasi | define_device 343 1.41 uebayasi | define_device_attachment 344 1.41 uebayasi | define_maxpartitions 345 1.41 uebayasi | define_maxusers 346 1.41 uebayasi | define_makeoptions 347 1.41 uebayasi | define_pseudo 348 1.41 uebayasi | define_pseudodev 349 1.41 uebayasi | define_major 350 1.41 uebayasi | define_version 351 1.41 uebayasi ; 352 1.41 uebayasi 353 1.41 uebayasi /* source file: file foo/bar.c bar|baz needs-flag compile-with blah */ 354 1.41 uebayasi define_file: 355 1.48 uebayasi XFILE filename fopts fflags rule { addfile($2, $3, $4, $5); } 356 1.41 uebayasi ; 357 1.41 uebayasi 358 1.41 uebayasi /* object file: object zot.o foo|zot needs-flag */ 359 1.41 uebayasi define_object: 360 1.51 uebayasi XOBJECT filename fopts oflags { addfile($2, $3, $4, NULL); } 361 1.41 uebayasi ; 362 1.41 uebayasi 363 1.41 uebayasi /* device major declaration */ 364 1.41 uebayasi define_device_major: 365 1.41 uebayasi DEVICE_MAJOR WORD device_major_char device_major_block fopts devnodes 366 1.41 uebayasi { 367 1.41 uebayasi adddevm($2, $3, $4, $5, $6); 368 1.41 uebayasi do_devsw = 1; 369 1.41 uebayasi } 370 1.41 uebayasi ; 371 1.41 uebayasi 372 1.41 uebayasi /* prefix delimiter */ 373 1.41 uebayasi define_prefix: 374 1.41 uebayasi PREFIX filename { prefix_push($2); } 375 1.41 uebayasi | PREFIX { prefix_pop(); } 376 1.41 uebayasi ; 377 1.41 uebayasi 378 1.52 uebayasi define_buildprefix: 379 1.52 uebayasi BUILDPREFIX filename { buildprefix_push($2); } 380 1.52 uebayasi | BUILDPREFIX WORD { buildprefix_push($2); } 381 1.52 uebayasi | BUILDPREFIX { buildprefix_pop(); } 382 1.52 uebayasi ; 383 1.52 uebayasi 384 1.41 uebayasi define_devclass: 385 1.42 uebayasi DEVCLASS WORD { (void)defdevclass($2, NULL, NULL, 1); } 386 1.41 uebayasi ; 387 1.41 uebayasi 388 1.41 uebayasi define_filesystems: 389 1.41 uebayasi DEFFS deffses optdepend_list { deffilesystem($2, $3); } 390 1.41 uebayasi ; 391 1.41 uebayasi 392 1.41 uebayasi define_attribute: 393 1.41 uebayasi DEFINE WORD interface_opt depend_list 394 1.42 uebayasi { (void)defattr0($2, $3, $4, 0); } 395 1.41 uebayasi ; 396 1.41 uebayasi 397 1.41 uebayasi define_option: 398 1.41 uebayasi DEFOPT optfile_opt defopts optdepend_list 399 1.26 dholland { defoption($2, $3, $4); } 400 1.41 uebayasi ; 401 1.41 uebayasi 402 1.41 uebayasi define_flag: 403 1.41 uebayasi DEFFLAG optfile_opt defopts optdepend_list 404 1.26 dholland { defflag($2, $3, $4, 0); } 405 1.41 uebayasi ; 406 1.41 uebayasi 407 1.57 thorpej define_flag_mkvar: 408 1.57 thorpej MKFLAGVAR defopts 409 1.57 thorpej { mkflagvar($2); } 410 1.57 thorpej 411 1.41 uebayasi define_obsolete_flag: 412 1.41 uebayasi OBSOLETE DEFFLAG optfile_opt defopts 413 1.26 dholland { defflag($3, $4, NULL, 1); } 414 1.41 uebayasi ; 415 1.41 uebayasi 416 1.41 uebayasi define_param: 417 1.41 uebayasi DEFPARAM optfile_opt defopts optdepend_list 418 1.26 dholland { defparam($2, $3, $4, 0); } 419 1.41 uebayasi ; 420 1.41 uebayasi 421 1.41 uebayasi define_obsolete_param: 422 1.41 uebayasi OBSOLETE DEFPARAM optfile_opt defopts 423 1.26 dholland { defparam($3, $4, NULL, 1); } 424 1.41 uebayasi ; 425 1.41 uebayasi 426 1.41 uebayasi define_device: 427 1.41 uebayasi DEVICE devbase interface_opt depend_list 428 1.26 dholland { defdev($2, $3, $4, 0); } 429 1.41 uebayasi ; 430 1.41 uebayasi 431 1.41 uebayasi define_device_attachment: 432 1.41 uebayasi ATTACH devbase AT atlist devattach_opt depend_list 433 1.26 dholland { defdevattach($5, $2, $4, $6); } 434 1.41 uebayasi ; 435 1.41 uebayasi 436 1.41 uebayasi define_maxpartitions: 437 1.44 christos MAXPARTITIONS int32 { maxpartitions = $2; } 438 1.41 uebayasi ; 439 1.41 uebayasi 440 1.41 uebayasi define_maxusers: 441 1.44 christos MAXUSERS int32 int32 int32 442 1.44 christos { setdefmaxusers($2, $3, $4); } 443 1.41 uebayasi ; 444 1.41 uebayasi 445 1.41 uebayasi define_makeoptions: 446 1.41 uebayasi MAKEOPTIONS condmkopt_list 447 1.41 uebayasi ; 448 1.41 uebayasi 449 1.41 uebayasi define_pseudo: 450 1.17 drochner /* interface_opt in DEFPSEUDO is for backwards compatibility */ 451 1.41 uebayasi DEFPSEUDO devbase interface_opt depend_list 452 1.26 dholland { defdev($2, $3, $4, 1); } 453 1.41 uebayasi ; 454 1.41 uebayasi 455 1.41 uebayasi define_pseudodev: 456 1.41 uebayasi DEFPSEUDODEV devbase interface_opt depend_list 457 1.26 dholland { defdev($2, $3, $4, 2); } 458 1.26 dholland ; 459 1.1 thorpej 460 1.41 uebayasi define_major: 461 1.41 uebayasi MAJOR '{' majorlist '}' 462 1.41 uebayasi ; 463 1.41 uebayasi 464 1.41 uebayasi define_version: 465 1.44 christos VERSION int32 { setversion($2); } 466 1.26 dholland ; 467 1.1 thorpej 468 1.33 dholland /* file options: optional expression of conditions */ 469 1.29 dholland fopts: 470 1.29 dholland /* empty */ { $$ = NULL; } 471 1.33 dholland | condexpr { $$ = $1; } 472 1.26 dholland ; 473 1.1 thorpej 474 1.29 dholland /* zero or more flags for a file */ 475 1.35 dholland fflags: 476 1.29 dholland /* empty */ { $$ = 0; } 477 1.35 dholland | fflags fflag { $$ = $1 | $2; } 478 1.26 dholland ; 479 1.1 thorpej 480 1.29 dholland /* one flag for a file */ 481 1.29 dholland fflag: 482 1.29 dholland NEEDS_COUNT { $$ = FI_NEEDSCOUNT; } 483 1.29 dholland | NEEDS_FLAG { $$ = FI_NEEDSFLAG; } 484 1.26 dholland ; 485 1.1 thorpej 486 1.48 uebayasi /* extra compile directive for a source file */ 487 1.48 uebayasi rule: 488 1.48 uebayasi /* empty */ { $$ = NULL; } 489 1.48 uebayasi | COMPILE_WITH stringvalue { $$ = $2; } 490 1.48 uebayasi ; 491 1.48 uebayasi 492 1.29 dholland /* zero or more flags for an object file */ 493 1.35 dholland oflags: 494 1.29 dholland /* empty */ { $$ = 0; } 495 1.35 dholland | oflags oflag { $$ = $1 | $2; } 496 1.29 dholland ; 497 1.29 dholland 498 1.29 dholland /* a single flag for an object file */ 499 1.29 dholland oflag: 500 1.51 uebayasi NEEDS_FLAG { $$ = FI_NEEDSFLAG; } 501 1.29 dholland ; 502 1.29 dholland 503 1.29 dholland /* char 55 */ 504 1.29 dholland device_major_char: 505 1.29 dholland /* empty */ { $$ = -1; } 506 1.44 christos | CHAR int32 { $$ = $2; } 507 1.26 dholland ; 508 1.1 thorpej 509 1.29 dholland /* block 33 */ 510 1.29 dholland device_major_block: 511 1.29 dholland /* empty */ { $$ = -1; } 512 1.44 christos | BLOCK int32 { $$ = $2; } 513 1.26 dholland ; 514 1.1 thorpej 515 1.29 dholland /* device node specification */ 516 1.29 dholland devnodes: 517 1.29 dholland /* empty */ { $$ = new_s("DEVNODE_DONTBOTHER"); } 518 1.29 dholland | devnodetype ',' devnodeflags { $$ = nvcat($1, $3); } 519 1.29 dholland | devnodetype { $$ = $1; } 520 1.26 dholland ; 521 1.1 thorpej 522 1.29 dholland /* device nodes without flags */ 523 1.29 dholland devnodetype: 524 1.29 dholland SINGLE { $$ = new_s("DEVNODE_SINGLE"); } 525 1.29 dholland | VECTOR '=' devnode_dims { $$ = nvcat(new_s("DEVNODE_VECTOR"), $3); } 526 1.26 dholland ; 527 1.1 thorpej 528 1.29 dholland /* dimensions (?) */ 529 1.29 dholland devnode_dims: 530 1.29 dholland NUMBER { $$ = new_i($1.val); } 531 1.29 dholland | NUMBER ':' NUMBER { 532 1.29 dholland struct nvlist *__nv1, *__nv2; 533 1.26 dholland 534 1.29 dholland __nv1 = new_i($1.val); 535 1.29 dholland __nv2 = new_i($3.val); 536 1.29 dholland $$ = nvcat(__nv1, __nv2); 537 1.26 dholland } 538 1.29 dholland ; 539 1.29 dholland 540 1.29 dholland /* flags for device nodes */ 541 1.29 dholland devnodeflags: 542 1.29 dholland LINKZERO { $$ = new_s("DEVNODE_FLAG_LINKZERO");} 543 1.29 dholland ; 544 1.26 dholland 545 1.29 dholland /* one or more file system names */ 546 1.29 dholland deffses: 547 1.29 dholland deffs { $$ = new_n($1); } 548 1.29 dholland | deffses deffs { $$ = new_nx($2, $1); } 549 1.26 dholland ; 550 1.1 thorpej 551 1.29 dholland /* a single file system name */ 552 1.29 dholland deffs: 553 1.29 dholland WORD { $$ = $1; } 554 1.26 dholland ; 555 1.1 thorpej 556 1.28 dholland /* optional locator specification */ 557 1.1 thorpej interface_opt: 558 1.26 dholland /* empty */ { $$ = NULL; } 559 1.36 dholland | '{' '}' { $$ = present_loclist(NULL); } 560 1.36 dholland | '{' loclist '}' { $$ = present_loclist($2); } 561 1.26 dholland ; 562 1.1 thorpej 563 1.25 dholland /* 564 1.25 dholland * loclist order matters, must use right recursion 565 1.25 dholland * XXX wot? 566 1.25 dholland */ 567 1.25 dholland 568 1.25 dholland /* list of locator definitions */ 569 1.1 thorpej loclist: 570 1.26 dholland locdef { $$ = $1; } 571 1.26 dholland | locdef ',' loclist { $$ = $1; app($1, $3); } 572 1.26 dholland ; 573 1.1 thorpej 574 1.25 dholland /* 575 1.25 dholland * "[ WORD locdefault ]" syntax may be unnecessary... 576 1.25 dholland */ 577 1.25 dholland 578 1.25 dholland /* one locator definition */ 579 1.1 thorpej locdef: 580 1.36 dholland locname locdefault { $$ = MK3(loc, $1, $2, 0); } 581 1.36 dholland | locname { $$ = MK3(loc, $1, NULL, 0); } 582 1.36 dholland | '[' locname locdefault ']' { $$ = MK3(loc, $2, $3, 1); } 583 1.44 christos | locname '[' int32 ']' { $$ = locarray($1, $3, NULL, 0); } 584 1.44 christos | locname '[' int32 ']' locdefaults 585 1.44 christos { $$ = locarray($1, $3, $5, 0); } 586 1.44 christos | '[' locname '[' int32 ']' locdefaults ']' 587 1.44 christos { $$ = locarray($2, $4, $6, 1); } 588 1.26 dholland ; 589 1.1 thorpej 590 1.25 dholland /* locator name */ 591 1.1 thorpej locname: 592 1.26 dholland WORD { $$ = $1; } 593 1.26 dholland | QSTRING { $$ = $1; } 594 1.26 dholland ; 595 1.1 thorpej 596 1.25 dholland /* locator default value */ 597 1.1 thorpej locdefault: 598 1.26 dholland '=' value { $$ = $2; } 599 1.26 dholland ; 600 1.1 thorpej 601 1.25 dholland /* multiple locator default values */ 602 1.1 thorpej locdefaults: 603 1.26 dholland '=' '{' values '}' { $$ = $3; } 604 1.26 dholland ; 605 1.1 thorpej 606 1.33 dholland /* list of depends, may be empty */ 607 1.33 dholland depend_list: 608 1.26 dholland /* empty */ { $$ = NULL; } 609 1.33 dholland | ':' depends { $$ = $2; } 610 1.29 dholland ; 611 1.29 dholland 612 1.33 dholland /* one or more depend items */ 613 1.33 dholland depends: 614 1.33 dholland depend { $$ = MK2(attrlist, NULL, $1); } 615 1.33 dholland | depends ',' depend { $$ = MK2(attrlist, $1, $3); } 616 1.29 dholland ; 617 1.29 dholland 618 1.33 dholland /* one depend item (which is an attribute) */ 619 1.33 dholland depend: 620 1.43 uebayasi WORD { $$ = refattr($1); } 621 1.29 dholland ; 622 1.29 dholland 623 1.35 dholland /* list of option depends, may be empty */ 624 1.35 dholland optdepend_list: 625 1.35 dholland /* empty */ { $$ = NULL; } 626 1.35 dholland | ':' optdepends { $$ = $2; } 627 1.35 dholland ; 628 1.35 dholland 629 1.35 dholland /* a list of option dependencies */ 630 1.35 dholland optdepends: 631 1.35 dholland optdepend { $$ = new_n($1); } 632 1.35 dholland | optdepends ',' optdepend { $$ = new_nx($3, $1); } 633 1.35 dholland ; 634 1.35 dholland 635 1.35 dholland /* one option depend, which is an option name */ 636 1.35 dholland optdepend: 637 1.35 dholland WORD { $$ = $1; } 638 1.35 dholland ; 639 1.35 dholland 640 1.35 dholland 641 1.29 dholland /* list of places to attach: attach blah at ... */ 642 1.29 dholland atlist: 643 1.29 dholland atname { $$ = new_n($1); } 644 1.29 dholland | atlist ',' atname { $$ = new_nx($3, $1); } 645 1.29 dholland ; 646 1.29 dholland 647 1.29 dholland /* a place to attach a device */ 648 1.29 dholland atname: 649 1.29 dholland WORD { $$ = $1; } 650 1.29 dholland | ROOT { $$ = NULL; } 651 1.26 dholland ; 652 1.1 thorpej 653 1.29 dholland /* one or more defined options */ 654 1.29 dholland defopts: 655 1.29 dholland defopt { $$ = $1; } 656 1.37 dholland | defopts defopt { $$ = defoptlist_append($2, $1); } 657 1.26 dholland ; 658 1.1 thorpej 659 1.29 dholland /* one defined option */ 660 1.29 dholland defopt: 661 1.37 dholland WORD { $$ = MK3(defoptlist, $1, NULL, NULL); } 662 1.37 dholland | WORD '=' value { $$ = MK3(defoptlist, $1, $3, NULL); } 663 1.37 dholland | WORD COLONEQ value { $$ = MK3(defoptlist, $1, NULL, $3); } 664 1.37 dholland | WORD '=' value COLONEQ value { $$ = MK3(defoptlist, $1, $3, $5); } 665 1.26 dholland ; 666 1.1 thorpej 667 1.29 dholland /* list of conditional makeoptions */ 668 1.29 dholland condmkopt_list: 669 1.29 dholland condmkoption 670 1.29 dholland | condmkopt_list ',' condmkoption 671 1.26 dholland ; 672 1.1 thorpej 673 1.29 dholland /* one conditional make option */ 674 1.29 dholland condmkoption: 675 1.33 dholland condexpr mkvarname PLUSEQ value { appendcondmkoption($1, $2, $4); } 676 1.26 dholland ; 677 1.1 thorpej 678 1.29 dholland /* device name */ 679 1.29 dholland devbase: 680 1.29 dholland WORD { $$ = getdevbase($1); } 681 1.26 dholland ; 682 1.1 thorpej 683 1.29 dholland /* optional attachment: with foo */ 684 1.29 dholland devattach_opt: 685 1.29 dholland /* empty */ { $$ = NULL; } 686 1.29 dholland | WITH WORD { $$ = getdevattach($2); } 687 1.26 dholland ; 688 1.1 thorpej 689 1.25 dholland /* list of major numbers */ 690 1.25 dholland /* XXX why is this right-recursive? */ 691 1.1 thorpej majorlist: 692 1.26 dholland majordef 693 1.26 dholland | majorlist ',' majordef 694 1.26 dholland ; 695 1.1 thorpej 696 1.25 dholland /* one major number */ 697 1.1 thorpej majordef: 698 1.44 christos devbase '=' int32 { setmajor($1, $3); } 699 1.44 christos ; 700 1.44 christos 701 1.44 christos int32: 702 1.44 christos NUMBER { 703 1.44 christos if ($1.val > INT_MAX || $1.val < INT_MIN) 704 1.44 christos cfgerror("overflow %" PRId64, $1.val); 705 1.44 christos else 706 1.44 christos $$ = (int32_t)$1.val; 707 1.44 christos } 708 1.26 dholland ; 709 1.1 thorpej 710 1.25 dholland /************************************************************/ 711 1.1 thorpej 712 1.1 thorpej /* 713 1.40 uebayasi * The selection grammar. 714 1.1 thorpej */ 715 1.25 dholland 716 1.40 uebayasi /* Complete selection part: all std.* files plus selected config. */ 717 1.40 uebayasi selection_part: 718 1.40 uebayasi selections 719 1.26 dholland ; 720 1.1 thorpej 721 1.28 dholland /* Zero or more config items. Trap errors. */ 722 1.40 uebayasi selections: 723 1.28 dholland /* empty */ 724 1.40 uebayasi | selections '\n' 725 1.40 uebayasi | selections selection '\n' { wrap_continue(); } 726 1.41 uebayasi | selections error '\n' { wrap_cleanup(); } 727 1.26 dholland ; 728 1.1 thorpej 729 1.25 dholland /* One config item. */ 730 1.40 uebayasi selection: 731 1.28 dholland definition 732 1.45 uebayasi | select_attr 733 1.45 uebayasi | select_no_attr 734 1.41 uebayasi | select_no_filesystems 735 1.41 uebayasi | select_filesystems 736 1.41 uebayasi | select_no_makeoptions 737 1.41 uebayasi | select_makeoptions 738 1.41 uebayasi | select_no_options 739 1.41 uebayasi | select_options 740 1.41 uebayasi | select_maxusers 741 1.41 uebayasi | select_ident 742 1.41 uebayasi | select_no_ident 743 1.41 uebayasi | select_config 744 1.41 uebayasi | select_no_config 745 1.41 uebayasi | select_no_pseudodev 746 1.41 uebayasi | select_pseudodev 747 1.41 uebayasi | select_pseudoroot 748 1.41 uebayasi | select_no_device_instance_attachment 749 1.41 uebayasi | select_no_device_attachment 750 1.41 uebayasi | select_no_device_instance 751 1.41 uebayasi | select_device_instance 752 1.41 uebayasi ; 753 1.41 uebayasi 754 1.45 uebayasi select_attr: 755 1.45 uebayasi SELECT WORD { addattr($2); } 756 1.45 uebayasi ; 757 1.45 uebayasi 758 1.45 uebayasi select_no_attr: 759 1.54 christos no SELECT WORD { delattr($3, $1); } 760 1.45 uebayasi ; 761 1.45 uebayasi 762 1.41 uebayasi select_no_filesystems: 763 1.54 christos no FILE_SYSTEM { nowarn = $1; } no_fs_list { nowarn = 0; } 764 1.41 uebayasi ; 765 1.41 uebayasi 766 1.41 uebayasi select_filesystems: 767 1.41 uebayasi FILE_SYSTEM fs_list 768 1.41 uebayasi ; 769 1.41 uebayasi 770 1.41 uebayasi select_no_makeoptions: 771 1.54 christos no MAKEOPTIONS { nowarn = $1; } no_mkopt_list { nowarn = 0; } 772 1.41 uebayasi ; 773 1.41 uebayasi 774 1.41 uebayasi select_makeoptions: 775 1.41 uebayasi MAKEOPTIONS mkopt_list 776 1.41 uebayasi ; 777 1.41 uebayasi 778 1.41 uebayasi select_no_options: 779 1.54 christos no OPTIONS { nowarn = $1; } no_opt_list { nowarn = 0; } 780 1.41 uebayasi ; 781 1.41 uebayasi 782 1.41 uebayasi select_options: 783 1.41 uebayasi OPTIONS opt_list 784 1.41 uebayasi ; 785 1.41 uebayasi 786 1.41 uebayasi select_maxusers: 787 1.50 uebayasi MAXUSERS int32 { setmaxusers($2); } 788 1.41 uebayasi ; 789 1.41 uebayasi 790 1.41 uebayasi select_ident: 791 1.41 uebayasi IDENT stringvalue { setident($2); } 792 1.41 uebayasi ; 793 1.41 uebayasi 794 1.41 uebayasi select_no_ident: 795 1.54 christos no IDENT { setident(NULL); } 796 1.41 uebayasi ; 797 1.41 uebayasi 798 1.41 uebayasi select_config: 799 1.41 uebayasi CONFIG conf root_spec sysparam_list 800 1.26 dholland { addconf(&conf); } 801 1.41 uebayasi ; 802 1.41 uebayasi 803 1.41 uebayasi select_no_config: 804 1.54 christos no CONFIG WORD { delconf($3, $1); } 805 1.41 uebayasi ; 806 1.41 uebayasi 807 1.41 uebayasi select_no_pseudodev: 808 1.54 christos no PSEUDO_DEVICE WORD { delpseudo($3, $1); } 809 1.41 uebayasi ; 810 1.41 uebayasi 811 1.41 uebayasi select_pseudodev: 812 1.41 uebayasi PSEUDO_DEVICE WORD npseudo { addpseudo($2, $3); } 813 1.41 uebayasi ; 814 1.41 uebayasi 815 1.41 uebayasi select_pseudoroot: 816 1.41 uebayasi PSEUDO_ROOT device_instance { addpseudoroot($2); } 817 1.41 uebayasi ; 818 1.41 uebayasi 819 1.41 uebayasi select_no_device_instance_attachment: 820 1.54 christos no device_instance AT attachment 821 1.54 christos { deldevi($2, $4, $1); } 822 1.41 uebayasi ; 823 1.41 uebayasi 824 1.41 uebayasi select_no_device_attachment: 825 1.54 christos no DEVICE AT attachment { deldeva($4, $1); } 826 1.41 uebayasi ; 827 1.41 uebayasi 828 1.41 uebayasi select_no_device_instance: 829 1.54 christos no device_instance { deldev($2, $1); } 830 1.41 uebayasi ; 831 1.41 uebayasi 832 1.41 uebayasi select_device_instance: 833 1.41 uebayasi device_instance AT attachment locators device_flags 834 1.26 dholland { adddev($1, $3, $4, $5); } 835 1.26 dholland ; 836 1.1 thorpej 837 1.25 dholland /* list of filesystems */ 838 1.1 thorpej fs_list: 839 1.26 dholland fsoption 840 1.26 dholland | fs_list ',' fsoption 841 1.26 dholland ; 842 1.1 thorpej 843 1.25 dholland /* one filesystem */ 844 1.1 thorpej fsoption: 845 1.26 dholland WORD { addfsoption($1); } 846 1.26 dholland ; 847 1.1 thorpej 848 1.25 dholland /* list of filesystems that had NO in front */ 849 1.1 thorpej no_fs_list: 850 1.26 dholland no_fsoption 851 1.26 dholland | no_fs_list ',' no_fsoption 852 1.26 dholland ; 853 1.1 thorpej 854 1.25 dholland /* one filesystem that had NO in front */ 855 1.1 thorpej no_fsoption: 856 1.54 christos WORD { delfsoption($1, nowarn); } 857 1.26 dholland ; 858 1.1 thorpej 859 1.25 dholland /* list of make options */ 860 1.25 dholland /* XXX why is this right-recursive? */ 861 1.1 thorpej mkopt_list: 862 1.26 dholland mkoption 863 1.26 dholland | mkopt_list ',' mkoption 864 1.26 dholland ; 865 1.1 thorpej 866 1.25 dholland /* one make option */ 867 1.1 thorpej mkoption: 868 1.26 dholland mkvarname '=' value { addmkoption($1, $3); } 869 1.26 dholland | mkvarname PLUSEQ value { appendmkoption($1, $3); } 870 1.26 dholland ; 871 1.1 thorpej 872 1.25 dholland /* list of make options that had NO in front */ 873 1.1 thorpej no_mkopt_list: 874 1.26 dholland no_mkoption 875 1.26 dholland | no_mkopt_list ',' no_mkoption 876 1.26 dholland ; 877 1.1 thorpej 878 1.25 dholland /* one make option that had NO in front */ 879 1.29 dholland /* XXX shouldn't this be mkvarname rather than WORD? */ 880 1.1 thorpej no_mkoption: 881 1.54 christos WORD { delmkoption($1, nowarn); } 882 1.26 dholland ; 883 1.1 thorpej 884 1.25 dholland /* list of options */ 885 1.1 thorpej opt_list: 886 1.26 dholland option 887 1.26 dholland | opt_list ',' option 888 1.26 dholland ; 889 1.1 thorpej 890 1.25 dholland /* one option */ 891 1.1 thorpej option: 892 1.26 dholland WORD { addoption($1, NULL); } 893 1.26 dholland | WORD '=' value { addoption($1, $3); } 894 1.26 dholland ; 895 1.1 thorpej 896 1.25 dholland /* list of options that had NO in front */ 897 1.1 thorpej no_opt_list: 898 1.26 dholland no_option 899 1.26 dholland | no_opt_list ',' no_option 900 1.26 dholland ; 901 1.1 thorpej 902 1.25 dholland /* one option that had NO in front */ 903 1.1 thorpej no_option: 904 1.54 christos WORD { deloption($1, nowarn); } 905 1.26 dholland ; 906 1.1 thorpej 907 1.25 dholland /* the name in "config name root on ..." */ 908 1.1 thorpej conf: 909 1.26 dholland WORD { 910 1.26 dholland conf.cf_name = $1; 911 1.55 christos conf.cf_where.w_srcline = currentline(); 912 1.26 dholland conf.cf_fstype = NULL; 913 1.26 dholland conf.cf_root = NULL; 914 1.26 dholland conf.cf_dump = NULL; 915 1.26 dholland } 916 1.26 dholland ; 917 1.1 thorpej 918 1.25 dholland /* root fs specification */ 919 1.1 thorpej root_spec: 920 1.28 dholland ROOT on_opt dev_spec { setconf(&conf.cf_root, "root", $3); } 921 1.28 dholland | ROOT on_opt dev_spec fs_spec { setconf(&conf.cf_root, "root", $3); } 922 1.26 dholland ; 923 1.1 thorpej 924 1.29 dholland /* device for root fs or dump */ 925 1.29 dholland dev_spec: 926 1.53 mlelstv '?' { $$ = new_spi(intern("?"), 927 1.53 mlelstv NULL, 928 1.44 christos (long long)NODEV); } 929 1.53 mlelstv | QSTRING { $$ = new_spi($1, 930 1.53 mlelstv __UNCONST("spec"), 931 1.53 mlelstv (long long)NODEV); } 932 1.53 mlelstv | WORD { $$ = new_spi($1, 933 1.53 mlelstv NULL, 934 1.44 christos (long long)NODEV); } 935 1.29 dholland | major_minor { $$ = new_si(NULL, $1); } 936 1.29 dholland ; 937 1.29 dholland 938 1.29 dholland /* major and minor device number */ 939 1.29 dholland major_minor: 940 1.46 joerg MAJOR NUMBER MINOR NUMBER { $$ = (int64_t)makedev($2.val, $4.val); } 941 1.29 dholland ; 942 1.29 dholland 943 1.25 dholland /* filesystem type for root fs specification */ 944 1.1 thorpej fs_spec: 945 1.28 dholland TYPE '?' { setfstype(&conf.cf_fstype, intern("?")); } 946 1.28 dholland | TYPE WORD { setfstype(&conf.cf_fstype, $2); } 947 1.26 dholland ; 948 1.1 thorpej 949 1.25 dholland /* zero or more additional system parameters */ 950 1.1 thorpej sysparam_list: 951 1.26 dholland /* empty */ 952 1.26 dholland | sysparam_list sysparam 953 1.26 dholland ; 954 1.1 thorpej 955 1.25 dholland /* one additional system parameter (there's only one: dumps) */ 956 1.1 thorpej sysparam: 957 1.26 dholland DUMPS on_opt dev_spec { setconf(&conf.cf_dump, "dumps", $3); } 958 1.26 dholland ; 959 1.1 thorpej 960 1.25 dholland /* number of pseudo devices to configure (which is optional) */ 961 1.1 thorpej npseudo: 962 1.26 dholland /* empty */ { $$ = 1; } 963 1.44 christos | int32 { $$ = $1; } 964 1.26 dholland ; 965 1.1 thorpej 966 1.25 dholland /* name of a device to configure */ 967 1.1 thorpej device_instance: 968 1.26 dholland WORD { $$ = $1; } 969 1.26 dholland | WORD '*' { $$ = starref($1); } 970 1.26 dholland ; 971 1.1 thorpej 972 1.25 dholland /* name of a device to configure an attachment to */ 973 1.1 thorpej attachment: 974 1.26 dholland ROOT { $$ = NULL; } 975 1.26 dholland | WORD { $$ = $1; } 976 1.26 dholland | WORD '?' { $$ = wildref($1); } 977 1.26 dholland ; 978 1.1 thorpej 979 1.25 dholland /* zero or more locators */ 980 1.1 thorpej locators: 981 1.26 dholland /* empty */ { $$ = NULL; } 982 1.26 dholland | locators locator { $$ = $2; app($2, $1); } 983 1.26 dholland ; 984 1.1 thorpej 985 1.25 dholland /* one locator */ 986 1.1 thorpej locator: 987 1.36 dholland WORD '?' { $$ = MK3(loc, $1, NULL, 0); } 988 1.36 dholland | WORD values { $$ = namelocvals($1, $2); } 989 1.26 dholland ; 990 1.1 thorpej 991 1.25 dholland /* optional device flags */ 992 1.28 dholland device_flags: 993 1.26 dholland /* empty */ { $$ = 0; } 994 1.44 christos | FLAGS int32 { $$ = $2; } 995 1.26 dholland ; 996 1.1 thorpej 997 1.29 dholland /************************************************************/ 998 1.29 dholland 999 1.29 dholland /* 1000 1.33 dholland * conditions 1001 1.29 dholland */ 1002 1.29 dholland 1003 1.29 dholland 1004 1.29 dholland /* 1005 1.29 dholland * order of options is important, must use right recursion 1006 1.29 dholland * 1007 1.29 dholland * dholland 20120310: wut? 1008 1.29 dholland */ 1009 1.29 dholland 1010 1.33 dholland /* expression of conditions */ 1011 1.33 dholland condexpr: 1012 1.33 dholland cond_or_expr 1013 1.30 dholland ; 1014 1.30 dholland 1015 1.33 dholland cond_or_expr: 1016 1.33 dholland cond_and_expr 1017 1.34 dholland | cond_or_expr '|' cond_and_expr { $$ = MKF2(cx, or, $1, $3); } 1018 1.30 dholland ; 1019 1.30 dholland 1020 1.33 dholland cond_and_expr: 1021 1.33 dholland cond_prefix_expr 1022 1.34 dholland | cond_and_expr '&' cond_prefix_expr { $$ = MKF2(cx, and, $1, $3); } 1023 1.30 dholland ; 1024 1.30 dholland 1025 1.33 dholland cond_prefix_expr: 1026 1.33 dholland cond_base_expr 1027 1.30 dholland /* XXX notyet - need to strengthen downstream first */ 1028 1.34 dholland /* | '!' cond_prefix_expr { $$ = MKF1(cx, not, $2); } */ 1029 1.30 dholland ; 1030 1.30 dholland 1031 1.33 dholland cond_base_expr: 1032 1.33 dholland condatom { $$ = $1; } 1033 1.34 dholland | '!' condatom { $$ = MKF1(cx, not, $2); } 1034 1.33 dholland | '(' condexpr ')' { $$ = $2; } 1035 1.29 dholland ; 1036 1.29 dholland 1037 1.29 dholland /* basic element of config element expression: a config element */ 1038 1.33 dholland condatom: 1039 1.34 dholland WORD { $$ = MKF1(cx, atom, $1); } 1040 1.29 dholland ; 1041 1.29 dholland 1042 1.29 dholland /************************************************************/ 1043 1.29 dholland 1044 1.29 dholland /* 1045 1.29 dholland * Various nonterminals shared between the grammars. 1046 1.29 dholland */ 1047 1.29 dholland 1048 1.29 dholland /* variable name for make option */ 1049 1.29 dholland mkvarname: 1050 1.29 dholland QSTRING { $$ = $1; } 1051 1.29 dholland | WORD { $$ = $1; } 1052 1.29 dholland ; 1053 1.29 dholland 1054 1.29 dholland /* optional file for an option */ 1055 1.29 dholland optfile_opt: 1056 1.29 dholland /* empty */ { $$ = NULL; } 1057 1.29 dholland | filename { $$ = $1; } 1058 1.29 dholland ; 1059 1.29 dholland 1060 1.29 dholland /* filename. */ 1061 1.29 dholland filename: 1062 1.29 dholland QSTRING { $$ = $1; } 1063 1.29 dholland | PATHNAME { $$ = $1; } 1064 1.29 dholland ; 1065 1.29 dholland 1066 1.29 dholland /* constant value */ 1067 1.29 dholland value: 1068 1.29 dholland QSTRING { $$ = $1; } 1069 1.29 dholland | WORD { $$ = $1; } 1070 1.29 dholland | EMPTYSTRING { $$ = $1; } 1071 1.29 dholland | signed_number { 1072 1.29 dholland char bf[40]; 1073 1.29 dholland 1074 1.29 dholland (void)snprintf(bf, sizeof(bf), FORMAT($1), (long long)$1.val); 1075 1.29 dholland $$ = intern(bf); 1076 1.29 dholland } 1077 1.29 dholland ; 1078 1.29 dholland 1079 1.29 dholland /* constant value that is a string */ 1080 1.29 dholland stringvalue: 1081 1.29 dholland QSTRING { $$ = $1; } 1082 1.29 dholland | WORD { $$ = $1; } 1083 1.29 dholland ; 1084 1.29 dholland 1085 1.29 dholland /* comma-separated list of values */ 1086 1.29 dholland /* XXX why right-recursive? */ 1087 1.29 dholland values: 1088 1.36 dholland value { $$ = MKF2(loc, val, $1, NULL); } 1089 1.36 dholland | value ',' values { $$ = MKF2(loc, val, $1, $3); } 1090 1.29 dholland ; 1091 1.29 dholland 1092 1.29 dholland /* possibly negative number */ 1093 1.29 dholland signed_number: 1094 1.29 dholland NUMBER { $$ = $1; } 1095 1.29 dholland | '-' NUMBER { $$.fmt = $2.fmt; $$.val = -$2.val; } 1096 1.29 dholland ; 1097 1.29 dholland 1098 1.29 dholland /* optional ON keyword */ 1099 1.29 dholland on_opt: 1100 1.29 dholland /* empty */ 1101 1.29 dholland | ON 1102 1.29 dholland ; 1103 1.29 dholland 1104 1.1 thorpej %% 1105 1.1 thorpej 1106 1.1 thorpej void 1107 1.1 thorpej yyerror(const char *s) 1108 1.1 thorpej { 1109 1.1 thorpej 1110 1.13 christos cfgerror("%s", s); 1111 1.1 thorpej } 1112 1.1 thorpej 1113 1.31 dholland /************************************************************/ 1114 1.31 dholland 1115 1.31 dholland /* 1116 1.31 dholland * Wrap allocations that live on the parser stack so that we can free 1117 1.31 dholland * them again on error instead of leaking. 1118 1.31 dholland */ 1119 1.31 dholland 1120 1.31 dholland #define MAX_WRAP 1000 1121 1.31 dholland 1122 1.31 dholland struct wrap_entry { 1123 1.31 dholland void *ptr; 1124 1.31 dholland unsigned typecode; 1125 1.31 dholland }; 1126 1.31 dholland 1127 1.31 dholland static struct wrap_entry wrapstack[MAX_WRAP]; 1128 1.31 dholland static unsigned wrap_depth; 1129 1.31 dholland 1130 1.1 thorpej /* 1131 1.31 dholland * Remember pointer PTR with type-code CODE. 1132 1.1 thorpej */ 1133 1.1 thorpej static void 1134 1.31 dholland wrap_alloc(void *ptr, unsigned code) 1135 1.1 thorpej { 1136 1.31 dholland unsigned pos; 1137 1.31 dholland 1138 1.31 dholland if (wrap_depth >= MAX_WRAP) { 1139 1.31 dholland panic("allocation wrapper stack overflow"); 1140 1.31 dholland } 1141 1.31 dholland pos = wrap_depth++; 1142 1.31 dholland wrapstack[pos].ptr = ptr; 1143 1.31 dholland wrapstack[pos].typecode = code; 1144 1.31 dholland } 1145 1.31 dholland 1146 1.31 dholland /* 1147 1.31 dholland * We succeeded; commit to keeping everything that's been allocated so 1148 1.31 dholland * far and clear the stack. 1149 1.31 dholland */ 1150 1.31 dholland static void 1151 1.31 dholland wrap_continue(void) 1152 1.31 dholland { 1153 1.31 dholland wrap_depth = 0; 1154 1.31 dholland } 1155 1.31 dholland 1156 1.31 dholland /* 1157 1.31 dholland * We failed; destroy all the objects allocated. 1158 1.31 dholland */ 1159 1.31 dholland static void 1160 1.31 dholland wrap_cleanup(void) 1161 1.31 dholland { 1162 1.31 dholland unsigned i; 1163 1.1 thorpej 1164 1.36 dholland /* 1165 1.36 dholland * Destroy each item. Note that because everything allocated 1166 1.36 dholland * is entered on the list separately, lists and trees need to 1167 1.36 dholland * have their links blanked before being destroyed. Also note 1168 1.36 dholland * that strings are interned elsewhere and not handled by this 1169 1.36 dholland * mechanism. 1170 1.36 dholland */ 1171 1.36 dholland 1172 1.31 dholland for (i=0; i<wrap_depth; i++) { 1173 1.31 dholland switch (wrapstack[i].typecode) { 1174 1.31 dholland case WRAP_CODE_nvlist: 1175 1.31 dholland nvfree(wrapstack[i].ptr); 1176 1.31 dholland break; 1177 1.37 dholland case WRAP_CODE_defoptlist: 1178 1.37 dholland { 1179 1.37 dholland struct defoptlist *dl = wrapstack[i].ptr; 1180 1.37 dholland 1181 1.37 dholland dl->dl_next = NULL; 1182 1.37 dholland defoptlist_destroy(dl); 1183 1.37 dholland } 1184 1.37 dholland break; 1185 1.36 dholland case WRAP_CODE_loclist: 1186 1.36 dholland { 1187 1.36 dholland struct loclist *ll = wrapstack[i].ptr; 1188 1.36 dholland 1189 1.36 dholland ll->ll_next = NULL; 1190 1.36 dholland loclist_destroy(ll); 1191 1.36 dholland } 1192 1.36 dholland break; 1193 1.32 dholland case WRAP_CODE_attrlist: 1194 1.32 dholland { 1195 1.32 dholland struct attrlist *al = wrapstack[i].ptr; 1196 1.32 dholland 1197 1.32 dholland al->al_next = NULL; 1198 1.32 dholland al->al_this = NULL; 1199 1.32 dholland attrlist_destroy(al); 1200 1.32 dholland } 1201 1.32 dholland break; 1202 1.36 dholland case WRAP_CODE_condexpr: 1203 1.36 dholland { 1204 1.36 dholland struct condexpr *cx = wrapstack[i].ptr; 1205 1.36 dholland 1206 1.36 dholland cx->cx_type = CX_ATOM; 1207 1.36 dholland cx->cx_atom = NULL; 1208 1.36 dholland condexpr_destroy(cx); 1209 1.36 dholland } 1210 1.36 dholland break; 1211 1.31 dholland default: 1212 1.31 dholland panic("invalid code %u on allocation wrapper stack", 1213 1.31 dholland wrapstack[i].typecode); 1214 1.31 dholland } 1215 1.31 dholland } 1216 1.32 dholland 1217 1.31 dholland wrap_depth = 0; 1218 1.1 thorpej } 1219 1.1 thorpej 1220 1.31 dholland /* 1221 1.31 dholland * Instantiate the wrapper functions. 1222 1.31 dholland * 1223 1.31 dholland * Each one calls wrap_alloc to save the pointer and then returns the 1224 1.31 dholland * pointer again; these need to be generated with the preprocessor in 1225 1.31 dholland * order to be typesafe. 1226 1.31 dholland */ 1227 1.31 dholland #define DEF_ALLOCWRAP(t) \ 1228 1.31 dholland static struct t * \ 1229 1.31 dholland wrap_mk_##t(struct t *arg) \ 1230 1.31 dholland { \ 1231 1.31 dholland wrap_alloc(arg, WRAP_CODE_##t); \ 1232 1.31 dholland return arg; \ 1233 1.31 dholland } 1234 1.31 dholland 1235 1.31 dholland DEF_ALLOCWRAP(nvlist); 1236 1.37 dholland DEF_ALLOCWRAP(defoptlist); 1237 1.36 dholland DEF_ALLOCWRAP(loclist); 1238 1.32 dholland DEF_ALLOCWRAP(attrlist); 1239 1.34 dholland DEF_ALLOCWRAP(condexpr); 1240 1.32 dholland 1241 1.32 dholland /************************************************************/ 1242 1.32 dholland 1243 1.32 dholland /* 1244 1.32 dholland * Data constructors 1245 1.36 dholland * 1246 1.36 dholland * (These are *beneath* the allocation wrappers.) 1247 1.32 dholland */ 1248 1.32 dholland 1249 1.37 dholland static struct defoptlist * 1250 1.37 dholland mk_defoptlist(const char *name, const char *val, const char *lintval) 1251 1.37 dholland { 1252 1.37 dholland return defoptlist_create(name, val, lintval); 1253 1.37 dholland } 1254 1.37 dholland 1255 1.36 dholland static struct loclist * 1256 1.36 dholland mk_loc(const char *name, const char *str, long long num) 1257 1.36 dholland { 1258 1.36 dholland return loclist_create(name, str, num); 1259 1.36 dholland } 1260 1.36 dholland 1261 1.36 dholland static struct loclist * 1262 1.36 dholland mk_loc_val(const char *str, struct loclist *next) 1263 1.36 dholland { 1264 1.36 dholland struct loclist *ll; 1265 1.36 dholland 1266 1.36 dholland ll = mk_loc(NULL, str, 0); 1267 1.36 dholland ll->ll_next = next; 1268 1.36 dholland return ll; 1269 1.36 dholland } 1270 1.36 dholland 1271 1.32 dholland static struct attrlist * 1272 1.32 dholland mk_attrlist(struct attrlist *next, struct attr *a) 1273 1.32 dholland { 1274 1.32 dholland return attrlist_cons(next, a); 1275 1.32 dholland } 1276 1.31 dholland 1277 1.34 dholland static struct condexpr * 1278 1.34 dholland mk_cx_atom(const char *s) 1279 1.34 dholland { 1280 1.34 dholland struct condexpr *cx; 1281 1.34 dholland 1282 1.34 dholland cx = condexpr_create(CX_ATOM); 1283 1.34 dholland cx->cx_atom = s; 1284 1.34 dholland return cx; 1285 1.34 dholland } 1286 1.34 dholland 1287 1.34 dholland static struct condexpr * 1288 1.34 dholland mk_cx_not(struct condexpr *sub) 1289 1.34 dholland { 1290 1.34 dholland struct condexpr *cx; 1291 1.34 dholland 1292 1.34 dholland cx = condexpr_create(CX_NOT); 1293 1.34 dholland cx->cx_not = sub; 1294 1.34 dholland return cx; 1295 1.34 dholland } 1296 1.34 dholland 1297 1.34 dholland static struct condexpr * 1298 1.34 dholland mk_cx_and(struct condexpr *left, struct condexpr *right) 1299 1.34 dholland { 1300 1.34 dholland struct condexpr *cx; 1301 1.34 dholland 1302 1.34 dholland cx = condexpr_create(CX_AND); 1303 1.34 dholland cx->cx_and.left = left; 1304 1.34 dholland cx->cx_and.right = right; 1305 1.34 dholland return cx; 1306 1.34 dholland } 1307 1.34 dholland 1308 1.34 dholland static struct condexpr * 1309 1.34 dholland mk_cx_or(struct condexpr *left, struct condexpr *right) 1310 1.34 dholland { 1311 1.34 dholland struct condexpr *cx; 1312 1.34 dholland 1313 1.34 dholland cx = condexpr_create(CX_OR); 1314 1.34 dholland cx->cx_or.left = left; 1315 1.34 dholland cx->cx_or.right = right; 1316 1.34 dholland return cx; 1317 1.34 dholland } 1318 1.34 dholland 1319 1.31 dholland /************************************************************/ 1320 1.31 dholland 1321 1.1 thorpej static void 1322 1.20 pooka setmachine(const char *mch, const char *mcharch, struct nvlist *mchsubarches, 1323 1.20 pooka int isioconf) 1324 1.1 thorpej { 1325 1.1 thorpej char buf[MAXPATHLEN]; 1326 1.1 thorpej struct nvlist *nv; 1327 1.1 thorpej 1328 1.20 pooka if (isioconf) { 1329 1.20 pooka if (include(_PATH_DEVNULL, ENDDEFS, 0, 0) != 0) 1330 1.20 pooka exit(1); 1331 1.20 pooka ioconfname = mch; 1332 1.20 pooka return; 1333 1.20 pooka } 1334 1.20 pooka 1335 1.1 thorpej machine = mch; 1336 1.1 thorpej machinearch = mcharch; 1337 1.1 thorpej machinesubarches = mchsubarches; 1338 1.1 thorpej 1339 1.1 thorpej /* 1340 1.14 cube * Define attributes for all the given names 1341 1.14 cube */ 1342 1.15 cube if (defattr(machine, NULL, NULL, 0) != 0 || 1343 1.15 cube (machinearch != NULL && 1344 1.15 cube defattr(machinearch, NULL, NULL, 0) != 0)) 1345 1.14 cube exit(1); 1346 1.14 cube for (nv = machinesubarches; nv != NULL; nv = nv->nv_next) { 1347 1.14 cube if (defattr(nv->nv_name, NULL, NULL, 0) != 0) 1348 1.14 cube exit(1); 1349 1.14 cube } 1350 1.14 cube 1351 1.14 cube /* 1352 1.1 thorpej * Set up the file inclusion stack. This empty include tells 1353 1.1 thorpej * the parser there are no more device definitions coming. 1354 1.1 thorpej */ 1355 1.20 pooka if (include(_PATH_DEVNULL, ENDDEFS, 0, 0) != 0) 1356 1.1 thorpej exit(1); 1357 1.1 thorpej 1358 1.1 thorpej /* Include arch/${MACHINE}/conf/files.${MACHINE} */ 1359 1.1 thorpej (void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s", 1360 1.1 thorpej machine, machine); 1361 1.1 thorpej if (include(buf, ENDFILE, 0, 0) != 0) 1362 1.1 thorpej exit(1); 1363 1.1 thorpej 1364 1.1 thorpej /* Include any arch/${MACHINE_SUBARCH}/conf/files.${MACHINE_SUBARCH} */ 1365 1.1 thorpej for (nv = machinesubarches; nv != NULL; nv = nv->nv_next) { 1366 1.1 thorpej (void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s", 1367 1.1 thorpej nv->nv_name, nv->nv_name); 1368 1.1 thorpej if (include(buf, ENDFILE, 0, 0) != 0) 1369 1.1 thorpej exit(1); 1370 1.1 thorpej } 1371 1.1 thorpej 1372 1.1 thorpej /* Include any arch/${MACHINE_ARCH}/conf/files.${MACHINE_ARCH} */ 1373 1.1 thorpej if (machinearch != NULL) 1374 1.1 thorpej (void)snprintf(buf, sizeof(buf), "arch/%s/conf/files.%s", 1375 1.1 thorpej machinearch, machinearch); 1376 1.1 thorpej else 1377 1.1 thorpej strlcpy(buf, _PATH_DEVNULL, sizeof(buf)); 1378 1.1 thorpej if (include(buf, ENDFILE, 0, 0) != 0) 1379 1.1 thorpej exit(1); 1380 1.1 thorpej 1381 1.1 thorpej /* 1382 1.1 thorpej * Include the global conf/files. As the last thing 1383 1.1 thorpej * pushed on the stack, it will be processed first. 1384 1.1 thorpej */ 1385 1.1 thorpej if (include("conf/files", ENDFILE, 0, 0) != 0) 1386 1.1 thorpej exit(1); 1387 1.2 martin 1388 1.2 martin oktopackage = 1; 1389 1.1 thorpej } 1390 1.1 thorpej 1391 1.1 thorpej static void 1392 1.1 thorpej check_maxpart(void) 1393 1.1 thorpej { 1394 1.1 thorpej 1395 1.20 pooka if (maxpartitions <= 0 && ioconfname == NULL) { 1396 1.1 thorpej stop("cannot proceed without maxpartitions specifier"); 1397 1.1 thorpej } 1398 1.1 thorpej } 1399 1.1 thorpej 1400 1.1 thorpej static void 1401 1.4 cube check_version(void) 1402 1.4 cube { 1403 1.4 cube /* 1404 1.4 cube * In essence, version is 0 and is not supported anymore 1405 1.4 cube */ 1406 1.4 cube if (version < CONFIG_MINVERSION) 1407 1.4 cube stop("your sources are out of date -- please update."); 1408 1.4 cube } 1409 1.4 cube 1410 1.36 dholland /* 1411 1.36 dholland * Prepend a blank entry to the locator definitions so the code in 1412 1.36 dholland * sem.c can distinguish "empty locator list" from "no locator list". 1413 1.36 dholland * XXX gross. 1414 1.36 dholland */ 1415 1.36 dholland static struct loclist * 1416 1.36 dholland present_loclist(struct loclist *ll) 1417 1.36 dholland { 1418 1.36 dholland struct loclist *ret; 1419 1.36 dholland 1420 1.36 dholland ret = MK3(loc, "", NULL, 0); 1421 1.36 dholland ret->ll_next = ll; 1422 1.36 dholland return ret; 1423 1.36 dholland } 1424 1.36 dholland 1425 1.4 cube static void 1426 1.36 dholland app(struct loclist *p, struct loclist *q) 1427 1.1 thorpej { 1428 1.36 dholland while (p->ll_next) 1429 1.36 dholland p = p->ll_next; 1430 1.36 dholland p->ll_next = q; 1431 1.1 thorpej } 1432 1.1 thorpej 1433 1.36 dholland static struct loclist * 1434 1.36 dholland locarray(const char *name, int count, struct loclist *adefs, int opt) 1435 1.1 thorpej { 1436 1.36 dholland struct loclist *defs = adefs; 1437 1.36 dholland struct loclist **p; 1438 1.1 thorpej char buf[200]; 1439 1.1 thorpej int i; 1440 1.1 thorpej 1441 1.1 thorpej if (count <= 0) { 1442 1.1 thorpej fprintf(stderr, "config: array with <= 0 size: %s\n", name); 1443 1.1 thorpej exit(1); 1444 1.1 thorpej } 1445 1.1 thorpej p = &defs; 1446 1.1 thorpej for(i = 0; i < count; i++) { 1447 1.1 thorpej if (*p == NULL) 1448 1.36 dholland *p = MK3(loc, NULL, "0", 0); 1449 1.1 thorpej snprintf(buf, sizeof(buf), "%s%c%d", name, ARRCHR, i); 1450 1.36 dholland (*p)->ll_name = i == 0 ? name : intern(buf); 1451 1.36 dholland (*p)->ll_num = i > 0 || opt; 1452 1.36 dholland p = &(*p)->ll_next; 1453 1.1 thorpej } 1454 1.1 thorpej *p = 0; 1455 1.1 thorpej return defs; 1456 1.1 thorpej } 1457 1.1 thorpej 1458 1.1 thorpej 1459 1.36 dholland static struct loclist * 1460 1.36 dholland namelocvals(const char *name, struct loclist *vals) 1461 1.1 thorpej { 1462 1.36 dholland struct loclist *p; 1463 1.1 thorpej char buf[200]; 1464 1.1 thorpej int i; 1465 1.1 thorpej 1466 1.36 dholland for (i = 0, p = vals; p; i++, p = p->ll_next) { 1467 1.1 thorpej snprintf(buf, sizeof(buf), "%s%c%d", name, ARRCHR, i); 1468 1.36 dholland p->ll_name = i == 0 ? name : intern(buf); 1469 1.1 thorpej } 1470 1.1 thorpej return vals; 1471 1.1 thorpej } 1472 1.1 thorpej 1473