]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/config/config.y
This commit was generated by cvs2svn to compensate for changes in r154178,
[FreeBSD/FreeBSD.git] / usr.sbin / config / config.y
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  NOCPU
12 %token  DEVICE
13 %token  NODEVICE
14 %token  ENV
15 %token  EQUALS
16 %token  HINTS
17 %token  IDENT
18 %token  MAXUSERS
19 %token  PROFILE
20 %token  OPTIONS
21 %token  NOOPTION
22 %token  MAKEOPTIONS
23 %token  NOMAKEOPTION 
24 %token  SEMICOLON
25 %token  INCLUDE
26 %token  FILES
27
28 %token  <str>   ID
29 %token  <val>   NUMBER
30
31 %type   <str>   Save_id
32 %type   <str>   Opt_value
33 %type   <str>   Dev
34
35 %{
36
37 /*
38  * Copyright (c) 1988, 1993
39  *      The Regents of the University of California.  All rights reserved.
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  * 1. Redistributions of source code must retain the above copyright
45  *    notice, this list of conditions and the following disclaimer.
46  * 2. Redistributions in binary form must reproduce the above copyright
47  *    notice, this list of conditions and the following disclaimer in the
48  *    documentation and/or other materials provided with the distribution.
49  * 3. All advertising materials mentioning features or use of this software
50  *    must display the following acknowledgement:
51  *      This product includes software developed by the University of
52  *      California, Berkeley and its contributors.
53  * 4. Neither the name of the University nor the names of its contributors
54  *    may be used to endorse or promote products derived from this software
55  *    without specific prior written permission.
56  *
57  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
58  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
60  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
61  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
63  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
65  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
67  * SUCH DAMAGE.
68  *
69  *      @(#)config.y    8.1 (Berkeley) 6/6/93
70  * $FreeBSD$
71  */
72
73 #include <ctype.h>
74 #include <err.h>
75 #include <stdio.h>
76 #include <string.h>
77
78 #include "config.h"
79
80 struct  device_head dtab;
81 char    *ident;
82 char    *env;
83 int     envmode;
84 char    *hints;
85 int     hintmode;
86 int     yyline;
87 const   char *yyfile;
88 struct  file_list_head ftab;
89 struct  files_name_head fntab;
90 char    errbuf[80];
91 int     maxusers;
92
93 #define ns(s)   strdup(s)
94 int include(const char *, int);
95 void yyerror(const char *s);
96 int yywrap(void);
97
98 static char *
99 devopt(char *dev)
100 {
101         char *ret = malloc(strlen(dev) + 5);
102         
103         sprintf(ret, "DEV_%s", dev);
104         raisestr(ret);
105         return ret;
106 }
107
108 %}
109 %%
110 Configuration:
111         Many_specs
112                 ;
113
114 Many_specs:
115         Many_specs Spec
116                 |
117         /* lambda */
118                 ;
119
120 Spec:
121         Device_spec SEMICOLON
122                 |
123         Config_spec SEMICOLON
124                 |
125         INCLUDE ID SEMICOLON
126               = { include($2, 0); };
127                 |
128         FILES ID SEMICOLON
129               = { newfile($2); };
130                 |
131         SEMICOLON
132                 |
133         error SEMICOLON
134                 ;
135
136 Config_spec:
137         ARCH Save_id
138             = {
139                 if (machinename != NULL && !eq($2, machinename))
140                     errx(1, "%s:%d: only one machine directive is allowed",
141                         yyfile, yyline);
142                 machinename = $2;
143                 machinearch = $2;
144               } |
145         ARCH Save_id Save_id
146             = {
147                 if (machinename != NULL &&
148                     !(eq($2, machinename) && eq($3, machinearch)))
149                     errx(1, "%s:%d: only one machine directive is allowed",
150                         yyfile, yyline);
151                 machinename = $2;
152                 machinearch = $3;
153               } |
154         CPU Save_id
155               = {
156                 struct cputype *cp =
157                     (struct cputype *)malloc(sizeof (struct cputype));
158                 memset(cp, 0, sizeof(*cp));
159                 cp->cpu_name = $2;
160                 SLIST_INSERT_HEAD(&cputype, cp, cpu_next);
161               } |
162         NOCPU Save_id
163               = {
164                 struct cputype *cp, *cp2;
165                 SLIST_FOREACH_SAFE(cp, &cputype, cpu_next, cp2) {
166                         if (eq(cp->cpu_name, $2)) {
167                                 SLIST_REMOVE(&cputype, cp, cputype, cpu_next);
168                                 free(cp);
169                         }
170                 }
171               } |
172         OPTIONS Opt_list
173                 |
174         NOOPTION Save_id
175               = { rmopt(&opt, $2); } |
176         MAKEOPTIONS Mkopt_list
177                 |
178         NOMAKEOPTION Save_id
179               = { rmopt(&mkopt, $2); } |
180         IDENT ID
181               = { ident = $2; } |
182         System_spec
183                 |
184         MAXUSERS NUMBER
185               = { maxusers = $2; } |
186         PROFILE NUMBER
187               = { profiling = $2; } |
188         ENV ID
189               = {
190                       env = $2;
191                       envmode = 1;
192                 } |
193         HINTS ID
194               = {
195                       hints = $2;
196                       hintmode = 1;
197                 }
198
199 System_spec:
200         CONFIG System_id System_parameter_list
201           = { errx(1, "%s:%d: root/dump/swap specifications obsolete",
202               yyfile, yyline);}
203           |
204         CONFIG System_id
205           ;
206
207 System_id:
208         Save_id
209               = { newopt(&mkopt, ns("KERNEL"), $1); };
210
211 System_parameter_list:
212           System_parameter_list ID
213         | ID
214         ;
215
216 Opt_list:
217         Opt_list COMMA Option
218                 |
219         Option
220                 ;
221
222 Option:
223         Save_id
224               = {
225                 char *s;
226
227                 newopt(&opt, $1, NULL);
228                 if ((s = strchr($1, '=')))
229                         errx(1, "%s:%d: The `=' in options should not be "
230                             "quoted", yyfile, yyline);
231               } |
232         Save_id EQUALS Opt_value
233               = {
234                 newopt(&opt, $1, $3);
235               } ;
236
237 Opt_value:
238         ID
239                 = { $$ = $1; } |
240         NUMBER
241                 = {
242                         char buf[80];
243
244                         (void) snprintf(buf, sizeof(buf), "%d", $1);
245                         $$ = ns(buf);
246                 } ;
247
248 Save_id:
249         ID
250               = { $$ = $1; }
251         ;
252
253 Mkopt_list:
254         Mkopt_list COMMA Mkoption
255                 |
256         Mkoption
257                 ;
258
259 Mkoption:
260         Save_id
261               = { newopt(&mkopt, $1, ns("")); } |
262         Save_id EQUALS Opt_value
263               = { newopt(&mkopt, $1, $3); } ;
264
265 Dev:
266         ID
267               = { $$ = $1; }
268         ;
269
270 Device_spec:
271         DEVICE Dev_list
272                 |
273         NODEVICE NoDev_list
274                 ;
275
276 Dev_list:
277         Dev_list COMMA Device
278                 |
279         Device
280                 ;
281
282 NoDev_list:
283         NoDev_list COMMA NoDevice
284                 |
285         NoDevice
286                 ;
287
288 Device:
289         Dev
290               = {
291                 newopt(&opt, devopt($1), ns("1"));
292                 /* and the device part */
293                 newdev($1);
294                 }
295
296 NoDevice:
297         Dev
298               = {
299                 char *s = devopt($1);
300
301                 rmopt(&opt, s);
302                 free(s);
303                 /* and the device part */
304                 rmdev($1);
305                 } ;
306
307 %%
308
309 void
310 yyerror(const char *s)
311 {
312
313         errx(1, "%s:%d: %s", yyfile, yyline + 1, s);
314 }
315
316 int
317 yywrap(void)
318 {
319
320         if (found_defaults) {
321                 if (freopen(PREFIX, "r", stdin) == NULL)
322                         err(2, "%s", PREFIX);           
323                 yyfile = PREFIX;
324                 yyline = 0;
325                 found_defaults = 0;
326                 return 0;
327         }
328         return 1;
329 }
330
331 /*
332  * Add a new file to the list of files.
333  */
334 static void
335 newfile(char *name)
336 {
337         struct files_name *nl;
338         
339         nl = (struct files_name *) malloc(sizeof *nl);
340         bzero(nl, sizeof *nl);
341         nl->f_name = name;
342         STAILQ_INSERT_TAIL(&fntab, nl, f_next);
343 }
344         
345 /*
346  * Find a device in the list of devices.
347  */
348 static struct device *
349 finddev(char *name)
350 {
351         struct device *dp;
352
353         STAILQ_FOREACH(dp, &dtab, d_next)
354                 if (eq(dp->d_name, name))
355                         return (dp);
356
357         return (NULL);
358 }
359         
360 /*
361  * Add a device to the list of devices.
362  */
363 static void
364 newdev(char *name)
365 {
366         struct device *np;
367
368         if (finddev(name)) {
369                 printf("WARNING: duplicate device `%s' encountered.\n", name);
370                 return;
371         }
372
373         np = (struct device *) malloc(sizeof *np);
374         memset(np, 0, sizeof(*np));
375         np->d_name = name;
376         STAILQ_INSERT_TAIL(&dtab, np, d_next);
377 }
378
379 /*
380  * Remove a device from the list of devices.
381  */
382 static void
383 rmdev(char *name)
384 {
385         struct device *dp;
386
387         dp = finddev(name);
388         if (dp != NULL) {
389                 STAILQ_REMOVE(&dtab, dp, device, d_next);
390                 free(dp->d_name);
391                 free(dp);
392         }
393 }
394
395 /*
396  * Find an option in the list of options.
397  */
398 static struct opt *
399 findopt(struct opt_head *list, char *name)
400 {
401         struct opt *op;
402
403         SLIST_FOREACH(op, list, op_next)
404                 if (eq(op->op_name, name))
405                         return (op);
406
407         return (NULL);
408 }
409
410 /*
411  * Add an option to the list of options.
412  */
413 static void
414 newopt(struct opt_head *list, char *name, char *value)
415 {
416         struct opt *op;
417
418         if (findopt(list, name)) {
419                 printf("WARNING: duplicate option `%s' encountered.\n", name);
420                 return;
421         }
422
423         op = (struct opt *)malloc(sizeof (struct opt));
424         memset(op, 0, sizeof(*op));
425         op->op_name = name;
426         op->op_ownfile = 0;
427         op->op_value = value;
428         SLIST_INSERT_HEAD(list, op, op_next);
429 }
430
431 /*
432  * Remove an option from the list of options.
433  */
434 static void
435 rmopt(struct opt_head *list, char *name)
436 {
437         struct opt *op;
438
439         op = findopt(list, name);
440         if (op != NULL) {
441                 SLIST_REMOVE(list, op, opt, op_next);
442                 free(op->op_name);
443                 if (op->op_value != NULL)
444                         free(op->op_value);
445                 free(op);
446         }
447 }