1 %union { 2 char *str; 3 int val; 4 struct file_list *file; 5 } 6 7 %token ANY 8 %token AT 9 %token BUS 10 %token COMMA 11 %token CONFIG 12 %token CONFIG_MACHINE 13 %token CONFIG_MACHINE_ARCH 14 %token CONFIG_PLATFORM 15 %token CPU 16 %token DEVICE 17 %token DISABLE 18 %token DRIVE 19 %token DRQ 20 %token EQUALS 21 %token FLAGS 22 %token IDENT 23 %token IOMEM 24 %token IOSIZ 25 %token IRQ 26 %token MAXUSERS 27 %token MINUS 28 %token NEXUS 29 %token OPTIONS 30 %token MAKEOPTIONS 31 %token PORT 32 %token PSEUDO_DEVICE 33 %token SEMICOLON 34 %token TARGET 35 %token TTY 36 %token UNIT 37 %token VECTOR 38 39 %token <str> ID 40 %token <val> NUMBER 41 %token <val> FPNUMBER 42 43 %type <str> Save_id 44 %type <str> Opt_value 45 %type <str> Dev 46 %type <str> device_name 47 48 %{ 49 50 /* 51 * Copyright (c) 1988, 1993 52 * The Regents of the University of California. All rights reserved. 53 * 54 * Redistribution and use in source and binary forms, with or without 55 * modification, are permitted provided that the following conditions 56 * are met: 57 * 1. Redistributions of source code must retain the above copyright 58 * notice, this list of conditions and the following disclaimer. 59 * 2. Redistributions in binary form must reproduce the above copyright 60 * notice, this list of conditions and the following disclaimer in the 61 * documentation and/or other materials provided with the distribution. 62 * 3. All advertising materials mentioning features or use of this software 63 * must display the following acknowledgement: 64 * This product includes software developed by the University of 65 * California, Berkeley and its contributors. 66 * 4. Neither the name of the University nor the names of its contributors 67 * may be used to endorse or promote products derived from this software 68 * without specific prior written permission. 69 * 70 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 71 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 72 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 73 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 74 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 75 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 76 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 77 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 78 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 79 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 80 * SUCH DAMAGE. 81 * 82 * @(#)config.y 8.1 (Berkeley) 6/6/93 83 * $FreeBSD: src/usr.sbin/config/config.y,v 1.42.2.1 2001/01/23 00:09:32 peter Exp $ 84 * $DragonFly: src/usr.sbin/config/config.y,v 1.15 2008/05/01 09:24:42 swildner Exp $ 85 */ 86 87 #include <ctype.h> 88 #include <err.h> 89 #include <stdio.h> 90 #include <string.h> 91 92 #include "config.h" 93 94 static struct device cur; 95 static struct device *curp = 0; 96 97 struct device *dtab; 98 char *ident; 99 int yyline; 100 struct file_list *ftab; 101 char errbuf[80]; 102 int maxusers; 103 104 static int connect(char *, int); 105 static void yyerror(const char *s); 106 107 int yylex(void); 108 109 %} 110 %% 111 Configuration: 112 Many_specs 113 ; 114 115 Many_specs: 116 Many_specs Spec 117 | 118 /* lambda */ 119 ; 120 121 Spec: 122 Device_spec SEMICOLON 123 = { newdev(&cur); } | 124 Config_spec SEMICOLON 125 | 126 SEMICOLON 127 | 128 error SEMICOLON 129 ; 130 131 Config_spec: 132 CONFIG_PLATFORM Save_id 133 = { 134 if (platformname != NULL) { 135 errx(1, "%d: only one platform directive is allowed", 136 yyline); 137 } 138 platformname = $2; 139 } | 140 CONFIG_MACHINE Save_id 141 = { 142 if (machinename != NULL) { 143 errx(1, "%d: only one machine directive is allowed", 144 yyline); 145 } 146 machinename = $2; 147 } | 148 CONFIG_MACHINE_ARCH Save_id 149 = { 150 if (machinearchname != NULL) { 151 errx(1, "%d: only one machine_arch directive is allowed", 152 yyline); 153 } 154 machinearchname = $2; 155 } | 156 CPU Save_id 157 = { 158 struct cputype *cp; 159 160 cp = malloc(sizeof(struct cputype)); 161 bzero(cp, sizeof(*cp)); 162 cp->cpu_name = $2; 163 cp->cpu_next = cputype; 164 cputype = cp; 165 } | 166 OPTIONS Opt_list 167 | 168 MAKEOPTIONS Mkopt_list 169 | 170 IDENT ID 171 = { ident = $2; } | 172 System_spec 173 | 174 MAXUSERS NUMBER 175 = { maxusers = $2; }; 176 177 System_spec: 178 CONFIG System_id System_parameter_list 179 = { errx(1,"line %d: root/dump/swap specifications obsolete", yyline);} 180 | 181 CONFIG System_id 182 ; 183 184 System_id: 185 Save_id 186 = { 187 struct opt *op; 188 189 op = malloc(sizeof(struct opt)); 190 bzero(op, sizeof(*op)); 191 op->op_name = strdup("KERNEL"); 192 op->op_ownfile = 0; 193 op->op_next = mkopt; 194 op->op_value = $1; 195 op->op_line = yyline + 1; 196 mkopt = op; 197 }; 198 199 System_parameter_list: 200 System_parameter_list ID 201 | ID 202 ; 203 204 device_name: 205 Save_id 206 = { $$ = $1; } 207 | Save_id NUMBER 208 = { 209 char buf[80]; 210 211 snprintf(buf, sizeof(buf), "%s%d", $1, $2); 212 $$ = strdup(buf); 213 free($1); 214 } 215 | Save_id NUMBER ID 216 = { 217 char buf[80]; 218 219 snprintf(buf, sizeof(buf), "%s%d%s", $1, $2, $3); 220 $$ = strdup(buf); 221 free($1); 222 } 223 | Save_id NUMBER ID NUMBER 224 = { 225 char buf[80]; 226 227 snprintf(buf, sizeof(buf), "%s%d%s%d", 228 $1, $2, $3, $4); 229 $$ = strdup(buf); 230 free($1); 231 } 232 | Save_id NUMBER ID NUMBER ID 233 = { 234 char buf[80]; 235 236 snprintf(buf, sizeof(buf), "%s%d%s%d%s", 237 $1, $2, $3, $4, $5); 238 $$ = strdup(buf); 239 free($1); 240 } 241 ; 242 243 Opt_list: 244 Opt_list COMMA Option 245 | 246 Option 247 ; 248 249 Option: 250 Save_id 251 = { 252 struct opt *op; 253 254 op = malloc(sizeof(struct opt)); 255 bzero(op, sizeof(*op)); 256 op->op_name = $1; 257 op->op_next = opt; 258 op->op_value = 0; 259 /* 260 * op->op_line is 1-based; yyline is 0-based but is now 1 261 * larger than when `Save_id' was lexed. 262 */ 263 op->op_line = yyline; 264 opt = op; 265 if (strchr(op->op_name, '=') != NULL) 266 errx(1, "line %d: The `=' in options should not be quoted", yyline); 267 } | 268 Save_id EQUALS Opt_value 269 = { 270 struct opt *op; 271 272 op = malloc(sizeof(struct opt)); 273 bzero(op, sizeof(*op)); 274 op->op_name = $1; 275 op->op_next = opt; 276 op->op_value = $3; 277 op->op_line = yyline + 1; 278 opt = op; 279 } ; 280 281 Opt_value: 282 ID 283 = { $$ = $1; } | 284 NUMBER 285 = { 286 char buf[80]; 287 288 snprintf(buf, sizeof(buf), "%d", $1); 289 $$ = strdup(buf); 290 } ; 291 292 Save_id: 293 ID 294 = { $$ = $1; } 295 ; 296 297 Mkopt_list: 298 Mkopt_list COMMA Mkoption 299 | 300 Mkoption 301 ; 302 303 Mkoption: 304 Save_id EQUALS Opt_value 305 = { 306 struct opt *op; 307 308 op = malloc(sizeof(struct opt)); 309 bzero(op, sizeof(*op)); 310 op->op_name = $1; 311 op->op_ownfile = 0; /* for now */ 312 op->op_next = mkopt; 313 op->op_value = $3; 314 op->op_line = yyline + 1; 315 mkopt = op; 316 } ; 317 318 Dev: 319 ID 320 = { $$ = $1; } 321 ; 322 323 Device_spec: 324 DEVICE Dev_spec 325 = { cur.d_type = DEVICE; } | 326 PSEUDO_DEVICE Init_dev Dev 327 = { 328 cur.d_name = $3; 329 cur.d_type = PSEUDO_DEVICE; 330 } | 331 PSEUDO_DEVICE Init_dev Dev NUMBER 332 = { 333 cur.d_name = $3; 334 cur.d_type = PSEUDO_DEVICE; 335 cur.d_count = $4; 336 } ; 337 338 Dev_spec: 339 Init_dev Dev 340 = { 341 cur.d_name = $2; 342 cur.d_unit = UNKNOWN; 343 } | 344 Init_dev Dev NUMBER Dev_info 345 = { 346 cur.d_name = $2; 347 cur.d_unit = $3; 348 }; 349 350 Init_dev: 351 /* lambda */ 352 = { init_dev(&cur); }; 353 354 Dev_info: 355 Con_info Info_list 356 | 357 /* lambda */ 358 ; 359 360 Con_info: 361 AT Dev NUMBER 362 = { 363 connect($2, $3); 364 cur.d_conn = $2; 365 cur.d_connunit = $3; 366 } | 367 AT NEXUS NUMBER 368 = { 369 cur.d_conn = "nexus"; 370 cur.d_connunit = 0; 371 }; 372 373 Info_list: 374 Info_list Info 375 | 376 /* lambda */ 377 ; 378 379 Info: 380 BUS NUMBER /* device scbus1 at ahc0 bus 1 - twin channel */ 381 = { cur.d_bus = $2; } | 382 TARGET NUMBER 383 = { cur.d_target = $2; } | 384 UNIT NUMBER 385 = { cur.d_lun = $2; } | 386 DRIVE NUMBER 387 = { cur.d_drive = $2; } | 388 IRQ NUMBER 389 = { cur.d_irq = $2; } | 390 DRQ NUMBER 391 = { cur.d_drq = $2; } | 392 IOMEM NUMBER 393 = { cur.d_maddr = $2; } | 394 IOSIZ NUMBER 395 = { cur.d_msize = $2; } | 396 PORT device_name 397 = { cur.d_port = $2; } | 398 PORT NUMBER 399 = { cur.d_portn = $2; } | 400 FLAGS NUMBER 401 = { cur.d_flags = $2; } | 402 DISABLE 403 = { cur.d_disabled = 1; } 404 405 %% 406 407 static void 408 yyerror(const char *s) 409 { 410 411 errx(1, "line %d: %s", yyline + 1, s); 412 } 413 414 /* 415 * add a device to the list of devices 416 */ 417 static void 418 newdev(struct device *dp) 419 { 420 struct device *np, *xp; 421 422 if (dp->d_unit >= 0) { 423 for (xp = dtab; xp != NULL; xp = xp->d_next) { 424 if ((xp->d_unit == dp->d_unit) && 425 !strcmp(xp->d_name, dp->d_name)) { 426 errx(1, "line %d: already seen device %s%d", 427 yyline, xp->d_name, xp->d_unit); 428 } 429 } 430 } 431 np = malloc(sizeof(*np)); 432 bzero(np, sizeof(*np)); 433 *np = *dp; 434 np->d_next = NULL; 435 if (curp == NULL) 436 dtab = np; 437 else 438 curp->d_next = np; 439 curp = np; 440 } 441 442 443 /* 444 * find the pointer to connect to the given device and number. 445 * returns 0 if no such device and prints an error message 446 */ 447 static int 448 connect(char *dev, int num) 449 { 450 struct device *dp; 451 452 if (num == QUES) { 453 for (dp = dtab; dp != NULL; dp = dp->d_next) 454 if (!strcmp(dp->d_name, dev)) 455 break; 456 if (dp == NULL) { 457 snprintf(errbuf, sizeof(errbuf), 458 "no %s's to wildcard", dev); 459 yyerror(errbuf); 460 return(0); 461 } 462 return(1); 463 } 464 for (dp = dtab; dp != NULL; dp = dp->d_next) { 465 if ((num != dp->d_unit) || strcmp(dev, dp->d_name)) 466 continue; 467 if (dp->d_type != DEVICE) { 468 snprintf(errbuf, sizeof(errbuf), 469 "%s connected to non-device", dev); 470 yyerror(errbuf); 471 return(0); 472 } 473 return(1); 474 } 475 snprintf(errbuf, sizeof(errbuf), "%s %d not defined", dev, num); 476 yyerror(errbuf); 477 return(0); 478 } 479 480 void 481 init_dev(struct device *dp) 482 { 483 484 dp->d_name = "OHNO!!!"; 485 dp->d_type = DEVICE; 486 dp->d_conn = 0; 487 dp->d_disabled = 0; 488 dp->d_flags = 0; 489 dp->d_bus = dp->d_lun = dp->d_target = dp->d_drive = dp->d_unit = 490 dp->d_count = UNKNOWN; 491 dp->d_port = NULL; 492 dp->d_portn = -1; 493 dp->d_irq = -1; 494 dp->d_drq = -1; 495 dp->d_maddr = 0; 496 dp->d_msize = 0; 497 } 498