mkoptions.c revision 37578
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: mkoptions.c,v 1.7 1998/07/12 02:31:08 bde Exp $"; 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 struct users { 57 int u_default; 58 int u_min; 59 int u_max; 60} users[] = { 61 { 8, 2, 512 }, /* MACHINE_VAX */ 62 { 8, 2, 512 }, /* MACHINE_TAHOE */ 63 { 8, 2, 512 }, /* MACHINE_HP300 */ 64 { 8, 2, 512 }, /* MACHINE_I386 */ 65 { 8, 2, 512 }, /* MACHINE_MIPS */ 66 { 8, 2, 512 }, /* MACHINE_PMAX */ 67 { 8, 2, 512 }, /* MACHINE_LUNA68K */ 68 { 8, 2, 512 }, /* MACHINE_NEWS3400 */ 69 { 8, 2, 512 }, /* MACHINE_PC98 */ 70 { 8, 2, 512 }, /* MACHINE_ALPHA */ 71}; 72#define NUSERS (sizeof (users) / sizeof (users[0])) 73 74static char *lower __P((char *)); 75void read_options __P((void)); 76void do_option __P((char *)); 77 78void 79options() 80{ 81 char buf[40]; 82 struct cputype *cp; 83 struct opt_list *ol; 84 struct opt *op; 85 struct users *up; 86 87 /* Fake the cpu types as options. */ 88 for (cp = cputype; cp != NULL; cp = cp->cpu_next) { 89 op = (struct opt *)malloc(sizeof(*op)); 90 memset(op, 0, sizeof(*op)); 91 op->op_name = ns(cp->cpu_name); 92 op->op_next = opt; 93 opt = op; 94 } 95 96 /* Initialize `maxusers'. */ 97 if ((unsigned)machine > NUSERS) { 98 printf("maxusers config info isn't present, using vax\n"); 99 up = &users[MACHINE_VAX - 1]; 100 } else 101 up = &users[machine - 1]; 102 if (maxusers == 0) { 103 printf("maxusers not specified; %d assumed\n", up->u_default); 104 maxusers = up->u_default; 105 } else if (maxusers < up->u_min) { 106 printf("minimum of %d maxusers assumed\n", up->u_min); 107 maxusers = up->u_min; 108 } else if (maxusers > up->u_max) 109 printf("warning: maxusers > %d (%d)\n", up->u_max, maxusers); 110 111 /* Fake MAXUSERS as an option. */ 112 op = (struct opt *)malloc(sizeof(*op)); 113 memset(op, 0, sizeof(*op)); 114 op->op_name = "MAXUSERS"; 115 sprintf(buf, "%d", maxusers); 116 op->op_value = ns(buf); 117 op->op_next = opt; 118 opt = op; 119 120 read_options(); 121 for (ol = otab; ol != 0; ol = ol->o_next) 122 do_option(ol->o_name); 123} 124 125/* 126 * Generate an <options>.h file 127 */ 128 129void 130do_option(name) 131 char *name; 132{ 133 char *file, *inw, *tooption(); 134 struct opt *op, *op_head, *topp; 135 FILE *inf, *outf; 136 char *value; 137 char *oldvalue; 138 int seen; 139 140 file = tooption(name); 141 142 /* 143 * Check to see if the option was specified.. 144 */ 145 value = NULL; 146 for (op = opt; op; op = op->op_next) { 147 if (eq(name, op->op_name)) { 148 oldvalue = value; 149 value = op->op_value; 150 if (value == NULL) 151 value = ns("1"); 152 if (oldvalue != NULL && !eq(value, oldvalue)) 153 printf( 154 "%s:%d: option \"%s\" redefined from %s to %s\n", 155 PREFIX, op->op_line, op->op_name, oldvalue, 156 value); 157 op->op_ownfile++; 158 } 159 } 160 161 inf = fopen(file, "r"); 162 if (inf == 0) { 163 outf = fopen(file, "w"); 164 if (outf == 0) 165 err(1, "%s", file); 166 167 /* was the option in the config file? */ 168 if (value) { 169 fprintf(outf, "#define %s %s\n", name, value); 170 } /* else empty file */ 171 172 (void) fclose(outf); 173 return; 174 } 175 oldvalue = NULL; 176 op_head = NULL; 177 seen = 0; 178 for (;;) { 179 char *cp; 180 char *invalue; 181 182 /* get the #define */ 183 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 184 break; 185 /* get the option name */ 186 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 187 break; 188 inw = ns(inw); 189 cp = get_word(inf); 190 if (cp == 0 || cp == (char *)EOF) 191 break; 192 /* option value */ 193 invalue = ns(cp); /* malloced */ 194 if (eq(inw, name)) { 195 oldvalue = invalue; 196 invalue = value; 197 seen++; 198 } 199 op = (struct opt *) malloc(sizeof *op); 200 bzero(op, sizeof(*op)); 201 op->op_name = inw; 202 op->op_value = invalue; 203 op->op_next = op_head; 204 op_head = op; 205 206 /* EOL? */ 207 cp = get_word(inf); 208 if (cp == (char *)EOF) 209 break; 210 } 211 (void) fclose(inf); 212 if ((value == NULL && oldvalue == NULL) || 213 (value && oldvalue && eq(value,oldvalue))) { 214 for (op = op_head; op != NULL; op = topp) { 215 topp = op->op_next; 216 free(op->op_name); 217 free(op->op_value); 218 free(op); 219 } 220 return; 221 } 222 223 if (value && !seen) { 224 /* New option appears */ 225 op = (struct opt *) malloc(sizeof *op); 226 bzero(op, sizeof(*op)); 227 op->op_name = ns(name); 228 op->op_value = value ? ns(value) : NULL; 229 op->op_next = op_head; 230 op_head = op; 231 } 232 233 outf = fopen(file, "w"); 234 if (outf == 0) 235 err(1, "%s", file); 236 for (op = op_head; op != NULL; op = topp) { 237 /* was the option in the config file? */ 238 if (op->op_value) { 239 fprintf(outf, "#define %s %s\n", 240 op->op_name, op->op_value); 241 } 242 topp = op->op_next; 243 free(op->op_name); 244 free(op->op_value); 245 free(op); 246 } 247 (void) fclose(outf); 248} 249 250/* 251 * Find the filename to store the option spec into. 252 */ 253char * 254tooption(name) 255 char *name; 256{ 257 static char hbuf[80]; 258 char nbuf[80]; 259 struct opt_list *po; 260 261 /* "cannot happen"? the otab list should be complete.. */ 262 (void) strcpy(nbuf, "options.h"); 263 264 for (po = otab ; po != 0; po = po->o_next) { 265 if (eq(po->o_name, name)) { 266 strcpy(nbuf, po->o_file); 267 break; 268 } 269 } 270 271 (void) strcpy(hbuf, path(nbuf)); 272 return (hbuf); 273} 274 275/* 276 * read the options and options.<machine> files 277 */ 278void 279read_options() 280{ 281 FILE *fp; 282 char fname[80]; 283 char *wd, *this, *val; 284 struct opt_list *po; 285 int first = 1; 286 char genopt[80]; 287 288 otab = 0; 289 (void) snprintf(fname, sizeof fname, "../../conf/options"); 290openit: 291 fp = fopen(fname, "r"); 292 if (fp == 0) { 293 return; 294 } 295 if(ident == NULL) { 296 printf("no ident line specified\n"); 297 exit(1); 298 } 299next: 300 wd = get_word(fp); 301 if (wd == (char *)EOF) { 302 (void) fclose(fp); 303 if (first == 1) { 304 (void) snprintf(fname, sizeof fname, "options.%s", machinename); 305 first++; 306 goto openit; 307 } 308 if (first == 2) { 309 (void) snprintf(fname, sizeof fname, "options.%s", raise(ident)); 310 first++; 311 fp = fopen(fname, "r"); 312 if (fp != 0) 313 goto next; 314 } 315 return; 316 } 317 if (wd == 0) 318 goto next; 319 /*************************************************\ 320 * If it's a comment ignore to the end of the line * 321 \*************************************************/ 322 if(wd[0] == '#') 323 { 324 while( ((wd = get_word(fp)) != (char *)EOF) && wd) 325 ; 326 goto next; 327 } 328 this = ns(wd); 329 val = get_word(fp); 330 if (val == (char *)EOF) 331 return; 332 if (val == 0) { 333 char *s = ns(this); 334 (void) snprintf(genopt, sizeof genopt, "opt_%s.h", lower(s)); 335 val = genopt; 336 free(s); 337 } 338 val = ns(val); 339 340 for (po = otab ; po != 0; po = po->o_next) { 341 if (eq(po->o_name, this)) { 342 printf("%s: Duplicate option %s.\n", 343 fname, this); 344 exit(1); 345 } 346 } 347 348 po = (struct opt_list *) malloc(sizeof *po); 349 bzero(po, sizeof(*po)); 350 po->o_name = this; 351 po->o_file = val; 352 po->o_next = otab; 353 otab = po; 354 355 goto next; 356} 357 358static char * 359lower(str) 360 register char *str; 361{ 362 register char *cp = str; 363 364 while (*str) { 365 if (isupper(*str)) 366 *str = tolower(*str); 367 str++; 368 } 369 return (cp); 370} 371 372