xref: /openbsd-src/usr.sbin/config/mkheaders.c (revision 51429809a2bab2098b4aa115befeeee0344de53a)
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