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