Remove obsolete keywords: conflicts, controller, disk, tape
[dragonfly.git] / usr.sbin / config / config.y
1 %union {
2         char    *str;
3         int     val;
4         struct  file_list *file;
5 }
6
7 %token  ANY
8 %token  AT
9 %token  BUS
10 %token  COMMA
11 %token  CONFIG
12 %token  CONFIG_MACHINE
13 %token  CONFIG_MACHINE_ARCH
14 %token  CONFIG_PLATFORM
15 %token  CPU
16 %token  DEVICE
17 %token  DISABLE
18 %token  DRIVE
19 %token  DRQ
20 %token  EQUALS
21 %token  FLAGS
22 %token  IDENT
23 %token  IOMEM
24 %token  IOSIZ
25 %token  IRQ
26 %token  MAXUSERS
27 %token  MINUS
28 %token  NEXUS
29 %token  OPTIONS
30 %token  MAKEOPTIONS
31 %token  PORT
32 %token  PSEUDO_DEVICE
33 %token  SEMICOLON
34 %token  TARGET
35 %token  TTY
36 %token  UNIT
37 %token  VECTOR
38
39 %token  <str>   ID
40 %token  <val>   NUMBER
41 %token  <val>   FPNUMBER
42
43 %type   <str>   Save_id
44 %type   <str>   Opt_value
45 %type   <str>   Dev
46 %type   <str>   device_name
47
48 %{
49
50 /*
51  * Copyright (c) 1988, 1993
52  *      The Regents of the University of California.  All rights reserved.
53  *
54  * Redistribution and use in source and binary forms, with or without
55  * modification, are permitted provided that the following conditions
56  * are met:
57  * 1. Redistributions of source code must retain the above copyright
58  *    notice, this list of conditions and the following disclaimer.
59  * 2. Redistributions in binary form must reproduce the above copyright
60  *    notice, this list of conditions and the following disclaimer in the
61  *    documentation and/or other materials provided with the distribution.
62  * 3. All advertising materials mentioning features or use of this software
63  *    must display the following acknowledgement:
64  *      This product includes software developed by the University of
65  *      California, Berkeley and its contributors.
66  * 4. Neither the name of the University nor the names of its contributors
67  *    may be used to endorse or promote products derived from this software
68  *    without specific prior written permission.
69  *
70  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
71  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
73  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
74  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
75  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
76  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
77  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
78  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
79  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
80  * SUCH DAMAGE.
81  *
82  *      @(#)config.y    8.1 (Berkeley) 6/6/93
83  * $FreeBSD: src/usr.sbin/config/config.y,v 1.42.2.1 2001/01/23 00:09:32 peter Exp $
84  * $DragonFly: src/usr.sbin/config/config.y,v 1.15 2008/05/01 09:24:42 swildner Exp $
85  */
86
87 #include <ctype.h>
88 #include <err.h>
89 #include <stdio.h>
90 #include <string.h>
91
92 #include "config.h"
93
94 static struct   device cur;
95 static struct   device *curp = 0;
96
97 struct  device *dtab;
98 char    *ident;
99 int     yyline;
100 struct  file_list *ftab;
101 char    errbuf[80];
102 int     maxusers;
103
104 static int connect(char *, int);
105 static void yyerror(const char *s);
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               = { newdev(&cur); } |
123         Config_spec SEMICOLON
124                 |
125         SEMICOLON
126                 |
127         error SEMICOLON
128                 ;
129
130 Config_spec:
131         CONFIG_PLATFORM Save_id
132             = {
133                 if (platformname != NULL) {
134                     errx(1, "%d: only one platform directive is allowed",
135                         yyline);
136                 }
137                 platformname = $2;
138               } |
139         CONFIG_MACHINE Save_id
140             = {
141                 if (machinename != NULL) {
142                     errx(1, "%d: only one machine directive is allowed",
143                         yyline);
144                 }
145                 machinename = $2;
146               } |
147         CONFIG_MACHINE_ARCH Save_id
148               = {
149                 if (machinearchname != NULL) {
150                     errx(1, "%d: only one machine_arch directive is allowed",
151                         yyline);
152                 }
153                 machinearchname = $2;
154               } |
155         CPU Save_id
156               = {
157                 struct cputype *cp;
158
159                 cp = malloc(sizeof(struct cputype));
160                 bzero(cp, sizeof(*cp));
161                 cp->cpu_name = $2;
162                 cp->cpu_next = cputype;
163                 cputype = cp;
164               } |
165         OPTIONS Opt_list
166                 |
167         MAKEOPTIONS Mkopt_list
168                 |
169         IDENT ID
170               = { ident = $2; } |
171         System_spec
172                 |
173         MAXUSERS NUMBER
174               = { maxusers = $2; };
175
176 System_spec:
177         CONFIG System_id System_parameter_list
178           = { errx(1,"line %d: root/dump/swap specifications obsolete", yyline);}
179           |
180         CONFIG System_id
181           ;
182
183 System_id:
184         Save_id
185               = {
186                 struct opt *op;
187
188                 op = malloc(sizeof(struct opt));
189                 bzero(op, sizeof(*op));
190                 op->op_name = strdup("KERNEL");
191                 op->op_ownfile = 0;
192                 op->op_next = mkopt;
193                 op->op_value = $1;
194                 op->op_line = yyline + 1;
195                 mkopt = op;
196               };
197
198 System_parameter_list:
199           System_parameter_list ID
200         | ID
201         ;
202
203 device_name:
204           Save_id
205                 = { $$ = $1; }
206         | Save_id NUMBER
207                 = {
208                         char buf[80];
209
210                         snprintf(buf, sizeof(buf), "%s%d", $1, $2);
211                         $$ = strdup(buf);
212                         free($1);
213                 }
214         | Save_id NUMBER ID
215                 = {
216                         char buf[80];
217
218                         snprintf(buf, sizeof(buf), "%s%d%s", $1, $2, $3);
219                         $$ = strdup(buf);
220                         free($1);
221                 }
222         | Save_id NUMBER ID NUMBER
223                 = {
224                         char buf[80];
225
226                         snprintf(buf, sizeof(buf), "%s%d%s%d",
227                              $1, $2, $3, $4);
228                         $$ = strdup(buf);
229                         free($1);
230                 }
231         | Save_id NUMBER ID NUMBER ID
232                 = {
233                         char buf[80];
234
235                         snprintf(buf, sizeof(buf), "%s%d%s%d%s",
236                              $1, $2, $3, $4, $5);
237                         $$ = strdup(buf);
238                         free($1);
239                 }
240         ;
241
242 Opt_list:
243         Opt_list COMMA Option
244                 |
245         Option
246                 ;
247
248 Option:
249         Save_id
250               = {
251                 struct opt *op;
252                 
253                 op = malloc(sizeof(struct opt));
254                 bzero(op, sizeof(*op));
255                 op->op_name = $1;
256                 op->op_next = opt;
257                 op->op_value = 0;
258                 /*
259                  * op->op_line is 1-based; yyline is 0-based but is now 1
260                  * larger than when `Save_id' was lexed.
261                  */
262                 op->op_line = yyline;
263                 opt = op;
264                 if (strchr(op->op_name, '=') != NULL)
265                         errx(1, "line %d: The `=' in options should not be quoted", yyline);
266               } |
267         Save_id EQUALS Opt_value
268               = {
269                 struct opt *op;
270
271                 op = malloc(sizeof(struct opt));
272                 bzero(op, sizeof(*op));
273                 op->op_name = $1;
274                 op->op_next = opt;
275                 op->op_value = $3;
276                 op->op_line = yyline + 1;
277                 opt = op;
278               } ;
279
280 Opt_value:
281         ID
282                 = { $$ = $1; } |
283         NUMBER
284                 = {
285                         char buf[80];
286
287                         snprintf(buf, sizeof(buf), "%d", $1);
288                         $$ = strdup(buf);
289                 } ;
290
291 Save_id:
292         ID
293               = { $$ = $1; }
294         ;
295
296 Mkopt_list:
297         Mkopt_list COMMA Mkoption
298                 |
299         Mkoption
300                 ;
301
302 Mkoption:
303         Save_id EQUALS Opt_value
304               = {
305                 struct opt *op;
306
307                 op = malloc(sizeof(struct opt));
308                 bzero(op, sizeof(*op));
309                 op->op_name = $1;
310                 op->op_ownfile = 0;     /* for now */
311                 op->op_next = mkopt;
312                 op->op_value = $3;
313                 op->op_line = yyline + 1;
314                 mkopt = op;
315               } ;
316
317 Dev:
318         ID
319               = { $$ = $1; }
320         ;
321
322 Device_spec:
323         DEVICE Dev_spec
324               = { cur.d_type = DEVICE; } |
325         PSEUDO_DEVICE Init_dev Dev
326               = {
327                 cur.d_name = $3;
328                 cur.d_type = PSEUDO_DEVICE;
329                 } |
330         PSEUDO_DEVICE Init_dev Dev NUMBER
331               = {
332                 cur.d_name = $3;
333                 cur.d_type = PSEUDO_DEVICE;
334                 cur.d_count = $4;
335                 } ;
336
337 Dev_spec:
338         Init_dev Dev
339               = {
340                 cur.d_name = $2;
341                 cur.d_unit = UNKNOWN;
342                 } |
343         Init_dev Dev NUMBER Dev_info
344               = {
345                 cur.d_name = $2;
346                 cur.d_unit = $3;
347                 };
348
349 Init_dev:
350         /* lambda */
351               = { init_dev(&cur); };
352
353 Dev_info:
354         Con_info Info_list
355                 |
356         /* lambda */
357                 ;
358
359 Con_info:
360         AT Dev NUMBER
361               = {
362                 connect($2, $3);
363                 cur.d_conn = $2;
364                 cur.d_connunit = $3;
365                 } |
366         AT NEXUS NUMBER
367               = {
368                 cur.d_conn = "nexus";
369                 cur.d_connunit = 0;
370                 };
371     
372 Info_list:
373         Info_list Info
374                 |
375         /* lambda */
376                 ;
377
378 Info:
379         BUS NUMBER      /* device scbus1 at ahc0 bus 1 - twin channel */
380               = { cur.d_bus = $2; } |
381         TARGET NUMBER
382               = { cur.d_target = $2; } |
383         UNIT NUMBER
384               = { cur.d_lun = $2; } |
385         DRIVE NUMBER
386               = { cur.d_drive = $2; } |
387         IRQ NUMBER
388               = { cur.d_irq = $2; } |
389         DRQ NUMBER
390               = { cur.d_drq = $2; } |
391         IOMEM NUMBER
392               = { cur.d_maddr = $2; } |
393         IOSIZ NUMBER
394               = { cur.d_msize = $2; } |
395         PORT device_name
396               = { cur.d_port = $2; } |
397         PORT NUMBER
398               = { cur.d_portn = $2; } |
399         FLAGS NUMBER
400               = { cur.d_flags = $2; } |
401         DISABLE 
402               = { cur.d_disabled = 1; }
403
404 %%
405
406 static void
407 yyerror(const char *s)
408 {
409
410         errx(1, "line %d: %s", yyline + 1, s);
411 }
412
413 /*
414  * add a device to the list of devices
415  */
416 static void
417 newdev(struct device *dp)
418 {
419         struct device *np, *xp;
420
421         if (dp->d_unit >= 0) {
422                 for (xp = dtab; xp != NULL; xp = xp->d_next) {
423                         if ((xp->d_unit == dp->d_unit) &&
424                             !strcmp(xp->d_name, dp->d_name)) {
425                                 errx(1, "line %d: already seen device %s%d",
426                                     yyline, xp->d_name, xp->d_unit);
427                         }
428                 }
429         }
430         np = malloc(sizeof(*np));
431         bzero(np, sizeof(*np));
432         *np = *dp;
433         np->d_next = NULL;
434         if (curp == NULL)
435                 dtab = np;
436         else
437                 curp->d_next = np;
438         curp = np;
439 }
440
441
442 /*
443  * find the pointer to connect to the given device and number.
444  * returns 0 if no such device and prints an error message
445  */
446 static int
447 connect(char *dev, int num)
448 {
449         struct device *dp;
450
451         if (num == QUES) {
452                 for (dp = dtab; dp != NULL; dp = dp->d_next)
453                         if (!strcmp(dp->d_name, dev))
454                                 break;
455                 if (dp == NULL) {
456                         snprintf(errbuf, sizeof(errbuf),
457                             "no %s's to wildcard", dev);
458                         yyerror(errbuf);
459                         return(0);
460                 }
461                 return(1);
462         }
463         for (dp = dtab; dp != NULL; dp = dp->d_next) {
464                 if ((num != dp->d_unit) || strcmp(dev, dp->d_name))
465                         continue;
466                 if (dp->d_type != DEVICE) {
467                         snprintf(errbuf, sizeof(errbuf), 
468                             "%s connected to non-device", dev);
469                         yyerror(errbuf);
470                         return(0);
471                 }
472                 return(1);
473         }
474         snprintf(errbuf, sizeof(errbuf), "%s %d not defined", dev, num);
475         yyerror(errbuf);
476         return(0);
477 }
478
479 void
480 init_dev(struct device *dp)
481 {
482
483         dp->d_name = "OHNO!!!";
484         dp->d_type = DEVICE;
485         dp->d_conn = 0;
486         dp->d_disabled = 0;
487         dp->d_flags = 0;
488         dp->d_bus = dp->d_lun = dp->d_target = dp->d_drive = dp->d_unit =
489             dp->d_count = UNKNOWN;
490         dp->d_port = NULL;
491         dp->d_portn = -1;
492         dp->d_irq = -1;
493         dp->d_drq = -1;
494         dp->d_maddr = 0;
495         dp->d_msize = 0;
496 }