]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/config/config.y
This commit was generated by cvs2svn to compensate for changes in r132451,
[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
250               = {
251                 newopt(&opt, devopt($2), ns("1"));
252                 /* and the device part */
253                 newdev($2, UNKNOWN);
254                 } |
255         DEVICE Dev NUMBER
256               = {
257                 newopt(&opt, devopt($2), ns("1"));
258                 /* and the device part */
259                 newdev($2, $3);
260                 if ($3 == 0)
261                         errx(1, "%s:%d: devices with zero units are not "
262                             "likely to be correct", yyfile, yyline);
263                 } |
264         NODEVICE Dev
265               = {
266                 char *s = devopt($2);
267
268                 rmopt(&opt, s);
269                 free(s);
270                 /* and the device part */
271                 rmdev($2);
272                 } ;
273
274 %%
275
276 void
277 yyerror(const char *s)
278 {
279
280         errx(1, "%s:%d: %s", yyfile, yyline + 1, s);
281 }
282
283 /*
284  * Add a new file to the list of files.
285  */
286 static void
287 newfile(char *name)
288 {
289         struct files_name *nl;
290         
291         nl = (struct files_name *) malloc(sizeof *nl);
292         bzero(nl, sizeof *nl);
293         nl->f_name = name;
294         STAILQ_INSERT_TAIL(&fntab, nl, f_next);
295 }
296         
297 /*
298  * add a device to the list of devices
299  */
300 static void
301 newdev(char *name, int count)
302 {
303         struct device *np;
304
305         np = (struct device *) malloc(sizeof *np);
306         memset(np, 0, sizeof(*np));
307         np->d_name = name;
308         np->d_count = count;
309         STAILQ_INSERT_TAIL(&dtab, np, d_next);
310 }
311
312 /*
313  * remove a device from the list of devices
314  */
315 static void
316 rmdev(char *name)
317 {
318         struct device *dp, *rmdp;
319
320         STAILQ_FOREACH(dp, &dtab, d_next) {
321                 if (eq(dp->d_name, name)) {
322                         rmdp = dp;
323                         dp = STAILQ_NEXT(dp, d_next);
324                         STAILQ_REMOVE(&dtab, rmdp, device, d_next);
325                         free(rmdp->d_name);
326                         free(rmdp);
327                         if (dp == NULL)
328                                 break;
329                 }
330         }
331 }
332
333 static void
334 newopt(struct opt_head *list, char *name, char *value)
335 {
336         struct opt *op;
337
338         op = (struct opt *)malloc(sizeof (struct opt));
339         memset(op, 0, sizeof(*op));
340         op->op_name = name;
341         op->op_ownfile = 0;
342         op->op_value = value;
343         SLIST_INSERT_HEAD(list, op, op_next);
344 }
345
346 static void
347 rmopt(struct opt_head *list, char *name)
348 {
349         struct opt *op, *rmop;
350
351         SLIST_FOREACH(op, list, op_next) {
352                 if (eq(op->op_name, name)) {
353                         rmop = op;
354                         op = SLIST_NEXT(op, op_next);
355                         SLIST_REMOVE(list, rmop, opt, op_next);
356                         free(rmop->op_name);
357                         if (rmop->op_value != NULL)
358                                 free(rmop->op_value);
359                         free(rmop);
360                         if (op == NULL)
361                                 break;
362                 }
363         }
364 }