]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/config/config.y
This commit was generated by cvs2svn to compensate for changes in r146897,
[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                 machinearch = $2;
142               } |
143         ARCH Save_id Save_id
144             = {
145                 if (machinename != NULL)
146                     errx(1, "%s:%d: only one machine directive is allowed",
147                         yyfile, yyline);
148                 machinename = $2;
149                 machinearch = $3;
150               } |
151         CPU Save_id
152               = {
153                 struct cputype *cp =
154                     (struct cputype *)malloc(sizeof (struct cputype));
155                 memset(cp, 0, sizeof(*cp));
156                 cp->cpu_name = $2;
157                 SLIST_INSERT_HEAD(&cputype, cp, cpu_next);
158               } |
159         OPTIONS Opt_list
160                 |
161         NOOPTION Save_id
162               = { rmopt(&opt, $2); } |
163         MAKEOPTIONS Mkopt_list
164                 |
165         NOMAKEOPTION Save_id
166               = { rmopt(&mkopt, $2); } |
167         IDENT ID
168               = { ident = $2; } |
169         System_spec
170                 |
171         MAXUSERS NUMBER
172               = { maxusers = $2; } |
173         PROFILE NUMBER
174               = { profiling = $2; } |
175         ENV ID
176               = {
177                       env = $2;
178                       envmode = 1;
179                 } |
180         HINTS ID
181               = {
182                       hints = $2;
183                       hintmode = 1;
184                 }
185
186 System_spec:
187         CONFIG System_id System_parameter_list
188           = { errx(1, "%s:%d: root/dump/swap specifications obsolete",
189               yyfile, yyline);}
190           |
191         CONFIG System_id
192           ;
193
194 System_id:
195         Save_id
196               = { newopt(&mkopt, ns("KERNEL"), $1); };
197
198 System_parameter_list:
199           System_parameter_list ID
200         | ID
201         ;
202
203 Opt_list:
204         Opt_list COMMA Option
205                 |
206         Option
207                 ;
208
209 Option:
210         Save_id
211               = {
212                 char *s;
213
214                 newopt(&opt, $1, NULL);
215                 if ((s = strchr($1, '=')))
216                         errx(1, "%s:%d: The `=' in options should not be "
217                             "quoted", yyfile, yyline);
218               } |
219         Save_id EQUALS Opt_value
220               = {
221                 newopt(&opt, $1, $3);
222               } ;
223
224 Opt_value:
225         ID
226                 = { $$ = $1; } |
227         NUMBER
228                 = {
229                         char buf[80];
230
231                         (void) snprintf(buf, sizeof(buf), "%d", $1);
232                         $$ = ns(buf);
233                 } ;
234
235 Save_id:
236         ID
237               = { $$ = $1; }
238         ;
239
240 Mkopt_list:
241         Mkopt_list COMMA Mkoption
242                 |
243         Mkoption
244                 ;
245
246 Mkoption:
247         Save_id
248               = { newopt(&mkopt, $1, ns("")); } |
249         Save_id EQUALS Opt_value
250               = { newopt(&mkopt, $1, $3); } ;
251
252 Dev:
253         ID
254               = { $$ = $1; }
255         ;
256
257 Device_spec:
258         DEVICE Dev_list
259                 |
260         NODEVICE NoDev_list
261                 ;
262
263 Dev_list:
264         Dev_list COMMA Device
265                 |
266         Device
267                 ;
268
269 NoDev_list:
270         NoDev_list COMMA NoDevice
271                 |
272         NoDevice
273                 ;
274
275 Device:
276         Dev
277               = {
278                 newopt(&opt, devopt($1), ns("1"));
279                 /* and the device part */
280                 newdev($1);
281                 }
282
283 NoDevice:
284         Dev
285               = {
286                 char *s = devopt($1);
287
288                 rmopt(&opt, s);
289                 free(s);
290                 /* and the device part */
291                 rmdev($1);
292                 } ;
293
294 %%
295
296 void
297 yyerror(const char *s)
298 {
299
300         errx(1, "%s:%d: %s", yyfile, yyline + 1, s);
301 }
302
303 /*
304  * Add a new file to the list of files.
305  */
306 static void
307 newfile(char *name)
308 {
309         struct files_name *nl;
310         
311         nl = (struct files_name *) malloc(sizeof *nl);
312         bzero(nl, sizeof *nl);
313         nl->f_name = name;
314         STAILQ_INSERT_TAIL(&fntab, nl, f_next);
315 }
316         
317 /*
318  * add a device to the list of devices
319  */
320 static void
321 newdev(char *name)
322 {
323         struct device *np;
324
325         np = (struct device *) malloc(sizeof *np);
326         memset(np, 0, sizeof(*np));
327         np->d_name = name;
328         STAILQ_INSERT_TAIL(&dtab, np, d_next);
329 }
330
331 /*
332  * remove a device from the list of devices
333  */
334 static void
335 rmdev(char *name)
336 {
337         struct device *dp, *rmdp;
338
339         STAILQ_FOREACH(dp, &dtab, d_next) {
340                 if (eq(dp->d_name, name)) {
341                         rmdp = dp;
342                         dp = STAILQ_NEXT(dp, d_next);
343                         STAILQ_REMOVE(&dtab, rmdp, device, d_next);
344                         free(rmdp->d_name);
345                         free(rmdp);
346                         if (dp == NULL)
347                                 break;
348                 }
349         }
350 }
351
352 static void
353 newopt(struct opt_head *list, char *name, char *value)
354 {
355         struct opt *op;
356
357         op = (struct opt *)malloc(sizeof (struct opt));
358         memset(op, 0, sizeof(*op));
359         op->op_name = name;
360         op->op_ownfile = 0;
361         op->op_value = value;
362         SLIST_INSERT_HEAD(list, op, op_next);
363 }
364
365 static void
366 rmopt(struct opt_head *list, char *name)
367 {
368         struct opt *op, *rmop;
369
370         SLIST_FOREACH(op, list, op_next) {
371                 if (eq(op->op_name, name)) {
372                         rmop = op;
373                         op = SLIST_NEXT(op, op_next);
374                         SLIST_REMOVE(list, rmop, opt, op_next);
375                         free(rmop->op_name);
376                         if (rmop->op_value != NULL)
377                                 free(rmop->op_value);
378                         free(rmop);
379                         if (op == NULL)
380                                 break;
381                 }
382         }
383 }