mkoptions.c revision 29451
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[] =
4029451Scharnier	"$Id$";
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
5620458Sjoergstatic	char *lower __P((char *));
5729451Scharniervoid read_options __P((void));
5829451Scharniervoid do_option __P((char *));
5920458Sjoerg
6029451Scharniervoid
6112772Speteroptions()
6212772Speter{
6312772Speter	struct opt_list *ol;
6412772Speter
6512772Speter	/* fake the cpu types as options */
6612772Speter	/* Please forgive me for this hack.. :-) */
6712772Speter	struct cputype *cp;
6812772Speter
6912772Speter	for (cp = cputype; cp; cp = cp->cpu_next) {
7012772Speter		struct opt *op = (struct opt *)malloc(sizeof (struct opt));
7112772Speter		memset(op, 0, sizeof(*op));
7220458Sjoerg		op->op_name = ns(cp->cpu_name);
7312772Speter		op->op_value = 0;
7412772Speter		op->op_next = opt;
7512772Speter		opt = op;
7612772Speter	}
7712772Speter
7812772Speter	read_options();
7912772Speter	for (ol = otab; ol != 0; ol = ol->o_next)
8012772Speter		do_option(ol->o_name);
8112772Speter}
8212772Speter
8312772Speter/*
8412772Speter * Generate an <options>.h file
8512772Speter */
8612772Speter
8729451Scharniervoid
8812772Speterdo_option(name)
8912772Speter	char *name;
9012772Speter{
9112772Speter	char *file, *inw, *tooption();
9212772Speter	struct opt *op, *op_head, *topp;
9312772Speter	FILE *inf, *outf;
9412772Speter	char *value;
9512772Speter	char *oldvalue;
9612772Speter	int seen;
9712772Speter
9812772Speter	file = tooption(name);
9912772Speter
10012772Speter	/*
10112772Speter	 * Check to see if the option was specified..
10212772Speter	 */
10312772Speter	value = NULL;
10412772Speter	for (op = opt; op; op = op->op_next) {
10512772Speter		if (eq(name, op->op_name)) {
10612772Speter			value = op->op_value;
10712772Speter			if (!value)
10812772Speter				value = ns("1");
10912772Speter			op->op_ownfile++;
11012772Speter		}
11112772Speter	}
11212772Speter
11312772Speter	inf = fopen(file, "r");
11412772Speter	if (inf == 0) {
11512772Speter		outf = fopen(file, "w");
11629451Scharnier		if (outf == 0)
11729451Scharnier			err(1, "%s", file);
11812772Speter
11912772Speter		/* was the option in the config file? */
12012772Speter		if (value) {
12112772Speter			fprintf(outf, "#define %s %s\n", name, value);
12212772Speter		} /* else empty file */
12312772Speter
12412772Speter		(void) fclose(outf);
12512772Speter		return;
12612772Speter	}
12712772Speter	oldvalue = NULL;
12812772Speter	op_head = NULL;
12912772Speter	seen = 0;
13012772Speter	for (;;) {
13112772Speter		char *cp;
13212772Speter		char *invalue;
13312772Speter
13412772Speter		/* get the #define */
13512772Speter		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
13612772Speter			break;
13712772Speter		/* get the option name */
13812772Speter		if ((inw = get_word(inf)) == 0 || inw == (char *)EOF)
13912772Speter			break;
14012772Speter		inw = ns(inw);
14112772Speter		cp = get_word(inf);
14212772Speter		if (cp == 0 || cp == (char *)EOF)
14312772Speter			break;
14412772Speter		/* option value */
14512772Speter		invalue = ns(cp); /* malloced */
14612772Speter		if (eq(inw, name)) {
14712772Speter			oldvalue = invalue;
14812772Speter			invalue = value;
14912772Speter			seen++;
15012772Speter		}
15112772Speter		op = (struct opt *) malloc(sizeof *op);
15212772Speter		bzero(op, sizeof(*op));
15312772Speter		op->op_name = inw;
15412772Speter		op->op_value = invalue;
15512772Speter		op->op_next = op_head;
15612772Speter		op_head = op;
15712772Speter
15812772Speter		/* EOL? */
15912772Speter		cp = get_word(inf);
16012772Speter		if (cp == (char *)EOF)
16112772Speter			break;
16212772Speter	}
16312772Speter	(void) fclose(inf);
16412772Speter	if ((value == NULL && oldvalue == NULL) ||
16512772Speter	    (value && oldvalue && eq(value,oldvalue))) {
16612772Speter		for (op = op_head; op != NULL; op = topp) {
16712772Speter			topp = op->op_next;
16812772Speter			free(op->op_name);
16912772Speter			free(op->op_value);
17012772Speter			free(op);
17112772Speter		}
17212772Speter		return;
17312772Speter	}
17412772Speter
17512772Speter	if (value && !seen) {
17612772Speter		/* New option appears */
17712772Speter		op = (struct opt *) malloc(sizeof *op);
17812772Speter		bzero(op, sizeof(*op));
17912772Speter		op->op_name = ns(name);
18012772Speter		op->op_value = value ? ns(value) : NULL;
18112772Speter		op->op_next = op_head;
18212772Speter		op_head = op;
18312772Speter	}
18412772Speter
18512772Speter	outf = fopen(file, "w");
18629451Scharnier	if (outf == 0)
18729451Scharnier		err(1, "%s", file);
18812772Speter	for (op = op_head; op != NULL; op = topp) {
18912772Speter		/* was the option in the config file? */
19012772Speter		if (op->op_value) {
19112772Speter			fprintf(outf, "#define %s %s\n",
19212772Speter				op->op_name, op->op_value);
19312772Speter		}
19412772Speter		topp = op->op_next;
19512772Speter		free(op->op_name);
19612772Speter		free(op->op_value);
19712772Speter		free(op);
19812772Speter	}
19912772Speter	(void) fclose(outf);
20012772Speter}
20112772Speter
20212772Speter/*
20312772Speter * Find the filename to store the option spec into.
20412772Speter */
20512772Speterchar *
20612772Spetertooption(name)
20712772Speter	char *name;
20812772Speter{
20912772Speter	static char hbuf[80];
21012772Speter	char nbuf[80];
21112772Speter	struct opt_list *po;
21212772Speter
21312772Speter	/* "cannot happen"?  the otab list should be complete.. */
21412772Speter	(void) strcpy(nbuf, "options.h");
21512772Speter
21612772Speter	for (po = otab ; po != 0; po = po->o_next) {
21712772Speter		if (eq(po->o_name, name)) {
21812772Speter			strcpy(nbuf, po->o_file);
21912772Speter			break;
22012772Speter		}
22112772Speter	}
22212772Speter
22312772Speter	(void) strcpy(hbuf, path(nbuf));
22412772Speter	return (hbuf);
22512772Speter}
22612772Speter
22712772Speter/*
22812772Speter * read the options and options.<machine> files
22912772Speter */
23029451Scharniervoid
23112772Speterread_options()
23212772Speter{
23312772Speter	FILE *fp;
23420457Sjoerg	char fname[80];
23512772Speter	char *wd, *this, *val;
23612772Speter	struct opt_list *po;
23712772Speter	int first = 1;
23812772Speter	char genopt[80];
23912772Speter
24012772Speter	otab = 0;
24120457Sjoerg	(void) snprintf(fname, sizeof fname, "../../conf/options");
24212772Speteropenit:
24312772Speter	fp = fopen(fname, "r");
24412772Speter	if (fp == 0) {
24512772Speter		return;
24612772Speter	}
24712772Speter	if(ident == NULL) {
24812772Speter		printf("no ident line specified\n");
24912772Speter		exit(1);
25012772Speter	}
25112772Speternext:
25212772Speter	wd = get_word(fp);
25312772Speter	if (wd == (char *)EOF) {
25412772Speter		(void) fclose(fp);
25512772Speter		if (first == 1) {
25620457Sjoerg			(void) snprintf(fname, sizeof fname, "options.%s", machinename);
25712772Speter			first++;
25812772Speter			goto openit;
25912772Speter		}
26012772Speter		if (first == 2) {
26120457Sjoerg			(void) snprintf(fname, sizeof fname, "options.%s", raise(ident));
26212772Speter			first++;
26312772Speter			fp = fopen(fname, "r");
26412772Speter			if (fp != 0)
26512772Speter				goto next;
26612772Speter		}
26712772Speter		return;
26812772Speter	}
26912772Speter	if (wd == 0)
27012772Speter		goto next;
27112772Speter	/*************************************************\
27212772Speter	* If it's a comment ignore to the end of the line *
27312772Speter	\*************************************************/
27412772Speter	if(wd[0] == '#')
27512772Speter	{
27612772Speter		while( ((wd = get_word(fp)) != (char *)EOF) && wd)
27712772Speter		;
27812772Speter		goto next;
27912772Speter	}
28012772Speter	this = ns(wd);
28112772Speter	val = get_word(fp);
28212772Speter	if (val == (char *)EOF)
28312772Speter		return;
28412772Speter	if (val == 0) {
28512772Speter		char *s = ns(this);
28620457Sjoerg		(void) snprintf(genopt, sizeof genopt, "opt_%s.h", lower(s));
28712772Speter		val = genopt;
28812772Speter		free(s);
28912772Speter	}
29012772Speter	val = ns(val);
29112772Speter
29212772Speter	for (po = otab ; po != 0; po = po->o_next) {
29312772Speter		if (eq(po->o_name, this)) {
29412772Speter			printf("%s: Duplicate option %s.\n",
29512772Speter			       fname, this);
29612772Speter			exit(1);
29712772Speter		}
29812772Speter	}
29912772Speter
30012772Speter	po = (struct opt_list *) malloc(sizeof *po);
30112772Speter	bzero(po, sizeof(*po));
30212772Speter	po->o_name = this;
30312772Speter	po->o_file = val;
30412772Speter	po->o_next = otab;
30512772Speter	otab = po;
30612772Speter
30712772Speter	goto next;
30812772Speter}
30912772Speter
31020458Sjoergstatic char *
31112772Speterlower(str)
31212772Speter	register char *str;
31312772Speter{
31412772Speter	register char *cp = str;
31512772Speter
31612772Speter	while (*str) {
31712772Speter		if (isupper(*str))
31812772Speter			*str = tolower(*str);
31912772Speter		str++;
32012772Speter	}
32112772Speter	return (cp);
32212772Speter}
32312772Speter
324