mkheaders.c revision 30796
1/*
2 * Copyright (c) 1980, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35#if 0
36static char sccsid[] = "@(#)mkheaders.c	8.1 (Berkeley) 6/6/93";
37#endif
38static const char rcsid[] =
39	"$Id: mkheaders.c,v 1.6 1997/09/15 06:37:09 charnier Exp $";
40#endif /* not lint */
41
42/*
43 * Make all the .h files for the optional entries
44 */
45
46#include <ctype.h>
47#include <err.h>
48#include <stdio.h>
49#include <string.h>
50#include "config.h"
51#include "y.tab.h"
52
53#define ns(s) strdup(s)
54
55void do_header __P((char *, char *, int));
56void do_count __P((char *, char *, int));
57
58void
59headers()
60{
61	register struct file_list *fl;
62	struct device *dp;
63
64	for (fl = ftab; fl != 0; fl = fl->f_next)
65		if (fl->f_needs != 0)
66			do_count(fl->f_needs, fl->f_needs, 1);
67	for (dp = dtab; dp != 0; dp = dp->d_next)
68		if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE) {
69			if (!(dp->d_type & DEVDONE))
70				printf("Warning: pseudo-device \"%s\" is unknown\n",
71				       dp->d_name);
72			else
73				dp->d_type &= TYPEMASK;
74		}
75}
76
77/*
78 * count all the devices of a certain type and recurse to count
79 * whatever the device is connected to
80 */
81void
82do_count(dev, hname, search)
83	register char *dev, *hname;
84	int search;
85{
86	register struct device *dp, *mp;
87	register int count, hicount;
88
89	/*
90	 * After this loop, "count" will be the actual number of units,
91	 * and "hicount" will be the highest unit declared.  do_header()
92	 * must use this higher of these values.
93	 */
94	for (hicount = count = 0, dp = dtab; dp != 0; dp = dp->d_next)
95		if (dp->d_unit != -1 && eq(dp->d_name, dev)) {
96			if (dp->d_type == PSEUDO_DEVICE) {
97				count =
98				    dp->d_slave != UNKNOWN ? dp->d_slave : 1;
99				dp->d_type |= DEVDONE;
100				break;
101			}
102			count++;
103			/*
104			 * Allow holes in unit numbering,
105			 * assumption is unit numbering starts
106			 * at zero.
107			 */
108			if (dp->d_unit + 1 > hicount)
109				hicount = dp->d_unit + 1;
110			if (search) {
111				mp = dp->d_conn;
112				if (mp != 0 && mp != TO_NEXUS &&
113				    mp->d_conn != 0 && mp->d_conn != TO_NEXUS) {
114					do_count(mp->d_name, hname, 0);
115					search = 0;
116				}
117			}
118		}
119	do_header(dev, hname, count > hicount ? count : hicount);
120}
121
122void
123do_header(dev, hname, count)
124	char *dev, *hname;
125	int count;
126{
127	char *file, *name, *inw, *toheader(), *tomacro();
128	struct file_list *fl, *fl_head, *tflp;
129	FILE *inf, *outf;
130	int inc, oldcount;
131
132	file = toheader(hname);
133	name = tomacro(dev);
134	inf = fopen(file, "r");
135	oldcount = -1;
136	if (inf == 0) {
137		outf = fopen(file, "w");
138		if (outf == 0)
139			err(1, "%s", file);
140		fprintf(outf, "#define %s %d\n", name, count);
141		(void) fclose(outf);
142		return;
143	}
144	fl_head = NULL;
145	for (;;) {
146		char *cp;
147		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
148			break;
149		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
150			break;
151		inw = ns(inw);
152		cp = get_word(inf);
153		if (cp == 0 || cp == (char *)EOF)
154			break;
155		inc = atoi(cp);
156		if (eq(inw, name)) {
157			oldcount = inc;
158			inc = count;
159		}
160		cp = get_word(inf);
161		if (cp == (char *)EOF)
162			break;
163		fl = (struct file_list *) malloc(sizeof *fl);
164		bzero(fl, sizeof(*fl));
165		fl->f_fn = inw;		/* malloced */
166		fl->f_type = inc;
167		fl->f_next = fl_head;
168		fl_head = fl;
169	}
170	(void) fclose(inf);
171	if (count == oldcount) {
172		for (fl = fl_head; fl != NULL; fl = tflp) {
173			tflp = fl->f_next;
174			free(fl->f_fn);
175			free(fl);
176		}
177		return;
178	}
179	if (oldcount == -1) {
180		fl = (struct file_list *) malloc(sizeof *fl);
181		bzero(fl, sizeof(*fl));
182		fl->f_fn = ns(name);
183		fl->f_type = count;
184		fl->f_next = fl_head;
185		fl_head = fl;
186	}
187	outf = fopen(file, "w");
188	if (outf == 0)
189		err(1, "%s", file);
190	for (fl = fl_head; fl != NULL; fl = tflp) {
191		fprintf(outf,
192		    "#define %s %u\n", fl->f_fn, count ? fl->f_type : 0);
193		tflp = fl->f_next;
194		free(fl->f_fn);
195		free(fl);
196	}
197	(void) fclose(outf);
198}
199
200/*
201 * convert a dev name to a .h file name
202 */
203char *
204toheader(dev)
205	char *dev;
206{
207	static char hbuf[80];
208
209	(void) strcpy(hbuf, path(dev));
210	(void) strcat(hbuf, ".h");
211	return (hbuf);
212}
213
214/*
215 * convert a dev name to a macro name
216 */
217char *tomacro(dev)
218	register char *dev;
219{
220	static char mbuf[20];
221	register char *cp;
222
223	cp = mbuf;
224	*cp++ = 'N';
225	while (*dev)
226		*cp++ = islower(*dev) ? toupper(*dev++) : *dev++;
227	*cp++ = 0;
228	return (mbuf);
229}
230