xref: /dragonfly/usr.sbin/config/config.y (revision 1de703da)
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