config.y revision 117269
1%union {
2	char	*str;
3	int	val;
4	struct	file_list *file;
5}
6
7%token	ARCH
8%token	COMMA
9%token	CONFIG
10%token	CPU
11%token	DEVICE
12%token	NODEVICE
13%token	ENV
14%token	EQUALS
15%token	HINTS
16%token	IDENT
17%token	MAXUSERS
18%token	PROFILE
19%token	OPTIONS
20%token	NOOPTION
21%token	MAKEOPTIONS
22%token	NOMAKEOPTION
23%token	SEMICOLON
24%token	INCLUDE
25
26%token	<str>	ID
27%token	<val>	NUMBER
28
29%type	<str>	Save_id
30%type	<str>	Opt_value
31%type	<str>	Dev
32
33%{
34
35/*
36 * Copyright (c) 1988, 1993
37 *	The Regents of the University of California.  All rights reserved.
38 *
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions
41 * are met:
42 * 1. Redistributions of source code must retain the above copyright
43 *    notice, this list of conditions and the following disclaimer.
44 * 2. Redistributions in binary form must reproduce the above copyright
45 *    notice, this list of conditions and the following disclaimer in the
46 *    documentation and/or other materials provided with the distribution.
47 * 3. All advertising materials mentioning features or use of this software
48 *    must display the following acknowledgement:
49 *	This product includes software developed by the University of
50 *	California, Berkeley and its contributors.
51 * 4. Neither the name of the University nor the names of its contributors
52 *    may be used to endorse or promote products derived from this software
53 *    without specific prior written permission.
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * SUCH DAMAGE.
66 *
67 *	@(#)config.y	8.1 (Berkeley) 6/6/93
68 * $FreeBSD: head/usr.sbin/config/config.y 117269 2003-07-06 02:00:52Z jkoshy $
69 */
70
71#include <ctype.h>
72#include <err.h>
73#include <stdio.h>
74#include <string.h>
75
76#include "config.h"
77
78struct	device_head dtab;
79char	*ident;
80char	*env;
81int	envmode;
82char	*hints;
83int	hintmode;
84int	yyline;
85const	char *yyfile;
86struct  file_list_head ftab;
87char	errbuf[80];
88int	maxusers;
89
90#define ns(s)	strdup(s)
91int include(const char *, int);
92void yyerror(const char *s);
93
94static char *
95devopt(char *dev)
96{
97	char *ret = malloc(strlen(dev) + 5);
98
99	sprintf(ret, "DEV_%s", dev);
100	raisestr(ret);
101	return ret;
102}
103
104%}
105%%
106Configuration:
107	Many_specs
108		;
109
110Many_specs:
111	Many_specs Spec
112		|
113	/* lambda */
114		;
115
116Spec:
117	Device_spec SEMICOLON
118		|
119	Config_spec SEMICOLON
120		|
121	SEMICOLON
122		|
123	error SEMICOLON
124		;
125
126Config_spec:
127	ARCH Save_id
128	    = {
129		if (machinename != NULL)
130		    errx(1, "%s:%d: only one machine directive is allowed",
131			yyfile, yyline);
132		machinename = $2;
133	      } |
134	CPU Save_id
135	      = {
136		struct cputype *cp =
137		    (struct cputype *)malloc(sizeof (struct cputype));
138		memset(cp, 0, sizeof(*cp));
139		cp->cpu_name = $2;
140		SLIST_INSERT_HEAD(&cputype, cp, cpu_next);
141	      } |
142	OPTIONS Opt_list
143		|
144	NOOPTION Save_id
145	      = { rmopt(&opt, $2); } |
146	MAKEOPTIONS Mkopt_list
147		|
148	NOMAKEOPTION Save_id
149	      = { rmopt(&mkopt, $2); } |
150	IDENT ID
151	      = { ident = $2; } |
152	System_spec
153		|
154	MAXUSERS NUMBER
155	      = { maxusers = $2; } |
156	PROFILE NUMBER
157	      = { profiling = $2; } |
158	ENV ID
159	      = {
160		      env = $2;
161		      envmode = 1;
162		} |
163	HINTS ID
164	      = {
165		      hints = $2;
166		      hintmode = 1;
167	        } |
168	INCLUDE ID
169	      = { include($2, 0); };
170
171System_spec:
172	CONFIG System_id System_parameter_list
173	  = { errx(1, "%s:%d: root/dump/swap specifications obsolete",
174	      yyfile, yyline);}
175	  |
176	CONFIG System_id
177	  ;
178
179System_id:
180	Save_id
181	      = { newopt(&mkopt, ns("KERNEL"), $1); };
182
183System_parameter_list:
184	  System_parameter_list ID
185	| ID
186	;
187
188Opt_list:
189	Opt_list COMMA Option
190		|
191	Option
192		;
193
194Option:
195	Save_id
196	      = {
197		char *s;
198
199		newopt(&opt, $1, NULL);
200		if ((s = strchr($1, '=')))
201			errx(1, "%s:%d: The `=' in options should not be "
202			    "quoted", yyfile, yyline);
203	      } |
204	Save_id EQUALS Opt_value
205	      = {
206		newopt(&opt, $1, $3);
207	      } ;
208
209Opt_value:
210	ID
211		= { $$ = $1; } |
212	NUMBER
213		= {
214			char buf[80];
215
216			(void) snprintf(buf, sizeof(buf), "%d", $1);
217			$$ = ns(buf);
218		} ;
219
220Save_id:
221	ID
222	      = { $$ = $1; }
223	;
224
225Mkopt_list:
226	Mkopt_list COMMA Mkoption
227		|
228	Mkoption
229		;
230
231Mkoption:
232	Save_id
233	      = { newopt(&mkopt, $1, ns("")); } |
234	Save_id EQUALS Opt_value
235	      = { newopt(&mkopt, $1, $3); } ;
236
237Dev:
238	ID
239	      = { $$ = $1; }
240	;
241
242Device_spec:
243	DEVICE Dev
244	      = {
245		newopt(&opt, devopt($2), ns("1"));
246		/* and the device part */
247		newdev($2, UNKNOWN);
248		} |
249	DEVICE Dev NUMBER
250	      = {
251		newopt(&opt, devopt($2), ns("1"));
252		/* and the device part */
253		newdev($2, $3);
254		if ($3 == 0)
255			errx(1, "%s:%d: devices with zero units are not "
256			    "likely to be correct", yyfile, yyline);
257		} |
258	NODEVICE Dev
259	      = {
260		char *s = devopt($2);
261
262		rmopt(&opt, s);
263		free(s);
264		/* and the device part */
265		rmdev($2);
266		} ;
267
268%%
269
270void
271yyerror(const char *s)
272{
273
274	errx(1, "%s:%d: %s", yyfile, yyline + 1, s);
275}
276
277/*
278 * add a device to the list of devices
279 */
280static void
281newdev(char *name, int count)
282{
283	struct device *np;
284
285	np = (struct device *) malloc(sizeof *np);
286	memset(np, 0, sizeof(*np));
287	np->d_name = name;
288	np->d_count = count;
289	STAILQ_INSERT_TAIL(&dtab, np, d_next);
290}
291
292/*
293 * remove a device from the list of devices
294 */
295static void
296rmdev(char *name)
297{
298	struct device *dp, *rmdp;
299
300	STAILQ_FOREACH(dp, &dtab, d_next) {
301		if (eq(dp->d_name, name)) {
302			rmdp = dp;
303			dp = STAILQ_NEXT(dp, d_next);
304			STAILQ_REMOVE(&dtab, rmdp, device, d_next);
305			free(rmdp->d_name);
306			free(rmdp);
307			if (dp == NULL)
308				break;
309		}
310	}
311}
312
313static void
314newopt(struct opt_head *list, char *name, char *value)
315{
316	struct opt *op;
317
318	op = (struct opt *)malloc(sizeof (struct opt));
319	memset(op, 0, sizeof(*op));
320	op->op_name = name;
321	op->op_ownfile = 0;
322	op->op_value = value;
323	SLIST_INSERT_HEAD(list, op, op_next);
324}
325
326static void
327rmopt(struct opt_head *list, char *name)
328{
329	struct opt *op, *rmop;
330
331	SLIST_FOREACH(op, list, op_next) {
332		if (eq(op->op_name, name)) {
333			rmop = op;
334			op = SLIST_NEXT(op, op_next);
335			SLIST_REMOVE(list, rmop, opt, op_next);
336			free(rmop->op_name);
337			if (rmop->op_value != NULL)
338				free(rmop->op_value);
339			free(rmop);
340			if (op == NULL)
341				break;
342		}
343	}
344}
345