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 * Find a device in the list of devices. 347 */ 348 static struct device * 349 finddev(char *name) 350 { 351 struct device *dp; 352 353 STAILQ_FOREACH(dp, &dtab, d_next) 354 if (eq(dp->d_name, name)) 355 return (dp); 356 357 return (NULL); 358 } 359 360 /* 361 * Add a device to the list of devices. 362 */ 363 static void 364 newdev(char *name) 365 { 366 struct device *np; 367 368 if (finddev(name)) { 369 printf("WARNING: duplicate device `%s' encountered.\n", name); 370 return; 371 } 372 373 np = (struct device *) malloc(sizeof *np); 374 memset(np, 0, sizeof(*np)); 375 np->d_name = name; 376 STAILQ_INSERT_TAIL(&dtab, np, d_next); 377 } 378 379 /* 380 * Remove a device from the list of devices. 381 */ 382 static void 383 rmdev(char *name) 384 { 385 struct device *dp; 386 387 dp = finddev(name); 388 if (dp != NULL) { 389 STAILQ_REMOVE(&dtab, dp, device, d_next); 390 free(dp->d_name); 391 free(dp); 392 } 393 } 394 395 /* 396 * Find an option in the list of options. 397 */ 398 static struct opt * 399 findopt(struct opt_head *list, char *name) 400 { 401 struct opt *op; 402 403 SLIST_FOREACH(op, list, op_next) 404 if (eq(op->op_name, name)) 405 return (op); 406 407 return (NULL); 408 } 409 410 /* 411 * Add an option to the list of options. 412 */ 413 static void 414 newopt(struct opt_head *list, char *name, char *value) 415 { 416 struct opt *op; 417 418 if (findopt(list, name)) { 419 printf("WARNING: duplicate option `%s' encountered.\n", name); 420 return; 421 } 422 423 op = (struct opt *)malloc(sizeof (struct opt)); 424 memset(op, 0, sizeof(*op)); 425 op->op_name = name; 426 op->op_ownfile = 0; 427 op->op_value = value; 428 SLIST_INSERT_HEAD(list, op, op_next); 429 } 430 431 /* 432 * Remove an option from the list of options. 433 */ 434 static void 435 rmopt(struct opt_head *list, char *name) 436 { 437 struct opt *op; 438 439 op = findopt(list, name); 440 if (op != NULL) { 441 SLIST_REMOVE(list, op, opt, op_next); 442 free(op->op_name); 443 if (op->op_value != NULL) 444 free(op->op_value); 445 free(op); 446 } 447 } 448