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