Merge branch 'vendor/OPENSSL'
[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.13 2005/01/12 00:26:03 cpressey 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(const char *, char *, int);
51 static void do_count(const char *, char *, int);
52 static char *toheader(const char *);
53 static char *tomacro(const char *);
54
55 void
56 headers(void)
57 {
58         struct file_list *fl;
59         struct device *dp;
60
61         for (fl = ftab; fl != NULL; fl = fl->f_next)
62                 if (fl->f_needs != NULL)
63                         do_count(fl->f_needs, fl->f_needs, 1);
64         for (dp = dtab; dp != NULL; 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(const char *dev, char *hname, int search)
88 {
89         struct device *dp;
90         int count, hicount;
91         const char *mp;
92
93         /*
94          * After this loop, "count" will be the actual number of units,
95          * and "hicount" will be the highest unit declared. do_header()
96          * must use the higher of these values.
97          */
98         for (dp = dtab; dp != NULL; dp = dp->d_next) {
99                 if (strcmp(dp->d_name, dev) == 0) {
100                         if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE)
101                                 dp->d_type |= DEVDONE;
102                         else if ((dp->d_type & TYPEMASK) == DEVICE)
103                                 dp->d_type |= DEVDONE;
104                 }
105         }
106         for (hicount = count = 0, dp = dtab; dp != NULL; dp = dp->d_next) {
107                 if (dp->d_unit != -1 && strcmp(dp->d_name, dev) == 0) {
108                         if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE) {
109                                 count =
110                                     dp->d_count != UNKNOWN ? dp->d_count : 1;
111                                 break;
112                         }
113                         count++;
114                         /*
115                          * Allow holes in unit numbering,
116                          * assumption is unit numbering starts
117                          * at zero.
118                          */
119                         if (dp->d_unit + 1 > hicount)
120                                 hicount = dp->d_unit + 1;
121                         if (search) {
122                                 mp = dp->d_conn;
123                                 if (mp != NULL && dp->d_connunit < 0)
124                                         mp = NULL;
125                                 if (mp != NULL && strcmp(mp, "nexus") == 0)
126                                         mp = NULL;
127                                 if (mp != NULL) {
128                                         do_count(mp, hname, 0);
129                                         search = 0;
130                                 }
131                         }
132                 }
133         }
134         do_header(dev, hname, count > hicount ? count : hicount);
135 }
136
137 static void
138 do_header(const char *dev, char *hname, int count)
139 {
140         char *file, *name, *inw;
141         struct file_list *fl, *fl_head, *tflp;
142         FILE *inf, *outf;
143         int inc, oldcount;
144
145         file = toheader(hname);
146         name = tomacro(dev);
147         inf = fopen(file, "r");
148         oldcount = -1;
149         if (inf == NULL) {
150                 outf = fopen(file, "w");
151                 if (outf == NULL)
152                         err(1, "%s", file);
153                 fprintf(outf, "#define %s %d\n", name, count);
154                 fclose(outf);
155                 return;
156         }
157         fl_head = NULL;
158         for (;;) {
159                 char *cp;
160                 if ((inw = get_word(inf)) == NULL || inw == (char *)EOF)
161                         break;
162                 if ((inw = get_word(inf)) == NULL || inw == (char *)EOF)
163                         break;
164                 inw = strdup(inw);
165                 cp = get_word(inf);
166                 if (cp == NULL || cp == (char *)EOF)
167                         break;
168                 inc = atoi(cp);
169                 if (strcmp(inw, name) == 0) {
170                         oldcount = inc;
171                         inc = count;
172                 }
173                 cp = get_word(inf);
174                 if (cp == (char *)EOF)
175                         break;
176                 fl = malloc(sizeof(*fl));
177                 bzero(fl, sizeof(*fl));
178                 fl->f_fn = inw;         /* malloced */
179                 fl->f_type = inc;
180                 fl->f_next = fl_head;
181                 fl_head = fl;
182         }
183         fclose(inf);
184         if (count == oldcount) {
185                 for (fl = fl_head; fl != NULL; fl = tflp) {
186                         tflp = fl->f_next;
187                         free(fl->f_fn);
188                         free(fl);
189                 }
190                 return;
191         }
192         if (oldcount == -1) {
193                 fl = malloc(sizeof(*fl));
194                 bzero(fl, sizeof(*fl));
195                 fl->f_fn = strdup(name);
196                 fl->f_type = count;
197                 fl->f_next = fl_head;
198                 fl_head = fl;
199         }
200         outf = fopen(file, "w");
201         if (outf == 0)
202                 err(1, "%s", file);
203         for (fl = fl_head; fl != NULL; fl = tflp) {
204                 fprintf(outf,
205                     "#define %s %u\n", fl->f_fn, count ? fl->f_type : 0);
206                 tflp = fl->f_next;
207                 free(fl->f_fn);
208                 free(fl);
209         }
210         fclose(outf);
211 }
212
213 /*
214  * convert a dev name to a .h file name
215  */
216 static char *
217 toheader(const char *dev)
218 {
219         static char hbuf[MAXPATHLEN];
220         static char udev[MAXPATHLEN];
221
222         snprintf(udev, sizeof(udev), "use_%s", dev);
223
224         snprintf(hbuf, sizeof(hbuf), "%s.h", path(udev));
225         return(hbuf);
226 }
227
228 /*
229  * convert a dev name to a macro name
230  */
231 static char *
232 tomacro(const char *dev)
233 {
234         static char mbuf[20];
235         char *cp;
236
237         cp = mbuf;
238         *cp++ = 'N';
239         while (*dev != 0)
240                 *cp++ = islower(*dev) ? toupper(*dev++) : *dev++;
241         *cp++ = 0;
242         return(mbuf);
243 }