mkoptions.c revision 37578
112772Speter/*
212772Speter * Copyright (c) 1995  Peter Wemm
312772Speter * Copyright (c) 1980, 1993
412772Speter *	The Regents of the University of California.  All rights reserved.
512772Speter *
612772Speter * Redistribution and use in source and binary forms, with or without
712772Speter * modification, are permitted provided that the following conditions
812772Speter * are met:
912772Speter * 1. Redistributions of source code must retain the above copyright
1012772Speter *    notice, this list of conditions and the following disclaimer.
1112772Speter * 2. Redistributions in binary form must reproduce the above copyright
1212772Speter *    notice, this list of conditions and the following disclaimer in the
1312772Speter *    documentation and/or other materials provided with the distribution.
1412772Speter * 3. All advertising materials mentioning features or use of this software
1512772Speter *    must display the following acknowledgement:
1612772Speter *	This product includes software developed by the University of
1712772Speter *	California, Berkeley and its contributors.
1812772Speter * 4. Neither the name of the University nor the names of its contributors
1912772Speter *    may be used to endorse or promote products derived from this software
2012772Speter *    without specific prior written permission.
2112772Speter *
2212772Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2312772Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2412772Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2512772Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2612772Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2712772Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2812772Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2912772Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3012772Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3112772Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3212772Speter * SUCH DAMAGE.
3312772Speter */
3412772Speter
3512772Speter#ifndef lint
3629451Scharnier#if 0
3712772Speterstatic char sccsid[] = "@(#)mkheaders.c	8.1 (Berkeley) 6/6/93";
3829451Scharnier#endif
3929451Scharnierstatic const char rcsid[] =
4037578Sbde	"$Id: mkoptions.c,v 1.7 1998/07/12 02:31:08 bde Exp $";
4112772Speter#endif /* not lint */
4212772Speter
4312772Speter/*
4412772Speter * Make all the .h files for the optional entries
4512772Speter */
4612772Speter
4729451Scharnier#include <ctype.h>
4829451Scharnier#include <err.h>
4912772Speter#include <stdio.h>
5020458Sjoerg#include <string.h>
5112772Speter#include "config.h"
5216073Sphk#include "y.tab.h"
5312772Speter
5420458Sjoerg#define ns(s) strdup(s)
5520458Sjoerg
5637578Sbdestatic	struct users {
5737578Sbde	int	u_default;
5837578Sbde	int	u_min;
5937578Sbde	int	u_max;
6037578Sbde} users[] = {
6137578Sbde	{ 8, 2, 512 },			/* MACHINE_VAX */
6237578Sbde	{ 8, 2, 512 },			/* MACHINE_TAHOE */
6337578Sbde	{ 8, 2, 512 },			/* MACHINE_HP300 */
6437578Sbde	{ 8, 2, 512 },			/* MACHINE_I386 */
6537578Sbde	{ 8, 2, 512 },			/* MACHINE_MIPS */
6637578Sbde	{ 8, 2, 512 },			/* MACHINE_PMAX */
6737578Sbde	{ 8, 2, 512 },			/* MACHINE_LUNA68K */
6837578Sbde	{ 8, 2, 512 },			/* MACHINE_NEWS3400 */
6937578Sbde	{ 8, 2, 512 },			/* MACHINE_PC98 */
7037578Sbde	{ 8, 2, 512 },			/* MACHINE_ALPHA */
7137578Sbde};
7237578Sbde#define	NUSERS	(sizeof (users) / sizeof (users[0]))
7337578Sbde
7420458Sjoergstatic	char *lower __P((char *));
7529451Scharniervoid read_options __P((void));
7629451Scharniervoid do_option __P((char *));
7720458Sjoerg
7829451Scharniervoid
7912772Speteroptions()
8012772Speter{
8137578Sbde	char buf[40];
8237578Sbde	struct cputype *cp;
8312772Speter	struct opt_list *ol;
8437578Sbde	struct opt *op;
8537578Sbde	struct users *up;
8612772Speter
8737578Sbde	/* Fake the cpu types as options. */
8837578Sbde	for (cp = cputype; cp != NULL; cp = cp->cpu_next) {
8937578Sbde		op = (struct opt *)malloc(sizeof(*op));
9012772Speter		memset(op, 0, sizeof(*op));
9120458Sjoerg		op->op_name = ns(cp->cpu_name);
9212772Speter		op->op_next = opt;
9312772Speter		opt = op;
9412772Speter	}
9512772Speter
9637578Sbde	/* Initialize `maxusers'. */
9737578Sbde	if ((unsigned)machine > NUSERS) {
9837578Sbde		printf("maxusers config info isn't present, using vax\n");
9937578Sbde		up = &users[MACHINE_VAX - 1];
10037578Sbde	} else
10137578Sbde		up = &users[machine - 1];
10237578Sbde	if (maxusers == 0) {
10337578Sbde		printf("maxusers not specified; %d assumed\n", up->u_default);
10437578Sbde		maxusers = up->u_default;
10537578Sbde	} else if (maxusers < up->u_min) {
10637578Sbde		printf("minimum of %d maxusers assumed\n", up->u_min);
10737578Sbde		maxusers = up->u_min;
10837578Sbde	} else if (maxusers > up->u_max)
10937578Sbde		printf("warning: maxusers > %d (%d)\n", up->u_max, maxusers);
11037578Sbde
11137578Sbde	/* Fake MAXUSERS as an option. */
11237578Sbde	op = (struct opt *)malloc(sizeof(*op));
11337578Sbde	memset(op, 0, sizeof(*op));
11437578Sbde	op->op_name = "MAXUSERS";
11537578Sbde	sprintf(buf, "%d", maxusers);
11637578Sbde	op->op_value = ns(buf);
11737578Sbde	op->op_next = opt;
11837578Sbde	opt = op;
11937578Sbde
12012772Speter	read_options();
12112772Speter	for (ol = otab; ol != 0; ol = ol->o_next)
12212772Speter		do_option(ol->o_name);
12312772Speter}
12412772Speter
12512772Speter/*
12612772Speter * Generate an <options>.h file
12712772Speter */
12812772Speter
12929451Scharniervoid
13012772Speterdo_option(name)
13112772Speter	char *name;
13212772Speter{
13312772Speter	char *file, *inw, *tooption();
13412772Speter	struct opt *op, *op_head, *topp;
13512772Speter	FILE *inf, *outf;
13612772Speter	char *value;
13712772Speter	char *oldvalue;
13812772Speter	int seen;
13912772Speter
14012772Speter	file = tooption(name);
14112772Speter
14212772Speter	/*
14312772Speter	 * Check to see if the option was specified..
14412772Speter	 */
14512772Speter	value = NULL;
14612772Speter	for (op = opt; op; op = op->op_next) {
14712772Speter		if (eq(name, op->op_name)) {
14837577Sbde			oldvalue = value;
14912772Speter			value = op->op_value;
15037577Sbde			if (value == NULL)
15112772Speter				value = ns("1");
15237577Sbde			if (oldvalue != NULL && !eq(value, oldvalue))
15337577Sbde				printf(
15437577Sbde			    "%s:%d: option \"%s\" redefined from %s to %s\n",
15537577Sbde				   PREFIX, op->op_line, op->op_name, oldvalue,
15637577Sbde				   value);
15712772Speter			op->op_ownfile++;
15812772Speter		}
15912772Speter	}
16012772Speter
16112772Speter	inf = fopen(file, "r");
16212772Speter	if (inf == 0) {
16312772Speter		outf = fopen(file, "w");
16429451Scharnier		if (outf == 0)
16529451Scharnier			err(1, "%s", file);
16612772Speter
16712772Speter		/* was the option in the config file? */
16812772Speter		if (value) {
16912772Speter			fprintf(outf, "#define %s %s\n", name, value);
17012772Speter		} /* else empty file */
17112772Speter
17212772Speter		(void) fclose(outf);
17312772Speter		return;
17412772Speter	}
17512772Speter	oldvalue = NULL;
17612772Speter	op_head = NULL;
17712772Speter	seen = 0;
17812772Speter	for (;;) {
17912772Speter		char *cp;
18012772Speter		char *invalue;
18112772Speter
18212772Speter		/* get the #define */
18312772Speter		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
18412772Speter			break;
18512772Speter		/* get the option name */
18612772Speter		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
18712772Speter			break;
18812772Speter		inw = ns(inw);
18912772Speter		cp = get_word(inf);
19012772Speter		if (cp == 0 || cp == (char *)EOF)
19112772Speter			break;
19212772Speter		/* option value */
19312772Speter		invalue = ns(cp); /* malloced */
19412772Speter		if (eq(inw, name)) {
19512772Speter			oldvalue = invalue;
19612772Speter			invalue = value;
19712772Speter			seen++;
19812772Speter		}
19912772Speter		op = (struct opt *) malloc(sizeof *op);
20012772Speter		bzero(op, sizeof(*op));
20112772Speter		op->op_name = inw;
20212772Speter		op->op_value = invalue;
20312772Speter		op->op_next = op_head;
20412772Speter		op_head = op;
20512772Speter
20612772Speter		/* EOL? */
20712772Speter		cp = get_word(inf);
20812772Speter		if (cp == (char *)EOF)
20912772Speter			break;
21012772Speter	}
21112772Speter	(void) fclose(inf);
21212772Speter	if ((value == NULL && oldvalue == NULL) ||
21312772Speter	    (value && oldvalue && eq(value,oldvalue))) {
21412772Speter		for (op = op_head; op != NULL; op = topp) {
21512772Speter			topp = op->op_next;
21612772Speter			free(op->op_name);
21712772Speter			free(op->op_value);
21812772Speter			free(op);
21912772Speter		}
22012772Speter		return;
22112772Speter	}
22212772Speter
22312772Speter	if (value && !seen) {
22412772Speter		/* New option appears */
22512772Speter		op = (struct opt *) malloc(sizeof *op);
22612772Speter		bzero(op, sizeof(*op));
22712772Speter		op->op_name = ns(name);
22812772Speter		op->op_value = value ? ns(value) : NULL;
22912772Speter		op->op_next = op_head;
23012772Speter		op_head = op;
23112772Speter	}
23212772Speter
23312772Speter	outf = fopen(file, "w");
23429451Scharnier	if (outf == 0)
23529451Scharnier		err(1, "%s", file);
23612772Speter	for (op = op_head; op != NULL; op = topp) {
23712772Speter		/* was the option in the config file? */
23812772Speter		if (op->op_value) {
23912772Speter			fprintf(outf, "#define %s %s\n",
24012772Speter				op->op_name, op->op_value);
24112772Speter		}
24212772Speter		topp = op->op_next;
24312772Speter		free(op->op_name);
24412772Speter		free(op->op_value);
24512772Speter		free(op);
24612772Speter	}
24712772Speter	(void) fclose(outf);
24812772Speter}
24912772Speter
25012772Speter/*
25112772Speter * Find the filename to store the option spec into.
25212772Speter */
25312772Speterchar *
25412772Spetertooption(name)
25512772Speter	char *name;
25612772Speter{
25712772Speter	static char hbuf[80];
25812772Speter	char nbuf[80];
25912772Speter	struct opt_list *po;
26012772Speter
26112772Speter	/* "cannot happen"?  the otab list should be complete.. */
26212772Speter	(void) strcpy(nbuf, "options.h");
26312772Speter
26412772Speter	for (po = otab ; po != 0; po = po->o_next) {
26512772Speter		if (eq(po->o_name, name)) {
26612772Speter			strcpy(nbuf, po->o_file);
26712772Speter			break;
26812772Speter		}
26912772Speter	}
27012772Speter
27112772Speter	(void) strcpy(hbuf, path(nbuf));
27212772Speter	return (hbuf);
27312772Speter}
27412772Speter
27512772Speter/*
27612772Speter * read the options and options.<machine> files
27712772Speter */
27829451Scharniervoid
27912772Speterread_options()
28012772Speter{
28112772Speter	FILE *fp;
28220457Sjoerg	char fname[80];
28312772Speter	char *wd, *this, *val;
28412772Speter	struct opt_list *po;
28512772Speter	int first = 1;
28612772Speter	char genopt[80];
28712772Speter
28812772Speter	otab = 0;
28920457Sjoerg	(void) snprintf(fname, sizeof fname, "../../conf/options");
29012772Speteropenit:
29112772Speter	fp = fopen(fname, "r");
29212772Speter	if (fp == 0) {
29312772Speter		return;
29412772Speter	}
29512772Speter	if(ident == NULL) {
29612772Speter		printf("no ident line specified\n");
29712772Speter		exit(1);
29812772Speter	}
29912772Speternext:
30012772Speter	wd = get_word(fp);
30112772Speter	if (wd == (char *)EOF) {
30212772Speter		(void) fclose(fp);
30312772Speter		if (first == 1) {
30420457Sjoerg			(void) snprintf(fname, sizeof fname, "options.%s", machinename);
30512772Speter			first++;
30612772Speter			goto openit;
30712772Speter		}
30812772Speter		if (first == 2) {
30920457Sjoerg			(void) snprintf(fname, sizeof fname, "options.%s", raise(ident));
31012772Speter			first++;
31112772Speter			fp = fopen(fname, "r");
31212772Speter			if (fp != 0)
31312772Speter				goto next;
31412772Speter		}
31512772Speter		return;
31612772Speter	}
31712772Speter	if (wd == 0)
31812772Speter		goto next;
31912772Speter	/*************************************************\
32012772Speter	* If it's a comment ignore to the end of the line *
32112772Speter	\*************************************************/
32212772Speter	if(wd[0] == '#')
32312772Speter	{
32412772Speter		while( ((wd = get_word(fp)) != (char *)EOF) && wd)
32512772Speter		;
32612772Speter		goto next;
32712772Speter	}
32812772Speter	this = ns(wd);
32912772Speter	val = get_word(fp);
33012772Speter	if (val == (char *)EOF)
33112772Speter		return;
33212772Speter	if (val == 0) {
33312772Speter		char *s = ns(this);
33420457Sjoerg		(void) snprintf(genopt, sizeof genopt, "opt_%s.h", lower(s));
33512772Speter		val = genopt;
33612772Speter		free(s);
33712772Speter	}
33812772Speter	val = ns(val);
33912772Speter
34012772Speter	for (po = otab ; po != 0; po = po->o_next) {
34112772Speter		if (eq(po->o_name, this)) {
34212772Speter			printf("%s: Duplicate option %s.\n",
34312772Speter			       fname, this);
34412772Speter			exit(1);
34512772Speter		}
34612772Speter	}
34712772Speter
34812772Speter	po = (struct opt_list *) malloc(sizeof *po);
34912772Speter	bzero(po, sizeof(*po));
35012772Speter	po->o_name = this;
35112772Speter	po->o_file = val;
35212772Speter	po->o_next = otab;
35312772Speter	otab = po;
35412772Speter
35512772Speter	goto next;
35612772Speter}
35712772Speter
35820458Sjoergstatic char *
35912772Speterlower(str)
36012772Speter	register char *str;
36112772Speter{
36212772Speter	register char *cp = str;
36312772Speter
36412772Speter	while (*str) {
36512772Speter		if (isupper(*str))
36612772Speter			*str = tolower(*str);
36712772Speter		str++;
36812772Speter	}
36912772Speter	return (cp);
37012772Speter}
37112772Speter
372