mkoptions.c revision 29451
1/* 2 * Copyright (c) 1995 Peter Wemm 3 * Copyright (c) 1980, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by the University of 17 * California, Berkeley and its contributors. 18 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35#ifndef lint 36#if 0 37static char sccsid[] = "@(#)mkheaders.c 8.1 (Berkeley) 6/6/93"; 38#endif 39static const char rcsid[] = 40 "$Id$"; 41#endif /* not lint */ 42 43/* 44 * Make all the .h files for the optional entries 45 */ 46 47#include <ctype.h> 48#include <err.h> 49#include <stdio.h> 50#include <string.h> 51#include "config.h" 52#include "y.tab.h" 53 54#define ns(s) strdup(s) 55 56static char *lower __P((char *)); 57void read_options __P((void)); 58void do_option __P((char *)); 59 60void 61options() 62{ 63 struct opt_list *ol; 64 65 /* fake the cpu types as options */ 66 /* Please forgive me for this hack.. :-) */ 67 struct cputype *cp; 68 69 for (cp = cputype; cp; cp = cp->cpu_next) { 70 struct opt *op = (struct opt *)malloc(sizeof (struct opt)); 71 memset(op, 0, sizeof(*op)); 72 op->op_name = ns(cp->cpu_name); 73 op->op_value = 0; 74 op->op_next = opt; 75 opt = op; 76 } 77 78 read_options(); 79 for (ol = otab; ol != 0; ol = ol->o_next) 80 do_option(ol->o_name); 81} 82 83/* 84 * Generate an <options>.h file 85 */ 86 87void 88do_option(name) 89 char *name; 90{ 91 char *file, *inw, *tooption(); 92 struct opt *op, *op_head, *topp; 93 FILE *inf, *outf; 94 char *value; 95 char *oldvalue; 96 int seen; 97 98 file = tooption(name); 99 100 /* 101 * Check to see if the option was specified.. 102 */ 103 value = NULL; 104 for (op = opt; op; op = op->op_next) { 105 if (eq(name, op->op_name)) { 106 value = op->op_value; 107 if (!value) 108 value = ns("1"); 109 op->op_ownfile++; 110 } 111 } 112 113 inf = fopen(file, "r"); 114 if (inf == 0) { 115 outf = fopen(file, "w"); 116 if (outf == 0) 117 err(1, "%s", file); 118 119 /* was the option in the config file? */ 120 if (value) { 121 fprintf(outf, "#define %s %s\n", name, value); 122 } /* else empty file */ 123 124 (void) fclose(outf); 125 return; 126 } 127 oldvalue = NULL; 128 op_head = NULL; 129 seen = 0; 130 for (;;) { 131 char *cp; 132 char *invalue; 133 134 /* get the #define */ 135 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 136 break; 137 /* get the option name */ 138 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 139 break; 140 inw = ns(inw); 141 cp = get_word(inf); 142 if (cp == 0 || cp == (char *)EOF) 143 break; 144 /* option value */ 145 invalue = ns(cp); /* malloced */ 146 if (eq(inw, name)) { 147 oldvalue = invalue; 148 invalue = value; 149 seen++; 150 } 151 op = (struct opt *) malloc(sizeof *op); 152 bzero(op, sizeof(*op)); 153 op->op_name = inw; 154 op->op_value = invalue; 155 op->op_next = op_head; 156 op_head = op; 157 158 /* EOL? */ 159 cp = get_word(inf); 160 if (cp == (char *)EOF) 161 break; 162 } 163 (void) fclose(inf); 164 if ((value == NULL && oldvalue == NULL) || 165 (value && oldvalue && eq(value,oldvalue))) { 166 for (op = op_head; op != NULL; op = topp) { 167 topp = op->op_next; 168 free(op->op_name); 169 free(op->op_value); 170 free(op); 171 } 172 return; 173 } 174 175 if (value && !seen) { 176 /* New option appears */ 177 op = (struct opt *) malloc(sizeof *op); 178 bzero(op, sizeof(*op)); 179 op->op_name = ns(name); 180 op->op_value = value ? ns(value) : NULL; 181 op->op_next = op_head; 182 op_head = op; 183 } 184 185 outf = fopen(file, "w"); 186 if (outf == 0) 187 err(1, "%s", file); 188 for (op = op_head; op != NULL; op = topp) { 189 /* was the option in the config file? */ 190 if (op->op_value) { 191 fprintf(outf, "#define %s %s\n", 192 op->op_name, op->op_value); 193 } 194 topp = op->op_next; 195 free(op->op_name); 196 free(op->op_value); 197 free(op); 198 } 199 (void) fclose(outf); 200} 201 202/* 203 * Find the filename to store the option spec into. 204 */ 205char * 206tooption(name) 207 char *name; 208{ 209 static char hbuf[80]; 210 char nbuf[80]; 211 struct opt_list *po; 212 213 /* "cannot happen"? the otab list should be complete.. */ 214 (void) strcpy(nbuf, "options.h"); 215 216 for (po = otab ; po != 0; po = po->o_next) { 217 if (eq(po->o_name, name)) { 218 strcpy(nbuf, po->o_file); 219 break; 220 } 221 } 222 223 (void) strcpy(hbuf, path(nbuf)); 224 return (hbuf); 225} 226 227/* 228 * read the options and options.<machine> files 229 */ 230void 231read_options() 232{ 233 FILE *fp; 234 char fname[80]; 235 char *wd, *this, *val; 236 struct opt_list *po; 237 int first = 1; 238 char genopt[80]; 239 240 otab = 0; 241 (void) snprintf(fname, sizeof fname, "../../conf/options"); 242openit: 243 fp = fopen(fname, "r"); 244 if (fp == 0) { 245 return; 246 } 247 if(ident == NULL) { 248 printf("no ident line specified\n"); 249 exit(1); 250 } 251next: 252 wd = get_word(fp); 253 if (wd == (char *)EOF) { 254 (void) fclose(fp); 255 if (first == 1) { 256 (void) snprintf(fname, sizeof fname, "options.%s", machinename); 257 first++; 258 goto openit; 259 } 260 if (first == 2) { 261 (void) snprintf(fname, sizeof fname, "options.%s", raise(ident)); 262 first++; 263 fp = fopen(fname, "r"); 264 if (fp != 0) 265 goto next; 266 } 267 return; 268 } 269 if (wd == 0) 270 goto next; 271 /*************************************************\ 272 * If it's a comment ignore to the end of the line * 273 \*************************************************/ 274 if(wd[0] == '#') 275 { 276 while( ((wd = get_word(fp)) != (char *)EOF) && wd) 277 ; 278 goto next; 279 } 280 this = ns(wd); 281 val = get_word(fp); 282 if (val == (char *)EOF) 283 return; 284 if (val == 0) { 285 char *s = ns(this); 286 (void) snprintf(genopt, sizeof genopt, "opt_%s.h", lower(s)); 287 val = genopt; 288 free(s); 289 } 290 val = ns(val); 291 292 for (po = otab ; po != 0; po = po->o_next) { 293 if (eq(po->o_name, this)) { 294 printf("%s: Duplicate option %s.\n", 295 fname, this); 296 exit(1); 297 } 298 } 299 300 po = (struct opt_list *) malloc(sizeof *po); 301 bzero(po, sizeof(*po)); 302 po->o_name = this; 303 po->o_file = val; 304 po->o_next = otab; 305 otab = po; 306 307 goto next; 308} 309 310static char * 311lower(str) 312 register char *str; 313{ 314 register char *cp = str; 315 316 while (*str) { 317 if (isupper(*str)) 318 *str = tolower(*str); 319 str++; 320 } 321 return (cp); 322} 323 324