1*51429809Stb /* $OpenBSD: mkheaders.c,v 1.22 2016/10/16 17:50:00 tb Exp $ */
2125b588dSderaadt /* $NetBSD: mkheaders.c,v 1.12 1997/02/02 21:12:34 thorpej Exp $ */
3608f9123Sniklas
4df930be7Sderaadt /*
5df930be7Sderaadt * Copyright (c) 1992, 1993
6df930be7Sderaadt * The Regents of the University of California. All rights reserved.
7df930be7Sderaadt *
8df930be7Sderaadt * This software was developed by the Computer Systems Engineering group
9df930be7Sderaadt * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10df930be7Sderaadt * contributed to Berkeley.
11df930be7Sderaadt *
12df930be7Sderaadt * All advertising materials mentioning features or use of this software
13df930be7Sderaadt * must display the following acknowledgement:
14df930be7Sderaadt * This product includes software developed by the University of
15df930be7Sderaadt * California, Lawrence Berkeley Laboratories.
16df930be7Sderaadt *
17df930be7Sderaadt * Redistribution and use in source and binary forms, with or without
18df930be7Sderaadt * modification, are permitted provided that the following conditions
19df930be7Sderaadt * are met:
20df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright
21df930be7Sderaadt * notice, this list of conditions and the following disclaimer.
22df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright
23df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the
24df930be7Sderaadt * documentation and/or other materials provided with the distribution.
2529295d1cSmillert * 3. Neither the name of the University nor the names of its contributors
26df930be7Sderaadt * may be used to endorse or promote products derived from this software
27df930be7Sderaadt * without specific prior written permission.
28df930be7Sderaadt *
29df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39df930be7Sderaadt * SUCH DAMAGE.
40df930be7Sderaadt *
41df930be7Sderaadt * from: @(#)mkheaders.c 8.1 (Berkeley) 6/6/93
42df930be7Sderaadt */
43df930be7Sderaadt
44df930be7Sderaadt #include <ctype.h>
45*51429809Stb #include <err.h>
46df930be7Sderaadt #include <errno.h>
47df930be7Sderaadt #include <stdio.h>
48df930be7Sderaadt #include <stdlib.h>
49df930be7Sderaadt #include <string.h>
50c6b62359Sedd
51df930be7Sderaadt #include "config.h"
52df930be7Sderaadt
53c72b5b24Smillert static int emitcnt(struct nvlist *);
54c72b5b24Smillert static int emitopt(struct nvlist *);
55*51429809Stb static int emitwarn(const char *, char *, FILE *);
56c72b5b24Smillert static char *cntname(const char *);
57df930be7Sderaadt
58df930be7Sderaadt /*
59df930be7Sderaadt * Make headers containing counts, as needed.
60df930be7Sderaadt */
61df930be7Sderaadt int
mkheaders(void)62815b5809Sderaadt mkheaders(void)
63df930be7Sderaadt {
640ac0d02eSmpech struct files *fi;
650ac0d02eSmpech struct nvlist *nv;
66df930be7Sderaadt
67df930be7Sderaadt for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
68df930be7Sderaadt if (fi->fi_flags & FI_HIDDEN)
69df930be7Sderaadt continue;
70df930be7Sderaadt if (fi->fi_flags & (FI_NEEDSCOUNT | FI_NEEDSFLAG) &&
71f3bae140Sderaadt emitcnt(fi->fi_optf))
72df930be7Sderaadt return (1);
73df930be7Sderaadt }
74efe9777cSdownsj
75efe9777cSdownsj for (nv = defoptions; nv != NULL; nv = nv->nv_next)
76efe9777cSdownsj if (emitopt(nv))
77efe9777cSdownsj return (1);
78efe9777cSdownsj
79df930be7Sderaadt return (0);
80df930be7Sderaadt }
81df930be7Sderaadt
82df930be7Sderaadt static int
emitcnt(struct nvlist * head)83815b5809Sderaadt emitcnt(struct nvlist *head)
84df930be7Sderaadt {
850ac0d02eSmpech struct nvlist *nv;
860ac0d02eSmpech FILE *fp;
87df930be7Sderaadt int cnt;
88df930be7Sderaadt char nam[100];
89df930be7Sderaadt char buf[BUFSIZ];
906fd5fbd6Sniklas char fname[BUFSIZ];
91df930be7Sderaadt
928c069c75Sderaadt (void)snprintf(fname, sizeof fname, "%s.h", head->nv_name);
93df930be7Sderaadt if ((fp = fopen(fname, "r")) == NULL)
94df930be7Sderaadt goto writeit;
95df930be7Sderaadt nv = head;
96df930be7Sderaadt while (fgets(buf, sizeof(buf), fp) != NULL) {
97df930be7Sderaadt if (nv == NULL)
98df930be7Sderaadt goto writeit;
99d2c3e300Sderaadt if (sscanf(buf, "#define %99s %d", nam, &cnt) != 2 ||
100df930be7Sderaadt strcmp(nam, cntname(nv->nv_name)) != 0 ||
101df930be7Sderaadt cnt != nv->nv_int)
102df930be7Sderaadt goto writeit;
103df930be7Sderaadt nv = nv->nv_next;
104df930be7Sderaadt }
105df930be7Sderaadt if (ferror(fp))
106*51429809Stb return (emitwarn("read", fname, fp));
107df930be7Sderaadt (void)fclose(fp);
108df930be7Sderaadt if (nv == NULL)
109df930be7Sderaadt return (0);
110df930be7Sderaadt writeit:
111*51429809Stb if ((fp = fopen(fname, "w")) == NULL)
112*51429809Stb return (emitwarn("writ", fname, NULL));
113df930be7Sderaadt for (nv = head; nv != NULL; nv = nv->nv_next)
114df930be7Sderaadt if (fprintf(fp, "#define\t%s\t%d\n",
115df930be7Sderaadt cntname(nv->nv_name), nv->nv_int) < 0)
116*51429809Stb return (emitwarn("writ", fname, fp));
117df930be7Sderaadt if (fclose(fp))
118*51429809Stb return (emitwarn("writ", fname, NULL));
119df930be7Sderaadt return (0);
120df930be7Sderaadt }
121df930be7Sderaadt
122df930be7Sderaadt static int
emitopt(struct nvlist * nv)123815b5809Sderaadt emitopt(struct nvlist *nv)
124efe9777cSdownsj {
125efe9777cSdownsj struct nvlist *option;
126efe9777cSdownsj char new_contents[BUFSIZ], buf[BUFSIZ];
12752e5342eSdrahn char fname[BUFSIZ];
12852e5342eSdrahn int totlen, nlines;
129efe9777cSdownsj FILE *fp;
130efe9777cSdownsj
131efe9777cSdownsj /*
132efe9777cSdownsj * Generate the new contents of the file.
133efe9777cSdownsj */
134efe9777cSdownsj if ((option = ht_lookup(opttab, nv->nv_str)) == NULL)
1350a264ab6Sderaadt totlen = snprintf(new_contents, sizeof new_contents,
1360a264ab6Sderaadt "/* option `%s' not defined */\n",
137efe9777cSdownsj nv->nv_str);
138efe9777cSdownsj else {
139efe9777cSdownsj if (option->nv_str != NULL)
1400a264ab6Sderaadt totlen = snprintf(new_contents, sizeof new_contents,
1410a264ab6Sderaadt "#define\t%s\t%s\n",
1420a264ab6Sderaadt option->nv_name, option->nv_str);
1430a264ab6Sderaadt else
1440a264ab6Sderaadt totlen = snprintf(new_contents, sizeof new_contents,
1450a264ab6Sderaadt "#define\t%s\n",
1460a264ab6Sderaadt option->nv_name);
1470a264ab6Sderaadt }
1480a264ab6Sderaadt
149f898e79cSderaadt if (totlen < 0 || totlen >= sizeof new_contents) {
150*51429809Stb warnx("string too long");
1510a264ab6Sderaadt return (1);
152efe9777cSdownsj }
153efe9777cSdownsj
154efe9777cSdownsj /*
155efe9777cSdownsj * Compare the new file to the old.
156efe9777cSdownsj */
1578c069c75Sderaadt snprintf(fname, sizeof fname, "opt_%s.h", nv->nv_name);
158efe9777cSdownsj if ((fp = fopen(fname, "r")) == NULL)
159efe9777cSdownsj goto writeit;
160efe9777cSdownsj nlines = 0;
161efe9777cSdownsj while (fgets(buf, sizeof(buf), fp) != NULL) {
162efe9777cSdownsj if (++nlines != 1 ||
163efe9777cSdownsj strcmp(buf, new_contents) != 0)
164efe9777cSdownsj goto writeit;
165efe9777cSdownsj }
166efe9777cSdownsj if (ferror(fp))
167*51429809Stb return (emitwarn("read", fname, fp));
168efe9777cSdownsj (void)fclose(fp);
169efe9777cSdownsj if (nlines == 1)
170efe9777cSdownsj return (0);
171efe9777cSdownsj writeit:
172efe9777cSdownsj /*
173efe9777cSdownsj * They're different, or the file doesn't exist.
174efe9777cSdownsj */
175*51429809Stb if ((fp = fopen(fname, "w")) == NULL)
176*51429809Stb return (emitwarn("writ", fname, NULL));
177efe9777cSdownsj if (fprintf(fp, "%s", new_contents) < 0)
178*51429809Stb return (emitwarn("writ", fname, fp));
179efe9777cSdownsj if (fclose(fp))
180*51429809Stb return (emitwarn("writ", fname, fp));
181efe9777cSdownsj return (0);
182efe9777cSdownsj }
183efe9777cSdownsj
184efe9777cSdownsj static int
emitwarn(const char * what,char * fname,FILE * fp)185*51429809Stb emitwarn(const char *what, char *fname, FILE *fp)
186df930be7Sderaadt {
187df930be7Sderaadt
188*51429809Stb warn("error %sing %s", what, fname);
189df930be7Sderaadt if (fp)
190df930be7Sderaadt (void)fclose(fp);
191df930be7Sderaadt return (1);
192df930be7Sderaadt }
193df930be7Sderaadt
194df930be7Sderaadt static char *
cntname(const char * src)195815b5809Sderaadt cntname(const char *src)
196df930be7Sderaadt {
1970ac0d02eSmpech char *dst, c;
198df930be7Sderaadt static char buf[100];
199df930be7Sderaadt
200df930be7Sderaadt dst = buf;
201df930be7Sderaadt *dst++ = 'N';
202df930be7Sderaadt while ((c = *src++) != 0)
2030a0228f8Sderaadt *dst++ = islower((unsigned char)c) ?
2040a0228f8Sderaadt toupper((unsigned char)c) : c;
205df930be7Sderaadt *dst = 0;
206df930be7Sderaadt return (buf);
207df930be7Sderaadt }
208