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