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