1 %union { 2 char *str; 3 int val; 4 struct file_list *file; 5 } 6 7 %token ARCH 8 %token COMMA 9 %token CONFIG 10 %token CPU 11 %token NOCPU 12 %token DEVICE 13 %token NODEVICE 14 %token ENV 15 %token EQUALS 16 %token HINTS 17 %token IDENT 18 %token MAXUSERS 19 %token PROFILE 20 %token OPTIONS 21 %token NOOPTION 22 %token MAKEOPTIONS 23 %token NOMAKEOPTION 24 %token SEMICOLON 25 %token INCLUDE 26 %token FILES 27 28 %token <str> ID 29 %token <val> NUMBER 30 31 %type <str> Save_id 32 %type <str> Opt_value 33 %type <str> Dev 34 35 %{ 36 37 /* 38 * Copyright (c) 1988, 1993 39 * The Regents of the University of California. All rights reserved. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. All advertising materials mentioning features or use of this software 50 * must display the following acknowledgement: 51 * This product includes software developed by the University of 52 * California, Berkeley and its contributors. 53 * 4. Neither the name of the University nor the names of its contributors 54 * may be used to endorse or promote products derived from this software 55 * without specific prior written permission. 56 * 57 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 58 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 59 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 60 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 61 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 62 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 63 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 64 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 65 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 67 * SUCH DAMAGE. 68 * 69 * @(#)config.y 8.1 (Berkeley) 6/6/93 70 * $FreeBSD$ 71 */ 72 73 #include <ctype.h> 74 #include <err.h> 75 #include <stdio.h> 76 #include <string.h> 77 78 #include "config.h" 79 80 struct device_head dtab; 81 char *ident; 82 char *env; 83 int envmode; 84 char *hints; 85 int hintmode; 86 int yyline; 87 const char *yyfile; 88 struct file_list_head ftab; 89 struct files_name_head fntab; 90 char errbuf[80]; 91 int maxusers; 92 93 #define ns(s) strdup(s) 94 int include(const char *, int); 95 void yyerror(const char *s); 96 int yywrap(void); 97 98 static char * 99 devopt(char *dev) 100 { 101 char *ret = malloc(strlen(dev) + 5); 102 103 sprintf(ret, "DEV_%s", dev); 104 raisestr(ret); 105 return ret; 106 } 107 108 %} 109 %% 110 Configuration: 111 Many_specs 112 ; 113 114 Many_specs: 115 Many_specs Spec 116 | 117 /* lambda */ 118 ; 119 120 Spec: 121 Device_spec SEMICOLON 122 | 123 Config_spec SEMICOLON 124 | 125 INCLUDE ID SEMICOLON 126 = { include($2, 0); }; 127 | 128 FILES ID SEMICOLON 129 = { newfile($2); }; 130 | 131 SEMICOLON 132 | 133 error SEMICOLON 134 ; 135 136 Config_spec: 137 ARCH Save_id 138 = { 139 if (machinename != NULL && !eq($2, machinename)) 140 errx(1, "%s:%d: only one machine directive is allowed", 141 yyfile, yyline); 142 machinename = $2; 143 machinearch = $2; 144 } | 145 ARCH Save_id Save_id 146 = { 147 if (machinename != NULL && 148 !(eq($2, machinename) && eq($3, machinearch))) 149 errx(1, "%s:%d: only one machine directive is allowed", 150 yyfile, yyline); 151 machinename = $2; 152 machinearch = $3; 153 } | 154 CPU Save_id 155 = { 156 struct cputype *cp = 157 (struct cputype *)malloc(sizeof (struct cputype)); 158 memset(cp, 0, sizeof(*cp)); 159 cp->cpu_name = $2; 160 SLIST_INSERT_HEAD(&cputype, cp, cpu_next); 161 } | 162 NOCPU Save_id 163 = { 164 struct cputype *cp, *cp2; 165 SLIST_FOREACH_SAFE(cp, &cputype, cpu_next, cp2) { 166 if (eq(cp->cpu_name, $2)) { 167 SLIST_REMOVE(&cputype, cp, cputype, cpu_next); 168 free(cp); 169 } 170 } 171 } | 172 OPTIONS Opt_list 173 | 174 NOOPTION Save_id 175 = { rmopt(&opt, $2); } | 176 MAKEOPTIONS Mkopt_list 177 | 178 NOMAKEOPTION Save_id 179 = { rmopt(&mkopt, $2); } | 180 IDENT ID 181 = { ident = $2; } | 182 System_spec 183 | 184 MAXUSERS NUMBER 185 = { maxusers = $2; } | 186 PROFILE NUMBER 187 = { profiling = $2; } | 188 ENV ID 189 = { 190 env = $2; 191 envmode = 1; 192 } | 193 HINTS ID 194 = { 195 hints = $2; 196 hintmode = 1; 197 } 198 199 System_spec: 200 CONFIG System_id System_parameter_list 201 = { errx(1, "%s:%d: root/dump/swap specifications obsolete", 202 yyfile, yyline);} 203 | 204 CONFIG System_id 205 ; 206 207 System_id: 208 Save_id 209 = { newopt(&mkopt, ns("KERNEL"), $1); }; 210 211 System_parameter_list: 212 System_parameter_list ID 213 | ID 214 ; 215 216 Opt_list: 217 Opt_list COMMA Option 218 | 219 Option 220 ; 221 222 Option: 223 Save_id 224 = { 225 char *s; 226 227 newopt(&opt, $1, NULL); 228 if ((s = strchr($1, '='))) 229 errx(1, "%s:%d: The `=' in options should not be " 230 "quoted", yyfile, yyline); 231 } | 232 Save_id EQUALS Opt_value 233 = { 234 newopt(&opt, $1, $3); 235 } ; 236 237 Opt_value: 238 ID 239 = { $$ = $1; } | 240 NUMBER 241 = { 242 char buf[80]; 243 244 (void) snprintf(buf, sizeof(buf), "%d", $1); 245 $$ = ns(buf); 246 } ; 247 248 Save_id: 249 ID 250 = { $$ = $1; } 251 ; 252 253 Mkopt_list: 254 Mkopt_list COMMA Mkoption 255 | 256 Mkoption 257 ; 258 259 Mkoption: 260 Save_id 261 = { newopt(&mkopt, $1, ns("")); } | 262 Save_id EQUALS Opt_value 263 = { newopt(&mkopt, $1, $3); } ; 264 265 Dev: 266 ID 267 = { $$ = $1; } 268 ; 269 270 Device_spec: 271 DEVICE Dev_list 272 | 273 NODEVICE NoDev_list 274 ; 275 276 Dev_list: 277 Dev_list COMMA Device 278 | 279 Device 280 ; 281 282 NoDev_list: 283 NoDev_list COMMA NoDevice 284 | 285 NoDevice 286 ; 287 288 Device: 289 Dev 290 = { 291 newopt(&opt, devopt($1), ns("1")); 292 /* and the device part */ 293 newdev($1); 294 } 295 296 NoDevice: 297 Dev 298 = { 299 char *s = devopt($1); 300 301 rmopt(&opt, s); 302 free(s); 303 /* and the device part */ 304 rmdev($1); 305 } ; 306 307 %% 308 309 void 310 yyerror(const char *s) 311 { 312 313 errx(1, "%s:%d: %s", yyfile, yyline + 1, s); 314 } 315 316 int 317 yywrap(void) 318 { 319 320 if (found_defaults) { 321 if (freopen(PREFIX, "r", stdin) == NULL) 322 err(2, "%s", PREFIX); 323 yyfile = PREFIX; 324 yyline = 0; 325 found_defaults = 0; 326 return 0; 327 } 328 return 1; 329 } 330 331 /* 332 * Add a new file to the list of files. 333 */ 334 static void 335 newfile(char *name) 336 { 337 struct files_name *nl; 338 339 nl = (struct files_name *) malloc(sizeof *nl); 340 bzero(nl, sizeof *nl); 341 nl->f_name = name; 342 STAILQ_INSERT_TAIL(&fntab, nl, f_next); 343 } 344 345 /* 346 * add a device to the list of devices 347 */ 348 static void 349 newdev(char *name) 350 { 351 struct device *np; 352 353 np = (struct device *) malloc(sizeof *np); 354 memset(np, 0, sizeof(*np)); 355 np->d_name = name; 356 STAILQ_INSERT_TAIL(&dtab, np, d_next); 357 } 358 359 /* 360 * remove a device from the list of devices 361 */ 362 static void 363 rmdev(char *name) 364 { 365 struct device *dp, *rmdp; 366 367 STAILQ_FOREACH(dp, &dtab, d_next) { 368 if (eq(dp->d_name, name)) { 369 rmdp = dp; 370 dp = STAILQ_NEXT(dp, d_next); 371 STAILQ_REMOVE(&dtab, rmdp, device, d_next); 372 free(rmdp->d_name); 373 free(rmdp); 374 if (dp == NULL) 375 break; 376 } 377 } 378 } 379 380 static void 381 newopt(struct opt_head *list, char *name, char *value) 382 { 383 struct opt *op; 384 385 op = (struct opt *)malloc(sizeof (struct opt)); 386 memset(op, 0, sizeof(*op)); 387 op->op_name = name; 388 op->op_ownfile = 0; 389 op->op_value = value; 390 SLIST_INSERT_HEAD(list, op, op_next); 391 } 392 393 static void 394 rmopt(struct opt_head *list, char *name) 395 { 396 struct opt *op, *rmop; 397 398 SLIST_FOREACH(op, list, op_next) { 399 if (eq(op->op_name, name)) { 400 rmop = op; 401 op = SLIST_NEXT(op, op_next); 402 SLIST_REMOVE(list, rmop, opt, op_next); 403 free(rmop->op_name); 404 if (rmop->op_value != NULL) 405 free(rmop->op_value); 406 free(rmop); 407 if (op == NULL) 408 break; 409 } 410 } 411 } 412