mkheaders.c revision 45744
1251875Speter/*
2251875Speter * Copyright (c) 1980, 1993
3251875Speter *	The Regents of the University of California.  All rights reserved.
4251875Speter *
5251875Speter * Redistribution and use in source and binary forms, with or without
6251875Speter * modification, are permitted provided that the following conditions
7251875Speter * are met:
8251875Speter * 1. Redistributions of source code must retain the above copyright
9251875Speter *    notice, this list of conditions and the following disclaimer.
10251875Speter * 2. Redistributions in binary form must reproduce the above copyright
11251875Speter *    notice, this list of conditions and the following disclaimer in the
12251875Speter *    documentation and/or other materials provided with the distribution.
13251875Speter * 3. All advertising materials mentioning features or use of this software
14251875Speter *    must display the following acknowledgement:
15251875Speter *	This product includes software developed by the University of
16251875Speter *	California, Berkeley and its contributors.
17251875Speter * 4. Neither the name of the University nor the names of its contributors
18251875Speter *    may be used to endorse or promote products derived from this software
19251875Speter *    without specific prior written permission.
20251875Speter *
21251875Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22251875Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23251875Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24251875Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25251875Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26251875Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27251875Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28251875Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29251875Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30251875Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31251875Speter * SUCH DAMAGE.
32251875Speter */
33251875Speter
34251875Speter#ifndef lint
35251875Speter#if 0
36251875Speterstatic char sccsid[] = "@(#)mkheaders.c	8.1 (Berkeley) 6/6/93";
37251875Speter#endif
38251875Speterstatic const char rcsid[] =
39251875Speter	"$Id: mkheaders.c,v 1.8 1997/11/07 00:09:40 joerg Exp $";
40251875Speter#endif /* not lint */
41251875Speter
42251875Speter/*
43251875Speter * Make all the .h files for the optional entries
44251875Speter */
45251875Speter
46251875Speter#include <ctype.h>
47251875Speter#include <err.h>
48251875Speter#include <stdio.h>
49251875Speter#include <string.h>
50251875Speter#include "config.h"
51251875Speter#include "y.tab.h"
52251875Speter
53251875Speter#define ns(s) strdup(s)
54251875Speter
55251875Speterstatic void do_header __P((char *, char *, int));
56251875Speterstatic void do_count __P((char *, char *, int));
57251875Speterstatic char *toheader __P((char *));
58251875Speterstatic char *tomacro __P((char *));
59251875Speter
60251875Spetervoid
61251875Speterheaders()
62251875Speter{
63251875Speter	register struct file_list *fl;
64251875Speter	struct device *dp;
65251875Speter
66251875Speter	for (fl = ftab; fl != 0; fl = fl->f_next)
67251875Speter		if (fl->f_needs != 0)
68251875Speter			do_count(fl->f_needs, fl->f_needs, 1);
69251875Speter	for (dp = dtab; dp != 0; dp = dp->d_next)
70251875Speter		if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE) {
71251875Speter			if (!(dp->d_type & DEVDONE))
72251875Speter				printf("Warning: pseudo-device \"%s\" is unknown\n",
73251875Speter				       dp->d_name);
74251875Speter			else
75251875Speter				dp->d_type &= TYPEMASK;
76251875Speter		}
77251875Speter}
78251875Speter
79251875Speter/*
80251875Speter * count all the devices of a certain type and recurse to count
81251875Speter * whatever the device is connected to
82251875Speter */
83251875Speterstatic void
84251875Speterdo_count(dev, hname, search)
85251875Speter	register char *dev, *hname;
86251875Speter	int search;
87251875Speter{
88251875Speter	register struct device *dp, *mp;
89251875Speter	register int count, hicount;
90251875Speter
91251875Speter	/*
92251875Speter	 * After this loop, "count" will be the actual number of units,
93251875Speter	 * and "hicount" will be the highest unit declared.  do_header()
94251875Speter	 * must use this higher of these values.
95251875Speter	 */
96251875Speter	for (hicount = count = 0, dp = dtab; dp != 0; dp = dp->d_next)
97251875Speter		if (dp->d_unit != -1 && eq(dp->d_name, dev)) {
98251875Speter			if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE) {
99251875Speter				count =
100251875Speter				    dp->d_slave != UNKNOWN ? dp->d_slave : 1;
101251875Speter				dp->d_type |= DEVDONE;
102251875Speter				break;
103251875Speter			}
104251875Speter			count++;
105251875Speter			/*
106251875Speter			 * Allow holes in unit numbering,
107251875Speter			 * assumption is unit numbering starts
108251875Speter			 * at zero.
109251875Speter			 */
110251875Speter			if (dp->d_unit + 1 > hicount)
111251875Speter				hicount = dp->d_unit + 1;
112251875Speter			if (search) {
113251875Speter				mp = dp->d_conn;
114251875Speter				if (mp != 0 && mp != TO_NEXUS &&
115251875Speter				    mp->d_conn != 0 && mp->d_conn != TO_NEXUS) {
116251875Speter					do_count(mp->d_name, hname, 0);
117251875Speter					search = 0;
118251875Speter				}
119251875Speter			}
120251875Speter		}
121251875Speter	do_header(dev, hname, count > hicount ? count : hicount);
122251875Speter}
123251875Speter
124251875Speterstatic void
125251875Speterdo_header(dev, hname, count)
126251875Speter	char *dev, *hname;
127251875Speter	int count;
128251875Speter{
129251875Speter	char *file, *name, *inw;
130251875Speter	struct file_list *fl, *fl_head, *tflp;
131251875Speter	FILE *inf, *outf;
132251875Speter	int inc, oldcount;
133251875Speter
134251875Speter	file = toheader(hname);
135251875Speter	name = tomacro(dev);
136251875Speter	inf = fopen(file, "r");
137251875Speter	oldcount = -1;
138251875Speter	if (inf == 0) {
139251875Speter		outf = fopen(file, "w");
140251875Speter		if (outf == 0)
141251875Speter			err(1, "%s", file);
142251875Speter		fprintf(outf, "#define %s %d\n", name, count);
143251875Speter		(void) fclose(outf);
144251875Speter		return;
145251875Speter	}
146251875Speter	fl_head = NULL;
147251875Speter	for (;;) {
148251875Speter		char *cp;
149251875Speter		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
150			break;
151		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
152			break;
153		inw = ns(inw);
154		cp = get_word(inf);
155		if (cp == 0 || cp == (char *)EOF)
156			break;
157		inc = atoi(cp);
158		if (eq(inw, name)) {
159			oldcount = inc;
160			inc = count;
161		}
162		cp = get_word(inf);
163		if (cp == (char *)EOF)
164			break;
165		fl = (struct file_list *) malloc(sizeof *fl);
166		bzero(fl, sizeof(*fl));
167		fl->f_fn = inw;		/* malloced */
168		fl->f_type = inc;
169		fl->f_next = fl_head;
170		fl_head = fl;
171	}
172	(void) fclose(inf);
173	if (count == oldcount) {
174		for (fl = fl_head; fl != NULL; fl = tflp) {
175			tflp = fl->f_next;
176			free(fl->f_fn);
177			free(fl);
178		}
179		return;
180	}
181	if (oldcount == -1) {
182		fl = (struct file_list *) malloc(sizeof *fl);
183		bzero(fl, sizeof(*fl));
184		fl->f_fn = ns(name);
185		fl->f_type = count;
186		fl->f_next = fl_head;
187		fl_head = fl;
188	}
189	outf = fopen(file, "w");
190	if (outf == 0)
191		err(1, "%s", file);
192	for (fl = fl_head; fl != NULL; fl = tflp) {
193		fprintf(outf,
194		    "#define %s %u\n", fl->f_fn, count ? fl->f_type : 0);
195		tflp = fl->f_next;
196		free(fl->f_fn);
197		free(fl);
198	}
199	(void) fclose(outf);
200}
201
202/*
203 * convert a dev name to a .h file name
204 */
205static char *
206toheader(dev)
207	char *dev;
208{
209	static char hbuf[80];
210
211	(void) strcpy(hbuf, path(dev));
212	(void) strcat(hbuf, ".h");
213	return (hbuf);
214}
215
216/*
217 * convert a dev name to a macro name
218 */
219static char *
220tomacro(dev)
221	register char *dev;
222{
223	static char mbuf[20];
224	register char *cp;
225
226	cp = mbuf;
227	*cp++ = 'N';
228	while (*dev)
229		*cp++ = islower(*dev) ? toupper(*dev++) : *dev++;
230	*cp++ = 0;
231	return (mbuf);
232}
233