MFC: Document -f.
[dragonfly.git] / usr.sbin / config / config.y
blob4f950bd9436e19619688ae4c9b703a26ade1f33b
1 %union {
2 char *str;
3 int val;
4 struct file_list *file;
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
39 %token <str> ID
40 %token <val> NUMBER
41 %token <val> FPNUMBER
43 %type <str> Save_id
44 %type <str> Opt_value
45 %type <str> Dev
46 %type <str> device_name
51 * Copyright (c) 1988, 1993
52 * The Regents of the University of California. All rights reserved.
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.
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.
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 $
87 #include <ctype.h>
88 #include <err.h>
89 #include <stdio.h>
90 #include <string.h>
92 #include "config.h"
94 static struct device cur;
95 static struct device *curp = 0;
97 struct device *dtab;
98 char *ident;
99 int yyline;
100 struct file_list *ftab;
101 char errbuf[80];
102 int maxusers;
104 static int connect(char *, int);
105 static void yyerror(const char *s);
110 Configuration:
111 Many_specs
114 Many_specs:
115 Many_specs Spec
117 /* lambda */
120 Spec:
121 Device_spec SEMICOLON
122 = { newdev(&cur); } |
123 Config_spec SEMICOLON
125 SEMICOLON
127 error SEMICOLON
130 Config_spec:
131 CONFIG_PLATFORM Save_id
133 if (platformname != NULL) {
134 errx(1, "%d: only one platform directive is allowed",
135 yyline);
137 platformname = $2;
139 CONFIG_MACHINE Save_id
141 if (machinename != NULL) {
142 errx(1, "%d: only one machine directive is allowed",
143 yyline);
145 machinename = $2;
147 CONFIG_MACHINE_ARCH Save_id
149 if (machinearchname != NULL) {
150 errx(1, "%d: only one machine_arch directive is allowed",
151 yyline);
153 machinearchname = $2;
155 CPU Save_id
157 struct cputype *cp;
159 cp = malloc(sizeof(struct cputype));
160 bzero(cp, sizeof(*cp));
161 cp->cpu_name = $2;
162 cp->cpu_next = cputype;
163 cputype = cp;
165 OPTIONS Opt_list
167 MAKEOPTIONS Mkopt_list
169 IDENT ID
170 = { ident = $2; } |
171 System_spec
173 MAXUSERS NUMBER
174 = { maxusers = $2; };
176 System_spec:
177 CONFIG System_id System_parameter_list
178 = { errx(1,"line %d: root/dump/swap specifications obsolete", yyline);}
180 CONFIG System_id
183 System_id:
184 Save_id
186 struct opt *op;
188 op = malloc(sizeof(struct opt));
189 bzero(op, sizeof(*op));
190 op->op_name = strdup("KERNEL");
191 op->op_ownfile = 0;
192 op->op_next = mkopt;
193 op->op_value = $1;
194 op->op_line = yyline + 1;
195 mkopt = op;
198 System_parameter_list:
199 System_parameter_list ID
200 | ID
203 device_name:
204 Save_id
205 = { $$ = $1; }
206 | Save_id NUMBER
208 char buf[80];
210 snprintf(buf, sizeof(buf), "%s%d", $1, $2);
211 $$ = strdup(buf);
212 free($1);
214 | Save_id NUMBER ID
216 char buf[80];
218 snprintf(buf, sizeof(buf), "%s%d%s", $1, $2, $3);
219 $$ = strdup(buf);
220 free($1);
222 | Save_id NUMBER ID NUMBER
224 char buf[80];
226 snprintf(buf, sizeof(buf), "%s%d%s%d",
227 $1, $2, $3, $4);
228 $$ = strdup(buf);
229 free($1);
231 | Save_id NUMBER ID NUMBER ID
233 char buf[80];
235 snprintf(buf, sizeof(buf), "%s%d%s%d%s",
236 $1, $2, $3, $4, $5);
237 $$ = strdup(buf);
238 free($1);
242 Opt_list:
243 Opt_list COMMA Option
245 Option
248 Option:
249 Save_id
251 struct opt *op;
253 op = malloc(sizeof(struct opt));
254 bzero(op, sizeof(*op));
255 op->op_name = $1;
256 op->op_next = opt;
257 op->op_value = 0;
259 * op->op_line is 1-based; yyline is 0-based but is now 1
260 * larger than when `Save_id' was lexed.
262 op->op_line = yyline;
263 opt = op;
264 if (strchr(op->op_name, '=') != NULL)
265 errx(1, "line %d: The `=' in options should not be quoted", yyline);
267 Save_id EQUALS Opt_value
269 struct opt *op;
271 op = malloc(sizeof(struct opt));
272 bzero(op, sizeof(*op));
273 op->op_name = $1;
274 op->op_next = opt;
275 op->op_value = $3;
276 op->op_line = yyline + 1;
277 opt = op;
280 Opt_value:
282 = { $$ = $1; } |
283 NUMBER
285 char buf[80];
287 snprintf(buf, sizeof(buf), "%d", $1);
288 $$ = strdup(buf);
291 Save_id:
293 = { $$ = $1; }
296 Mkopt_list:
297 Mkopt_list COMMA Mkoption
299 Mkoption
302 Mkoption:
303 Save_id EQUALS Opt_value
305 struct opt *op;
307 op = malloc(sizeof(struct opt));
308 bzero(op, sizeof(*op));
309 op->op_name = $1;
310 op->op_ownfile = 0; /* for now */
311 op->op_next = mkopt;
312 op->op_value = $3;
313 op->op_line = yyline + 1;
314 mkopt = op;
317 Dev:
319 = { $$ = $1; }
322 Device_spec:
323 DEVICE Dev_spec
324 = { cur.d_type = DEVICE; } |
325 PSEUDO_DEVICE Init_dev Dev
327 cur.d_name = $3;
328 cur.d_type = PSEUDO_DEVICE;
330 PSEUDO_DEVICE Init_dev Dev NUMBER
332 cur.d_name = $3;
333 cur.d_type = PSEUDO_DEVICE;
334 cur.d_count = $4;
337 Dev_spec:
338 Init_dev Dev
340 cur.d_name = $2;
341 cur.d_unit = UNKNOWN;
343 Init_dev Dev NUMBER Dev_info
345 cur.d_name = $2;
346 cur.d_unit = $3;
349 Init_dev:
350 /* lambda */
351 = { init_dev(&cur); };
353 Dev_info:
354 Con_info Info_list
356 /* lambda */
359 Con_info:
360 AT Dev NUMBER
362 connect($2, $3);
363 cur.d_conn = $2;
364 cur.d_connunit = $3;
366 AT NEXUS NUMBER
368 cur.d_conn = "nexus";
369 cur.d_connunit = 0;
372 Info_list:
373 Info_list Info
375 /* lambda */
378 Info:
379 BUS NUMBER /* device scbus1 at ahc0 bus 1 - twin channel */
380 = { cur.d_bus = $2; } |
381 TARGET NUMBER
382 = { cur.d_target = $2; } |
383 UNIT NUMBER
384 = { cur.d_lun = $2; } |
385 DRIVE NUMBER
386 = { cur.d_drive = $2; } |
387 IRQ NUMBER
388 = { cur.d_irq = $2; } |
389 DRQ NUMBER
390 = { cur.d_drq = $2; } |
391 IOMEM NUMBER
392 = { cur.d_maddr = $2; } |
393 IOSIZ NUMBER
394 = { cur.d_msize = $2; } |
395 PORT device_name
396 = { cur.d_port = $2; } |
397 PORT NUMBER
398 = { cur.d_portn = $2; } |
399 FLAGS NUMBER
400 = { cur.d_flags = $2; } |
401 DISABLE
402 = { cur.d_disabled = 1; }
406 static void
407 yyerror(const char *s)
410 errx(1, "line %d: %s", yyline + 1, s);
414 * add a device to the list of devices
416 static void
417 newdev(struct device *dp)
419 struct device *np, *xp;
421 if (dp->d_unit >= 0) {
422 for (xp = dtab; xp != NULL; xp = xp->d_next) {
423 if ((xp->d_unit == dp->d_unit) &&
424 !strcmp(xp->d_name, dp->d_name)) {
425 errx(1, "line %d: already seen device %s%d",
426 yyline, xp->d_name, xp->d_unit);
430 np = malloc(sizeof(*np));
431 bzero(np, sizeof(*np));
432 *np = *dp;
433 np->d_next = NULL;
434 if (curp == NULL)
435 dtab = np;
436 else
437 curp->d_next = np;
438 curp = np;
443 * find the pointer to connect to the given device and number.
444 * returns 0 if no such device and prints an error message
446 static int
447 connect(char *dev, int num)
449 struct device *dp;
451 if (num == QUES) {
452 for (dp = dtab; dp != NULL; dp = dp->d_next)
453 if (!strcmp(dp->d_name, dev))
454 break;
455 if (dp == NULL) {
456 snprintf(errbuf, sizeof(errbuf),
457 "no %s's to wildcard", dev);
458 yyerror(errbuf);
459 return(0);
461 return(1);
463 for (dp = dtab; dp != NULL; dp = dp->d_next) {
464 if ((num != dp->d_unit) || strcmp(dev, dp->d_name))
465 continue;
466 if (dp->d_type != DEVICE) {
467 snprintf(errbuf, sizeof(errbuf),
468 "%s connected to non-device", dev);
469 yyerror(errbuf);
470 return(0);
472 return(1);
474 snprintf(errbuf, sizeof(errbuf), "%s %d not defined", dev, num);
475 yyerror(errbuf);
476 return(0);
479 void
480 init_dev(struct device *dp)
483 dp->d_name = "OHNO!!!";
484 dp->d_type = DEVICE;
485 dp->d_conn = 0;
486 dp->d_disabled = 0;
487 dp->d_flags = 0;
488 dp->d_bus = dp->d_lun = dp->d_target = dp->d_drive = dp->d_unit =
489 dp->d_count = UNKNOWN;
490 dp->d_port = NULL;
491 dp->d_portn = -1;
492 dp->d_irq = -1;
493 dp->d_drq = -1;
494 dp->d_maddr = 0;
495 dp->d_msize = 0;