]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/config/mkheaders.c
Check for missing static unit 'count' declarations as well.
[FreeBSD/FreeBSD.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
34 #ifndef lint
35 #if 0
36 static char sccsid[] = "@(#)mkheaders.c 8.1 (Berkeley) 6/6/93";
37 #endif
38 static const char rcsid[] =
39   "$FreeBSD$";
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 <sys/param.h>
51 #include "config.h"
52 #include "y.tab.h"
53
54 static int do_header(char *, int);
55 static void nocount(char *);
56 static char *toheader(char *);
57 static char *tomacro(char *);
58
59 void
60 headers(void)
61 {
62         struct file_list *fl;
63         struct device *dp;
64         int match;
65         int errors;
66
67         errors = 0;
68         for (fl = ftab; fl != 0; fl = fl->f_next) {
69                 if (fl->f_needs != 0) {
70                         match = 0;
71                         for (dp = dtab; dp != 0; dp = dp->d_next) {
72                                 if (eq(dp->d_name, fl->f_needs)) {
73                                         match++;
74                                         dp->d_done |= DEVDONE;
75                                 }
76                         }
77                         if (fl->f_flags & NEED_COUNT)
78                                 errors += do_header(fl->f_needs, match);
79                 }
80         }
81         for (dp = dtab; dp != 0; dp = dp->d_next) {
82                 if (!(dp->d_done & DEVDONE)) {
83                         warnx("Error: device \"%s\" is unknown",
84                                dp->d_name);
85                                errors++;
86                         }
87                 if (dp->d_count == UNKNOWN)
88                         continue;
89                 match = 0;
90                 for (fl = ftab; fl != 0; fl = fl->f_next) {
91                         if (fl->f_needs == 0)
92                                 continue;
93                         if ((fl->f_flags & NEED_COUNT) == 0)
94                                 continue;
95                         if (eq(dp->d_name, fl->f_needs)) {
96                                 match++;
97                                 break;
98                         }
99                 }
100                 if (match == 0) {
101                         warnx("Error: device \"%s\" does not take a count",
102                             dp->d_name);
103                         errors++;
104                 }
105         }
106         if (errors)
107                 errx(1, "%d errors", errors);
108 }
109
110 static int
111 do_header(char *dev, int match)
112 {
113         char *file, *name, *inw;
114         struct file_list *fl, *fl_head, *tflp;
115         struct device *dp;
116         FILE *inf, *outf;
117         int inc, oldcount;
118         int count, hicount;
119         int errors;
120
121         /*
122          * After this loop, "count" will be the actual number of units,
123          * and "hicount" will be the highest unit declared.  do_header()
124          * must use this higher of these values.
125          */
126         errors = 0;
127         for (hicount = count = 0, dp = dtab; dp != 0; dp = dp->d_next) {
128                 if (eq(dp->d_name, dev)) {
129                         if (dp->d_count == UNKNOWN) {
130                                 warnx("Device \"%s\" requires a count", dev);
131                                 return 1;
132                         }
133                         count = dp->d_count;
134                         break;
135                 }
136         }
137         file = toheader(dev);
138         name = tomacro(dev);
139         if (match)
140                 printf("FYI: static unit limits for %s are set: %s=%d\n", dev, name, count);
141         remember(file);
142         inf = fopen(file, "r");
143         oldcount = -1;
144         if (inf == 0) {
145                 outf = fopen(file, "w");
146                 if (outf == 0)
147                         err(1, "%s", file);
148                 fprintf(outf, "#define %s %d\n", name, count);
149                 (void) fclose(outf);
150                 return 0;
151         }
152         fl_head = NULL;
153         for (;;) {
154                 char *cp;
155                 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
156                         break;
157                 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
158                         break;
159                 inw = ns(inw);
160                 cp = get_word(inf);
161                 if (cp == 0 || cp == (char *)EOF)
162                         break;
163                 inc = atoi(cp);
164                 if (eq(inw, name)) {
165                         oldcount = inc;
166                         inc = count;
167                 }
168                 cp = get_word(inf);
169                 if (cp == (char *)EOF)
170                         break;
171                 fl = (struct file_list *) malloc(sizeof *fl);
172                 bzero(fl, sizeof(*fl));
173                 fl->f_fn = inw;         /* malloced */
174                 fl->f_type = inc;
175                 fl->f_next = fl_head;
176                 fl_head = fl;
177         }
178         (void) fclose(inf);
179         if (count == oldcount) {
180                 for (fl = fl_head; fl != NULL; fl = tflp) {
181                         tflp = fl->f_next;
182                         free(fl->f_fn);
183                         free(fl);
184                 }
185                 return 0;
186         }
187         if (oldcount == -1) {
188                 fl = (struct file_list *) malloc(sizeof *fl);
189                 bzero(fl, sizeof(*fl));
190                 fl->f_fn = ns(name);
191                 fl->f_type = count;
192                 fl->f_next = fl_head;
193                 fl_head = fl;
194         }
195         outf = fopen(file, "w");
196         if (outf == 0)
197                 err(1, "%s", file);
198         for (fl = fl_head; fl != NULL; fl = tflp) {
199                 fprintf(outf,
200                     "#define %s %u\n", fl->f_fn, count ? fl->f_type : 0);
201                 tflp = fl->f_next;
202                 free(fl->f_fn);
203                 free(fl);
204         }
205         (void) fclose(outf);
206         return 0;
207 }
208
209 /*
210  * convert a dev name to a .h file name
211  */
212 static char *
213 toheader(char *dev)
214 {
215         static char hbuf[MAXPATHLEN];
216
217         snprintf(hbuf, sizeof(hbuf), "%s.h", path(dev));
218         return (hbuf);
219 }
220
221 /*
222  * convert a dev name to a macro name
223  */
224 static char *
225 tomacro(char *dev)
226 {
227         static char mbuf[20];
228         char *cp;
229
230         cp = mbuf;
231         *cp++ = 'N';
232         while (*dev)
233                 *cp++ = islower(*dev) ? toupper(*dev++) : *dev++;
234         *cp++ = 0;
235         return (mbuf);
236 }