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