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