mkheaders.c revision 31001
198937Sdes/*
298937Sdes * Copyright (c) 1980, 1993
398937Sdes *	The Regents of the University of California.  All rights reserved.
498937Sdes *
598937Sdes * Redistribution and use in source and binary forms, with or without
6147001Sdes * modification, are permitted provided that the following conditions
7126274Sdes * are met:
898937Sdes * 1. Redistributions of source code must retain the above copyright
998937Sdes *    notice, this list of conditions and the following disclaimer.
1098937Sdes * 2. Redistributions in binary form must reproduce the above copyright
1198937Sdes *    notice, this list of conditions and the following disclaimer in the
12126274Sdes *    documentation and/or other materials provided with the distribution.
13106121Sdes * 3. All advertising materials mentioning features or use of this software
1498937Sdes *    must display the following acknowledgement:
1598937Sdes *	This product includes software developed by the University of
1698937Sdes *	California, Berkeley and its contributors.
1798937Sdes * 4. Neither the name of the University nor the names of its contributors
1898937Sdes *    may be used to endorse or promote products derived from this software
19126274Sdes *    without specific prior written permission.
20126274Sdes *
21126274Sdes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2298937Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2398937Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2498937Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2598937Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2698937Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2798937Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2898937Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2998937Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3098937Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3198937Sdes * SUCH DAMAGE.
3298937Sdes */
33137015Sdes
3498937Sdes#ifndef lint
3598937Sdes#if 0
36124208Sdesstatic char sccsid[] = "@(#)mkheaders.c	8.1 (Berkeley) 6/6/93";
3798937Sdes#endif
3898937Sdesstatic const char rcsid[] =
3998937Sdes	"$Id: mkheaders.c,v 1.7 1997/10/28 07:21:02 joerg Exp $";
40126274Sdes#endif /* not lint */
4198937Sdes
4298937Sdes/*
4398937Sdes * Make all the .h files for the optional entries
4498937Sdes */
4598937Sdes
4698937Sdes#include <ctype.h>
4798937Sdes#include <err.h>
4898937Sdes#include <stdio.h>
4998937Sdes#include <string.h>
5098937Sdes#include "config.h"
5198937Sdes#include "y.tab.h"
5298937Sdes
53147001Sdes#define ns(s) strdup(s)
54147001Sdes
55147001Sdesvoid do_header __P((char *, char *, int));
56147001Sdesvoid do_count __P((char *, char *, int));
5798937Sdes
5898937Sdesvoid
59146998Sdesheaders()
60146998Sdes{
61146998Sdes	register struct file_list *fl;
62146998Sdes	struct device *dp;
63147001Sdes
64146998Sdes	for (fl = ftab; fl != 0; fl = fl->f_next)
65146998Sdes		if (fl->f_needs != 0)
66146998Sdes			do_count(fl->f_needs, fl->f_needs, 1);
6798937Sdes	for (dp = dtab; dp != 0; dp = dp->d_next)
6898937Sdes		if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE) {
6998937Sdes			if (!(dp->d_type & DEVDONE))
7098937Sdes				printf("Warning: pseudo-device \"%s\" is unknown\n",
7198937Sdes				       dp->d_name);
7298937Sdes			else
7398937Sdes				dp->d_type &= TYPEMASK;
7498937Sdes		}
7598937Sdes}
7698937Sdes
7798937Sdes/*
7898937Sdes * count all the devices of a certain type and recurse to count
7998937Sdes * whatever the device is connected to
8098937Sdes */
8198937Sdesvoid
8298937Sdesdo_count(dev, hname, search)
8398937Sdes	register char *dev, *hname;
84126274Sdes	int search;
8598937Sdes{
8698937Sdes	register struct device *dp, *mp;
8798937Sdes	register int count, hicount;
8898937Sdes
8998937Sdes	/*
9098937Sdes	 * After this loop, "count" will be the actual number of units,
9198937Sdes	 * and "hicount" will be the highest unit declared.  do_header()
9298937Sdes	 * must use this higher of these values.
9398937Sdes	 */
94147001Sdes	for (hicount = count = 0, dp = dtab; dp != 0; dp = dp->d_next)
95147001Sdes		if (dp->d_unit != -1 && eq(dp->d_name, dev)) {
96147001Sdes			if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE) {
97147001Sdes				count =
9898937Sdes				    dp->d_slave != UNKNOWN ? dp->d_slave : 1;
9998937Sdes				dp->d_type |= DEVDONE;
10098937Sdes				break;
10198937Sdes			}
10298937Sdes			count++;
10398937Sdes			/*
10498937Sdes			 * Allow holes in unit numbering,
10598937Sdes			 * assumption is unit numbering starts
10698937Sdes			 * at zero.
10798937Sdes			 */
10898937Sdes			if (dp->d_unit + 1 > hicount)
10998937Sdes				hicount = dp->d_unit + 1;
11098937Sdes			if (search) {
11198937Sdes				mp = dp->d_conn;
11298937Sdes				if (mp != 0 && mp != TO_NEXUS &&
11398937Sdes				    mp->d_conn != 0 && mp->d_conn != TO_NEXUS) {
11498937Sdes					do_count(mp->d_name, hname, 0);
11598937Sdes					search = 0;
116124208Sdes				}
117124208Sdes			}
11898937Sdes		}
119126274Sdes	do_header(dev, hname, count > hicount ? count : hicount);
120126274Sdes}
121126274Sdes
12298937Sdesvoid
12398937Sdesdo_header(dev, hname, count)
124126274Sdes	char *dev, *hname;
125126274Sdes	int count;
126126274Sdes{
12798937Sdes	char *file, *name, *inw, *toheader(), *tomacro();
12898937Sdes	struct file_list *fl, *fl_head, *tflp;
129126274Sdes	FILE *inf, *outf;
13098937Sdes	int inc, oldcount;
13198937Sdes
13298937Sdes	file = toheader(hname);
13398937Sdes	name = tomacro(dev);
13498937Sdes	inf = fopen(file, "r");
135126274Sdes	oldcount = -1;
13698937Sdes	if (inf == 0) {
13798937Sdes		outf = fopen(file, "w");
138126274Sdes		if (outf == 0)
13998937Sdes			err(1, "%s", file);
14098937Sdes		fprintf(outf, "#define %s %d\n", name, count);
14198937Sdes		(void) fclose(outf);
14298937Sdes		return;
14398937Sdes	}
14498937Sdes	fl_head = NULL;
145126274Sdes	for (;;) {
146126274Sdes		char *cp;
147126274Sdes		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
14898937Sdes			break;
149126274Sdes		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
15098937Sdes			break;
15198937Sdes		inw = ns(inw);
15298937Sdes		cp = get_word(inf);
15398937Sdes		if (cp == 0 || cp == (char *)EOF)
154126274Sdes			break;
15598937Sdes		inc = atoi(cp);
15698937Sdes		if (eq(inw, name)) {
15798937Sdes			oldcount = inc;
15898937Sdes			inc = count;
15998937Sdes		}
16098937Sdes		cp = get_word(inf);
16198937Sdes		if (cp == (char *)EOF)
16298937Sdes			break;
16398937Sdes		fl = (struct file_list *) malloc(sizeof *fl);
16498937Sdes		bzero(fl, sizeof(*fl));
16598937Sdes		fl->f_fn = inw;		/* malloced */
16698937Sdes		fl->f_type = inc;
16798937Sdes		fl->f_next = fl_head;
16898937Sdes		fl_head = fl;
16998937Sdes	}
17098937Sdes	(void) fclose(inf);
17198937Sdes	if (count == oldcount) {
17298937Sdes		for (fl = fl_head; fl != NULL; fl = tflp) {
17398937Sdes			tflp = fl->f_next;
17498937Sdes			free(fl->f_fn);
17598937Sdes			free(fl);
17698937Sdes		}
17798937Sdes		return;
17898937Sdes	}
17998937Sdes	if (oldcount == -1) {
18098937Sdes		fl = (struct file_list *) malloc(sizeof *fl);
18198937Sdes		bzero(fl, sizeof(*fl));
18298937Sdes		fl->f_fn = ns(name);
18398937Sdes		fl->f_type = count;
184126274Sdes		fl->f_next = fl_head;
18598937Sdes		fl_head = fl;
18698937Sdes	}
187126274Sdes	outf = fopen(file, "w");
18898937Sdes	if (outf == 0)
18998937Sdes		err(1, "%s", file);
19098937Sdes	for (fl = fl_head; fl != NULL; fl = tflp) {
191126274Sdes		fprintf(outf,
19298937Sdes		    "#define %s %u\n", fl->f_fn, count ? fl->f_type : 0);
19398937Sdes		tflp = fl->f_next;
19498937Sdes		free(fl->f_fn);
19598937Sdes		free(fl);
19698937Sdes	}
19798937Sdes	(void) fclose(outf);
198126274Sdes}
19998937Sdes
20098937Sdes/*
20198937Sdes * convert a dev name to a .h file name
20298937Sdes */
20398937Sdeschar *
204126274Sdestoheader(dev)
20598937Sdes	char *dev;
20698937Sdes{
207146998Sdes	static char hbuf[80];
208146998Sdes
209146998Sdes	(void) strcpy(hbuf, path(dev));
210146998Sdes	(void) strcat(hbuf, ".h");
211146998Sdes	return (hbuf);
212146998Sdes}
213146998Sdes
214146998Sdes/*
215146998Sdes * convert a dev name to a macro name
216146998Sdes */
217146998Sdeschar *tomacro(dev)
218146998Sdes	register char *dev;
219146998Sdes{
220146998Sdes	static char mbuf[20];
22198937Sdes	register char *cp;
22298937Sdes
223126274Sdes	cp = mbuf;
22498937Sdes	*cp++ = 'N';
22598937Sdes	while (*dev)
22698937Sdes		*cp++ = islower(*dev) ? toupper(*dev++) : *dev++;
22798937Sdes	*cp++ = 0;
228147001Sdes	return (mbuf);
229}
230