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