mkoptions.c revision 20458
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 36static char sccsid[] = "@(#)mkheaders.c 8.1 (Berkeley) 6/6/93"; 37#endif /* not lint */ 38 39/* 40 * Make all the .h files for the optional entries 41 */ 42 43#include <stdio.h> 44#include <string.h> 45#include <ctype.h> 46#include "config.h" 47#include "y.tab.h" 48 49#define ns(s) strdup(s) 50 51static char *lower __P((char *)); 52 53options() 54{ 55 struct opt_list *ol; 56 57 /* fake the cpu types as options */ 58 /* Please forgive me for this hack.. :-) */ 59 struct opt *op; 60 struct cputype *cp; 61 62 for (cp = cputype; cp; cp = cp->cpu_next) { 63 struct opt *op = (struct opt *)malloc(sizeof (struct opt)); 64 memset(op, 0, sizeof(*op)); 65 op->op_name = ns(cp->cpu_name); 66 op->op_value = 0; 67 op->op_next = opt; 68 opt = op; 69 } 70 71 read_options(); 72 for (ol = otab; ol != 0; ol = ol->o_next) 73 do_option(ol->o_name); 74} 75 76/* 77 * Generate an <options>.h file 78 */ 79 80do_option(name) 81 char *name; 82{ 83 char *file, *inw, *tooption(); 84 struct opt *op, *op_head, *topp; 85 FILE *inf, *outf; 86 char *value; 87 char *oldvalue; 88 int seen; 89 90 file = tooption(name); 91 92 /* 93 * Check to see if the option was specified.. 94 */ 95 value = NULL; 96 for (op = opt; op; op = op->op_next) { 97 if (eq(name, op->op_name)) { 98 value = op->op_value; 99 if (!value) 100 value = ns("1"); 101 op->op_ownfile++; 102 } 103 } 104 105 inf = fopen(file, "r"); 106 if (inf == 0) { 107 outf = fopen(file, "w"); 108 if (outf == 0) { 109 perror(file); 110 exit(1); 111 } 112 113 /* was the option in the config file? */ 114 if (value) { 115 fprintf(outf, "#define %s %s\n", name, value); 116 } /* else empty file */ 117 118 (void) fclose(outf); 119 return; 120 } 121 oldvalue = NULL; 122 op_head = NULL; 123 seen = 0; 124 for (;;) { 125 char *cp; 126 char *invalue; 127 128 /* get the #define */ 129 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 130 break; 131 /* get the option name */ 132 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 133 break; 134 inw = ns(inw); 135 cp = get_word(inf); 136 if (cp == 0 || cp == (char *)EOF) 137 break; 138 /* option value */ 139 invalue = ns(cp); /* malloced */ 140 if (eq(inw, name)) { 141 oldvalue = invalue; 142 invalue = value; 143 seen++; 144 } 145 op = (struct opt *) malloc(sizeof *op); 146 bzero(op, sizeof(*op)); 147 op->op_name = inw; 148 op->op_value = invalue; 149 op->op_next = op_head; 150 op_head = op; 151 152 /* EOL? */ 153 cp = get_word(inf); 154 if (cp == (char *)EOF) 155 break; 156 } 157 (void) fclose(inf); 158 if ((value == NULL && oldvalue == NULL) || 159 (value && oldvalue && eq(value,oldvalue))) { 160 for (op = op_head; op != NULL; op = topp) { 161 topp = op->op_next; 162 free(op->op_name); 163 free(op->op_value); 164 free(op); 165 } 166 return; 167 } 168 169 if (value && !seen) { 170 /* New option appears */ 171 op = (struct opt *) malloc(sizeof *op); 172 bzero(op, sizeof(*op)); 173 op->op_name = ns(name); 174 op->op_value = value ? ns(value) : NULL; 175 op->op_next = op_head; 176 op_head = op; 177 } 178 179 outf = fopen(file, "w"); 180 if (outf == 0) { 181 perror(file); 182 exit(1); 183 } 184 for (op = op_head; op != NULL; op = topp) { 185 /* was the option in the config file? */ 186 if (op->op_value) { 187 fprintf(outf, "#define %s %s\n", 188 op->op_name, op->op_value); 189 } 190 topp = op->op_next; 191 free(op->op_name); 192 free(op->op_value); 193 free(op); 194 } 195 (void) fclose(outf); 196} 197 198/* 199 * Find the filename to store the option spec into. 200 */ 201char * 202tooption(name) 203 char *name; 204{ 205 static char hbuf[80]; 206 char nbuf[80]; 207 struct opt_list *po; 208 209 /* "cannot happen"? the otab list should be complete.. */ 210 (void) strcpy(nbuf, "options.h"); 211 212 for (po = otab ; po != 0; po = po->o_next) { 213 if (eq(po->o_name, name)) { 214 strcpy(nbuf, po->o_file); 215 break; 216 } 217 } 218 219 (void) strcpy(hbuf, path(nbuf)); 220 return (hbuf); 221} 222 223/* 224 * read the options and options.<machine> files 225 */ 226read_options() 227{ 228 FILE *fp; 229 char fname[80]; 230 char *wd, *this, *val; 231 struct opt_list *po; 232 int first = 1; 233 char genopt[80]; 234 235 otab = 0; 236 (void) snprintf(fname, sizeof fname, "../../conf/options"); 237openit: 238 fp = fopen(fname, "r"); 239 if (fp == 0) { 240 return; 241 } 242 if(ident == NULL) { 243 printf("no ident line specified\n"); 244 exit(1); 245 } 246next: 247 wd = get_word(fp); 248 if (wd == (char *)EOF) { 249 (void) fclose(fp); 250 if (first == 1) { 251 (void) snprintf(fname, sizeof fname, "options.%s", machinename); 252 first++; 253 goto openit; 254 } 255 if (first == 2) { 256 (void) snprintf(fname, sizeof fname, "options.%s", raise(ident)); 257 first++; 258 fp = fopen(fname, "r"); 259 if (fp != 0) 260 goto next; 261 } 262 return; 263 } 264 if (wd == 0) 265 goto next; 266 /*************************************************\ 267 * If it's a comment ignore to the end of the line * 268 \*************************************************/ 269 if(wd[0] == '#') 270 { 271 while( ((wd = get_word(fp)) != (char *)EOF) && wd) 272 ; 273 goto next; 274 } 275 this = ns(wd); 276 val = get_word(fp); 277 if (val == (char *)EOF) 278 return; 279 if (val == 0) { 280 char *s = ns(this); 281 (void) snprintf(genopt, sizeof genopt, "opt_%s.h", lower(s)); 282 val = genopt; 283 free(s); 284 } 285 val = ns(val); 286 287 for (po = otab ; po != 0; po = po->o_next) { 288 if (eq(po->o_name, this)) { 289 printf("%s: Duplicate option %s.\n", 290 fname, this); 291 exit(1); 292 } 293 } 294 295 po = (struct opt_list *) malloc(sizeof *po); 296 bzero(po, sizeof(*po)); 297 po->o_name = this; 298 po->o_file = val; 299 po->o_next = otab; 300 otab = po; 301 302 goto next; 303} 304 305static char * 306lower(str) 307 register char *str; 308{ 309 register char *cp = str; 310 311 while (*str) { 312 if (isupper(*str)) 313 *str = tolower(*str); 314 str++; 315 } 316 return (cp); 317} 318 319