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.11 2005/01/12 00:26:03 cpressey 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 static int connect(char *, int); 107 static void yyerror(const char *s); 108 109 110 %} 111 %% 112 Configuration: 113 Many_specs 114 ; 115 116 Many_specs: 117 Many_specs Spec 118 | 119 /* lambda */ 120 ; 121 122 Spec: 123 Device_spec SEMICOLON 124 = { newdev(&cur); } | 125 Config_spec SEMICOLON 126 | 127 SEMICOLON 128 | 129 error SEMICOLON 130 ; 131 132 Config_spec: 133 ARCH Save_id 134 = { 135 if (machinename != NULL) { 136 errx(1, "%d: only one machine directive is allowed", 137 yyline); 138 } 139 machinename = $2; 140 } | 141 CPU Save_id 142 = { 143 struct cputype *cp; 144 145 cp = malloc(sizeof(struct cputype)); 146 bzero(cp, sizeof(*cp)); 147 cp->cpu_name = $2; 148 cp->cpu_next = cputype; 149 cputype = cp; 150 } | 151 OPTIONS Opt_list 152 | 153 MAKEOPTIONS Mkopt_list 154 | 155 IDENT ID 156 = { ident = $2; } | 157 System_spec 158 | 159 MAXUSERS NUMBER 160 = { maxusers = $2; }; 161 162 System_spec: 163 CONFIG System_id System_parameter_list 164 = { errx(1,"line %d: root/dump/swap specifications obsolete", yyline);} 165 | 166 CONFIG System_id 167 ; 168 169 System_id: 170 Save_id 171 = { 172 struct opt *op; 173 174 op = malloc(sizeof(struct opt)); 175 bzero(op, sizeof(*op)); 176 op->op_name = strdup("KERNEL"); 177 op->op_ownfile = 0; 178 op->op_next = mkopt; 179 op->op_value = $1; 180 op->op_line = yyline + 1; 181 mkopt = op; 182 }; 183 184 System_parameter_list: 185 System_parameter_list ID 186 | ID 187 ; 188 189 device_name: 190 Save_id 191 = { $$ = $1; } 192 | Save_id NUMBER 193 = { 194 char buf[80]; 195 196 snprintf(buf, sizeof(buf), "%s%d", $1, $2); 197 $$ = strdup(buf); 198 free($1); 199 } 200 | Save_id NUMBER ID 201 = { 202 char buf[80]; 203 204 snprintf(buf, sizeof(buf), "%s%d%s", $1, $2, $3); 205 $$ = strdup(buf); 206 free($1); 207 } 208 | Save_id NUMBER ID NUMBER 209 = { 210 char buf[80]; 211 212 snprintf(buf, sizeof(buf), "%s%d%s%d", 213 $1, $2, $3, $4); 214 $$ = strdup(buf); 215 free($1); 216 } 217 | Save_id NUMBER ID NUMBER ID 218 = { 219 char buf[80]; 220 221 snprintf(buf, sizeof(buf), "%s%d%s%d%s", 222 $1, $2, $3, $4, $5); 223 $$ = strdup(buf); 224 free($1); 225 } 226 ; 227 228 Opt_list: 229 Opt_list COMMA Option 230 | 231 Option 232 ; 233 234 Option: 235 Save_id 236 = { 237 struct opt *op; 238 239 op = malloc(sizeof(struct opt)); 240 bzero(op, 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 (strchr(op->op_name, '=') != NULL) 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; 256 257 op = malloc(sizeof(struct opt)); 258 bzero(op, sizeof(*op)); 259 op->op_name = $1; 260 op->op_next = opt; 261 op->op_value = $3; 262 op->op_line = yyline + 1; 263 opt = op; 264 } ; 265 266 Opt_value: 267 ID 268 = { $$ = $1; } | 269 NUMBER 270 = { 271 char buf[80]; 272 273 snprintf(buf, sizeof(buf), "%d", $1); 274 $$ = strdup(buf); 275 } ; 276 277 Save_id: 278 ID 279 = { $$ = $1; } 280 ; 281 282 Mkopt_list: 283 Mkopt_list COMMA Mkoption 284 | 285 Mkoption 286 ; 287 288 Mkoption: 289 Save_id EQUALS Opt_value 290 = { 291 struct opt *op; 292 293 op = malloc(sizeof(struct opt)); 294 bzero(op, sizeof(*op)); 295 op->op_name = $1; 296 op->op_ownfile = 0; /* for now */ 297 op->op_next = mkopt; 298 op->op_value = $3; 299 op->op_line = yyline + 1; 300 mkopt = op; 301 } ; 302 303 Dev: 304 ID 305 = { $$ = $1; } 306 ; 307 308 Device_spec: 309 DEVICE Dev_spec 310 = { cur.d_type = DEVICE; } | 311 DISK Dev_spec 312 = { 313 errx(1, "line %d: Obsolete keyword 'disk' found - use 'device'", yyline); 314 } | 315 TAPE Dev_spec 316 = { 317 errx(1, "line %d: Obsolete keyword 'tape' found - use 'device'", yyline); 318 } | 319 CONTROLLER Dev_spec 320 = { 321 errx(1, "line %d: Obsolete keyword 'controller' found - use 'device'", yyline); 322 } | 323 PSEUDO_DEVICE Init_dev Dev 324 = { 325 cur.d_name = $3; 326 cur.d_type = PSEUDO_DEVICE; 327 } | 328 PSEUDO_DEVICE Init_dev Dev NUMBER 329 = { 330 cur.d_name = $3; 331 cur.d_type = PSEUDO_DEVICE; 332 cur.d_count = $4; 333 } ; 334 335 Dev_spec: 336 Init_dev Dev 337 = { 338 cur.d_name = $2; 339 cur.d_unit = UNKNOWN; 340 } | 341 Init_dev Dev NUMBER Dev_info 342 = { 343 cur.d_name = $2; 344 cur.d_unit = $3; 345 }; 346 347 Init_dev: 348 /* lambda */ 349 = { init_dev(&cur); }; 350 351 Dev_info: 352 Con_info Info_list 353 | 354 /* lambda */ 355 ; 356 357 Con_info: 358 AT Dev NUMBER 359 = { 360 connect($2, $3); 361 cur.d_conn = $2; 362 cur.d_connunit = $3; 363 } | 364 AT NEXUS NUMBER 365 = { 366 cur.d_conn = "nexus"; 367 cur.d_connunit = 0; 368 }; 369 370 Info_list: 371 Info_list Info 372 | 373 /* lambda */ 374 ; 375 376 Info: 377 BUS NUMBER /* device scbus1 at ahc0 bus 1 - twin channel */ 378 = { cur.d_bus = $2; } | 379 TARGET NUMBER 380 = { cur.d_target = $2; } | 381 UNIT NUMBER 382 = { cur.d_lun = $2; } | 383 DRIVE NUMBER 384 = { cur.d_drive = $2; } | 385 IRQ NUMBER 386 = { cur.d_irq = $2; } | 387 DRQ NUMBER 388 = { cur.d_drq = $2; } | 389 IOMEM NUMBER 390 = { cur.d_maddr = $2; } | 391 IOSIZ NUMBER 392 = { cur.d_msize = $2; } | 393 PORT device_name 394 = { cur.d_port = $2; } | 395 PORT NUMBER 396 = { cur.d_portn = $2; } | 397 FLAGS NUMBER 398 = { cur.d_flags = $2; } | 399 DISABLE 400 = { cur.d_disabled = 1; } | 401 CONFLICTS 402 = { 403 errx(1, "line %d: Obsolete keyword 'conflicts' found", yyline); 404 }; 405 406 %% 407 408 static void 409 yyerror(const char *s) 410 { 411 412 errx(1, "line %d: %s", yyline + 1, s); 413 } 414 415 /* 416 * add a device to the list of devices 417 */ 418 static void 419 newdev(struct device *dp) 420 { 421 struct device *np, *xp; 422 423 if (dp->d_unit >= 0) { 424 for (xp = dtab; xp != NULL; xp = xp->d_next) { 425 if ((xp->d_unit == dp->d_unit) && 426 !strcmp(xp->d_name, dp->d_name)) { 427 errx(1, "line %d: already seen device %s%d", 428 yyline, xp->d_name, xp->d_unit); 429 } 430 } 431 } 432 np = malloc(sizeof(*np)); 433 bzero(np, sizeof(*np)); 434 *np = *dp; 435 np->d_next = NULL; 436 if (curp == NULL) 437 dtab = np; 438 else 439 curp->d_next = np; 440 curp = np; 441 } 442 443 444 /* 445 * find the pointer to connect to the given device and number. 446 * returns 0 if no such device and prints an error message 447 */ 448 static int 449 connect(char *dev, int num) 450 { 451 struct device *dp; 452 453 if (num == QUES) { 454 for (dp = dtab; dp != NULL; dp = dp->d_next) 455 if (!strcmp(dp->d_name, dev)) 456 break; 457 if (dp == NULL) { 458 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 != NULL; dp = dp->d_next) { 466 if ((num != dp->d_unit) || strcmp(dev, dp->d_name)) 467 continue; 468 if (dp->d_type != DEVICE) { 469 snprintf(errbuf, sizeof(errbuf), 470 "%s connected to non-device", dev); 471 yyerror(errbuf); 472 return(0); 473 } 474 return(1); 475 } 476 snprintf(errbuf, sizeof(errbuf), "%s %d not defined", dev, num); 477 yyerror(errbuf); 478 return(0); 479 } 480 481 void 482 init_dev(struct device *dp) 483 { 484 485 dp->d_name = "OHNO!!!"; 486 dp->d_type = DEVICE; 487 dp->d_conn = 0; 488 dp->d_disabled = 0; 489 dp->d_flags = 0; 490 dp->d_bus = dp->d_lun = dp->d_target = dp->d_drive = dp->d_unit = 491 dp->d_count = UNKNOWN; 492 dp->d_port = NULL; 493 dp->d_portn = -1; 494 dp->d_irq = -1; 495 dp->d_drq = -1; 496 dp->d_maddr = 0; 497 dp->d_msize = 0; 498 } 499