Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / usr.sbin / config / mkheaders.c
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  * @(#)mkheaders.c      8.1 (Berkeley) 6/6/93
34  * $FreeBSD: src/usr.sbin/config/mkheaders.c,v 1.14.2.2 2001/01/23 00:09:32 peter Exp $
35  * $DragonFly: src/usr.sbin/config/mkheaders.c,v 1.2 2003/06/17 04:29:53 dillon Exp $
36  */
37
38 /*
39  * Make all the .h files for the optional entries
40  */
41
42 #include <ctype.h>
43 #include <err.h>
44 #include <stdio.h>
45 #include <string.h>
46 #include <sys/param.h>
47 #include "config.h"
48 #include "y.tab.h"
49
50 static void do_header __P((char *, char *, int));
51 static void do_count __P((char *, char *, int));
52 static char *toheader __P((char *));
53 static char *tomacro __P((char *));
54
55 void
56 headers()
57 {
58         register struct file_list *fl;
59         struct device *dp;
60
61         for (fl = ftab; fl != 0; fl = fl->f_next)
62                 if (fl->f_needs != 0)
63                         do_count(fl->f_needs, fl->f_needs, 1);
64         for (dp = dtab; dp != 0; dp = dp->d_next) {
65                 if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE) {
66                         if (!(dp->d_type & DEVDONE)) {
67                                 printf("Warning: pseudo-device \"%s\" is unknown\n",
68                                        dp->d_name);
69                                 exit(1);
70                         }
71                 }
72                 if ((dp->d_type & TYPEMASK) == DEVICE) {
73                         if (!(dp->d_type & DEVDONE)) {
74                                 printf("Warning: device \"%s\" is unknown\n",
75                                        dp->d_name);
76                                 exit(1);
77                         }
78                 }
79         }
80 }
81
82 /*
83  * count all the devices of a certain type and recurse to count
84  * whatever the device is connected to
85  */
86 static void
87 do_count(dev, hname, search)
88         register char *dev, *hname;
89         int search;
90 {
91         register struct device *dp;
92         register int count, hicount;
93         char *mp;
94
95         /*
96          * After this loop, "count" will be the actual number of units,
97          * and "hicount" will be the highest unit declared.  do_header()
98          * must use this higher of these values.
99          */
100         for (dp = dtab; dp != 0; dp = dp->d_next) {
101                 if (eq(dp->d_name, dev)) {
102                         if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE)
103                                 dp->d_type |= DEVDONE;
104                         else if ((dp->d_type & TYPEMASK) == DEVICE)
105                                 dp->d_type |= DEVDONE;
106                 }
107         }
108         for (hicount = count = 0, dp = dtab; dp != 0; dp = dp->d_next) {
109                 if (dp->d_unit != -1 && eq(dp->d_name, dev)) {
110                         if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE) {
111                                 count =
112                                     dp->d_count != UNKNOWN ? dp->d_count : 1;
113                                 break;
114                         }
115                         count++;
116                         /*
117                          * Allow holes in unit numbering,
118                          * assumption is unit numbering starts
119                          * at zero.
120                          */
121                         if (dp->d_unit + 1 > hicount)
122                                 hicount = dp->d_unit + 1;
123                         if (search) {
124                                 mp = dp->d_conn;
125                                 if (mp != 0 && dp->d_connunit < 0)
126                                         mp = 0;
127                                 if (mp != 0 && eq(mp, "nexus"))
128                                         mp = 0;
129                                 if (mp != 0) {
130                                         do_count(mp, hname, 0);
131                                         search = 0;
132                                 }
133                         }
134                 }
135         }
136         do_header(dev, hname, count > hicount ? count : hicount);
137 }
138
139 static void
140 do_header(dev, hname, count)
141         char *dev, *hname;
142         int count;
143 {
144         char *file, *name, *inw;
145         struct file_list *fl, *fl_head, *tflp;
146         FILE *inf, *outf;
147         int inc, oldcount;
148
149         file = toheader(hname);
150         name = tomacro(dev);
151         inf = fopen(file, "r");
152         oldcount = -1;
153         if (inf == 0) {
154                 outf = fopen(file, "w");
155                 if (outf == 0)
156                         err(1, "%s", file);
157                 fprintf(outf, "#define %s %d\n", name, count);
158                 (void) fclose(outf);
159                 return;
160         }
161         fl_head = NULL;
162         for (;;) {
163                 char *cp;
164                 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
165                         break;
166                 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
167                         break;
168                 inw = ns(inw);
169                 cp = get_word(inf);
170                 if (cp == 0 || cp == (char *)EOF)
171                         break;
172                 inc = atoi(cp);
173                 if (eq(inw, name)) {
174                         oldcount = inc;
175                         inc = count;
176                 }
177                 cp = get_word(inf);
178                 if (cp == (char *)EOF)
179                         break;
180                 fl = (struct file_list *) malloc(sizeof *fl);
181                 bzero(fl, sizeof(*fl));
182                 fl->f_fn = inw;         /* malloced */
183                 fl->f_type = inc;
184                 fl->f_next = fl_head;
185                 fl_head = fl;
186         }
187         (void) fclose(inf);
188         if (count == oldcount) {
189                 for (fl = fl_head; fl != NULL; fl = tflp) {
190                         tflp = fl->f_next;
191                         free(fl->f_fn);
192                         free(fl);
193                 }
194                 return;
195         }
196         if (oldcount == -1) {
197                 fl = (struct file_list *) malloc(sizeof *fl);
198                 bzero(fl, sizeof(*fl));
199                 fl->f_fn = ns(name);
200                 fl->f_type = count;
201                 fl->f_next = fl_head;
202                 fl_head = fl;
203         }
204         outf = fopen(file, "w");
205         if (outf == 0)
206                 err(1, "%s", file);
207         for (fl = fl_head; fl != NULL; fl = tflp) {
208                 fprintf(outf,
209                     "#define %s %u\n", fl->f_fn, count ? fl->f_type : 0);
210                 tflp = fl->f_next;
211                 free(fl->f_fn);
212                 free(fl);
213         }
214         (void) fclose(outf);
215 }
216
217 /*
218  * convert a dev name to a .h file name
219  */
220 static char *
221 toheader(dev)
222         char *dev;
223 {
224         static char hbuf[MAXPATHLEN];
225
226         snprintf(hbuf, sizeof(hbuf), "%s.h", path(dev));
227         return (hbuf);
228 }
229
230 /*
231  * convert a dev name to a macro name
232  */
233 static char *
234 tomacro(dev)
235         register char *dev;
236 {
237         static char mbuf[20];
238         register char *cp;
239
240         cp = mbuf;
241         *cp++ = 'N';
242         while (*dev)
243                 *cp++ = islower(*dev) ? toupper(*dev++) : *dev++;
244         *cp++ = 0;
245         return (mbuf);
246 }