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