1/*
2 * Mach Operating System
3 * Copyright (c) 1990 Carnegie-Mellon University
4 * Copyright (c) 1989 Carnegie-Mellon University
5 * Copyright (c) 1988 Carnegie-Mellon University
6 * Copyright (c) 1987 Carnegie-Mellon University
7 * All rights reserved.  The CMU software License Agreement specifies
8 * the terms and conditions for use and redistribution.
9 */
10
11/*
12 * Copyright (c) 1988 Regents of the University of California.
13 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms are permitted
16 * provided that the above copyright notice and this paragraph are
17 * duplicated in all such forms and that any documentation,
18 * advertising materials, and other materials related to such
19 * distribution and use acknowledge that the software was developed
20 * by the University of California, Berkeley.  The name of the
21 * University may not be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
25 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26 *
27 *	@(#)config.y	5.8 (Berkeley) 6/18/88
28 */
29
30%union {
31	char	*str;
32	int	val;
33	struct	file_list *file;
34	struct	idlst *lst;
35}
36
37%token	BUILDDIR
38%token	COMMA
39%token	EQUALS
40%token	INIT
41%token	MACHINE
42%token	OBJECTDIR
43%token	OPTIONS
44%token	MAKEOPTIONS
45%token	PSEUDO_DEVICE
46%token	SEMICOLON
47%token	SOURCEDIR
48%token	TRACE
49
50%token	<str>	ID
51%token	<val>	NUMBER
52
53%type	<str>	Save_id
54%type	<str>	Opt_value
55%type	<str>	Dev
56
57%{
58
59#include "config.h"
60#include <ctype.h>
61#include <stdio.h>
62
63struct	device cur;
64struct	device *curp = 0;
65char	*temp_id;
66char	*val_id;
67/* char	*malloc(); */
68
69int yylex(void);
70
71void deverror(const char *systemname, const char *devtype);
72
73%}
74%%
75Configuration:
76	Many_specs
77		;
78
79Many_specs:
80	Many_specs Spec
81		|
82	/* lambda */
83		;
84
85Spec:
86	Device_spec SEMICOLON
87	      { newdev(&cur); } |
88	Config_spec SEMICOLON
89		|
90	TRACE SEMICOLON
91	      { do_trace = !do_trace; } |
92	SEMICOLON
93		|
94	error SEMICOLON
95		;
96
97Config_spec:
98	MACHINE Save_id
99		{ machinename = ns($2); }
100		|
101	OPTIONS Opt_list
102		|
103	MAKEOPTIONS Mkopt_list
104		|
105	BUILDDIR Save_id
106		{ build_directory = ns($2); }
107		|
108	OBJECTDIR Save_id
109		{ object_directory = ns($2); }
110		|
111	SOURCEDIR Save_id
112		{ source_directory = ns($2); }
113		;
114
115
116Opt_list:
117	Opt_list COMMA Option
118		|
119	Option
120		;
121
122Option:
123	Save_id
124	      {
125		struct opt *op = (struct opt *)malloc(sizeof (struct opt));
126		op->op_name = ns($1);
127		op->op_next = (struct opt *) 0;
128		op->op_value = 0;
129		if (opt == (struct opt *) 0)
130			opt = op;
131		else
132			opt_tail->op_next = op;
133		opt_tail = op;
134		free(temp_id);
135	      } |
136	Save_id EQUALS Opt_value
137	      {
138		struct opt *op = (struct opt *)malloc(sizeof (struct opt));
139		op->op_name = ns($1);
140		op->op_next = (struct opt *) 0;
141		op->op_value = ns($3);
142		if (opt == (struct opt *) 0)
143			opt = op;
144		else
145			opt_tail->op_next = op;
146		opt_tail = op;
147		free(temp_id);
148		if (val_id)
149			free(val_id);
150	      } ;
151
152Opt_value:
153	ID
154	      { $$ = val_id = ns($1); } |
155	NUMBER
156	      { char nb[16];
157	          (void) sprintf(nb, "%u", $1);
158	      	  $$ = val_id = ns(nb);
159	      } |
160	/* lambda from MIPS -- WHY */
161	      { $$ = val_id = ns(""); }
162	      ;
163
164Save_id:
165	ID
166	      { $$ = temp_id = ns($1); }
167	;
168
169Mkopt_list:
170	Mkopt_list COMMA Mkoption
171		|
172	Mkoption
173		;
174
175Mkoption:
176	Save_id
177	      {
178		struct opt *op = (struct opt *)malloc(sizeof (struct opt));
179		op->op_name = ns($1);
180		op->op_next =  (struct opt *) 0;
181		op->op_value = 0;
182		mkopt = op;
183		free(temp_id);
184	      } |
185	Save_id EQUALS Opt_value
186	      {
187		struct opt *op = (struct opt *)malloc(sizeof (struct opt));
188		op->op_name = ns($1);
189		op->op_next =  (struct opt *) 0;
190		op->op_value = ns($3);
191		if (mkopt == (struct opt *) 0)
192			mkopt = op;
193		else
194			mkopt_tail->op_next = op;
195		mkopt_tail = op;
196		free(temp_id);
197		if (val_id)
198			free(val_id);
199	      } ;
200
201Dev:
202	ID
203	      { $$ = ns($1); }
204	;
205
206Device_spec:
207	PSEUDO_DEVICE Init_dev Dev
208	      {
209		cur.d_name = $3;
210		cur.d_type = PSEUDO_DEVICE;
211		} |
212	PSEUDO_DEVICE Init_dev Dev NUMBER
213	      {
214		cur.d_name = $3;
215		cur.d_type = PSEUDO_DEVICE;
216		cur.d_slave = $4;
217		} |
218	PSEUDO_DEVICE Init_dev Dev INIT ID
219	      {
220		cur.d_name = $3;
221		cur.d_type = PSEUDO_DEVICE;
222		cur.d_init = ns($5);
223		} |
224	PSEUDO_DEVICE Init_dev Dev NUMBER INIT ID
225	      {
226		cur.d_name = $3;
227		cur.d_type = PSEUDO_DEVICE;
228		cur.d_slave = $4;
229		cur.d_init = ns($6);
230		};
231
232Init_dev:
233	/* lambda */
234	      { init_dev(&cur); };
235
236%%
237
238void
239yyerror(const char *s)
240{
241	fprintf(stderr, "config: line %d: %s\n", yyline, s);
242}
243
244/*
245 * return the passed string in a new space
246 */
247char *
248ns(const char *str)
249{
250	register char *cp;
251
252	cp = malloc((unsigned)(strlen(str)+1));
253	(void) strcpy(cp, str);
254	return (cp);
255}
256
257/*
258 * add a device to the list of devices
259 */
260void
261newdev(struct device *dp)
262{
263	register struct device *np;
264
265	np = (struct device *) malloc(sizeof *np);
266	*np = *dp;
267	if (curp == 0)
268		dtab = np;
269	else
270		curp->d_next = np;
271	curp = np;
272	curp->d_next = 0;
273}
274
275void
276init_dev(struct device *dp)
277{
278
279	dp->d_name = "OHNO!!!";
280	dp->d_type = PSEUDO_DEVICE;
281	dp->d_flags = 0;
282	dp->d_slave = UNKNOWN;
283	dp->d_init = 0;
284}
285
286void
287deverror(const char *systemname, const char *devtype)
288{
289
290	fprintf(stderr, "config: %s: %s device not configured\n",
291		systemname, devtype);
292}
293