xref: /freebsd/usr.sbin/config/config.y (revision 3193579b66fd7067f898dbc54bdea81a0e6f9bd0)
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$
69  */
70 
71 #include <ctype.h>
72 #include <err.h>
73 #include <stdio.h>
74 #include <string.h>
75 
76 #include "config.h"
77 
78 struct	device_head dtab;
79 char	*ident;
80 char	*env;
81 int	envmode;
82 char	*hints;
83 int	hintmode;
84 int	yyline;
85 const	char *yyfile;
86 struct  file_list_head ftab;
87 char	errbuf[80];
88 int	maxusers;
89 
90 #define ns(s)	strdup(s)
91 int include(const char *, int);
92 void yyerror(const char *s);
93 
94 static char *
95 devopt(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 %%
106 Configuration:
107 	Many_specs
108 		;
109 
110 Many_specs:
111 	Many_specs Spec
112 		|
113 	/* lambda */
114 		;
115 
116 Spec:
117 	Device_spec SEMICOLON
118 		|
119 	Config_spec SEMICOLON
120 		|
121 	INCLUDE ID SEMICOLON
122 	      = { include($2, 0); };
123 		|
124 	SEMICOLON
125 		|
126 	error SEMICOLON
127 		;
128 
129 Config_spec:
130 	ARCH Save_id
131 	    = {
132 		if (machinename != NULL)
133 		    errx(1, "%s:%d: only one machine directive is allowed",
134 			yyfile, yyline);
135 		machinename = $2;
136 	      } |
137 	CPU Save_id
138 	      = {
139 		struct cputype *cp =
140 		    (struct cputype *)malloc(sizeof (struct cputype));
141 		memset(cp, 0, sizeof(*cp));
142 		cp->cpu_name = $2;
143 		SLIST_INSERT_HEAD(&cputype, cp, cpu_next);
144 	      } |
145 	OPTIONS Opt_list
146 		|
147 	NOOPTION Save_id
148 	      = { rmopt(&opt, $2); } |
149 	MAKEOPTIONS Mkopt_list
150 		|
151 	NOMAKEOPTION Save_id
152 	      = { rmopt(&mkopt, $2); } |
153 	IDENT ID
154 	      = { ident = $2; } |
155 	System_spec
156 		|
157 	MAXUSERS NUMBER
158 	      = { maxusers = $2; } |
159 	PROFILE NUMBER
160 	      = { profiling = $2; } |
161 	ENV ID
162 	      = {
163 		      env = $2;
164 		      envmode = 1;
165 		} |
166 	HINTS ID
167 	      = {
168 		      hints = $2;
169 		      hintmode = 1;
170 	        }
171 
172 System_spec:
173 	CONFIG System_id System_parameter_list
174 	  = { errx(1, "%s:%d: root/dump/swap specifications obsolete",
175 	      yyfile, yyline);}
176 	  |
177 	CONFIG System_id
178 	  ;
179 
180 System_id:
181 	Save_id
182 	      = { newopt(&mkopt, ns("KERNEL"), $1); };
183 
184 System_parameter_list:
185 	  System_parameter_list ID
186 	| ID
187 	;
188 
189 Opt_list:
190 	Opt_list COMMA Option
191 		|
192 	Option
193 		;
194 
195 Option:
196 	Save_id
197 	      = {
198 		char *s;
199 
200 		newopt(&opt, $1, NULL);
201 		if ((s = strchr($1, '=')))
202 			errx(1, "%s:%d: The `=' in options should not be "
203 			    "quoted", yyfile, yyline);
204 	      } |
205 	Save_id EQUALS Opt_value
206 	      = {
207 		newopt(&opt, $1, $3);
208 	      } ;
209 
210 Opt_value:
211 	ID
212 		= { $$ = $1; } |
213 	NUMBER
214 		= {
215 			char buf[80];
216 
217 			(void) snprintf(buf, sizeof(buf), "%d", $1);
218 			$$ = ns(buf);
219 		} ;
220 
221 Save_id:
222 	ID
223 	      = { $$ = $1; }
224 	;
225 
226 Mkopt_list:
227 	Mkopt_list COMMA Mkoption
228 		|
229 	Mkoption
230 		;
231 
232 Mkoption:
233 	Save_id
234 	      = { newopt(&mkopt, $1, ns("")); } |
235 	Save_id EQUALS Opt_value
236 	      = { newopt(&mkopt, $1, $3); } ;
237 
238 Dev:
239 	ID
240 	      = { $$ = $1; }
241 	;
242 
243 Device_spec:
244 	DEVICE Dev
245 	      = {
246 		newopt(&opt, devopt($2), ns("1"));
247 		/* and the device part */
248 		newdev($2, UNKNOWN);
249 		} |
250 	DEVICE Dev NUMBER
251 	      = {
252 		newopt(&opt, devopt($2), ns("1"));
253 		/* and the device part */
254 		newdev($2, $3);
255 		if ($3 == 0)
256 			errx(1, "%s:%d: devices with zero units are not "
257 			    "likely to be correct", yyfile, yyline);
258 		} |
259 	NODEVICE Dev
260 	      = {
261 		char *s = devopt($2);
262 
263 		rmopt(&opt, s);
264 		free(s);
265 		/* and the device part */
266 		rmdev($2);
267 		} ;
268 
269 %%
270 
271 void
272 yyerror(const char *s)
273 {
274 
275 	errx(1, "%s:%d: %s", yyfile, yyline + 1, s);
276 }
277 
278 /*
279  * add a device to the list of devices
280  */
281 static void
282 newdev(char *name, int count)
283 {
284 	struct device *np;
285 
286 	np = (struct device *) malloc(sizeof *np);
287 	memset(np, 0, sizeof(*np));
288 	np->d_name = name;
289 	np->d_count = count;
290 	STAILQ_INSERT_TAIL(&dtab, np, d_next);
291 }
292 
293 /*
294  * remove a device from the list of devices
295  */
296 static void
297 rmdev(char *name)
298 {
299 	struct device *dp, *rmdp;
300 
301 	STAILQ_FOREACH(dp, &dtab, d_next) {
302 		if (eq(dp->d_name, name)) {
303 			rmdp = dp;
304 			dp = STAILQ_NEXT(dp, d_next);
305 			STAILQ_REMOVE(&dtab, rmdp, device, d_next);
306 			free(rmdp->d_name);
307 			free(rmdp);
308 			if (dp == NULL)
309 				break;
310 		}
311 	}
312 }
313 
314 static void
315 newopt(struct opt_head *list, char *name, char *value)
316 {
317 	struct opt *op;
318 
319 	op = (struct opt *)malloc(sizeof (struct opt));
320 	memset(op, 0, sizeof(*op));
321 	op->op_name = name;
322 	op->op_ownfile = 0;
323 	op->op_value = value;
324 	SLIST_INSERT_HEAD(list, op, op_next);
325 }
326 
327 static void
328 rmopt(struct opt_head *list, char *name)
329 {
330 	struct opt *op, *rmop;
331 
332 	SLIST_FOREACH(op, list, op_next) {
333 		if (eq(op->op_name, name)) {
334 			rmop = op;
335 			op = SLIST_NEXT(op, op_next);
336 			SLIST_REMOVE(list, rmop, opt, op_next);
337 			free(rmop->op_name);
338 			if (rmop->op_value != NULL)
339 				free(rmop->op_value);
340 			free(rmop);
341 			if (op == NULL)
342 				break;
343 		}
344 	}
345 }
346