mkmakefile.c revision 61640
11553Srgrimes/*
21553Srgrimes * Copyright (c) 1993, 19801990
31553Srgrimes *	The Regents of the University of California.  All rights reserved.
41553Srgrimes *
51553Srgrimes * Redistribution and use in source and binary forms, with or without
61553Srgrimes * modification, are permitted provided that the following conditions
71553Srgrimes * are met:
81553Srgrimes * 1. Redistributions of source code must retain the above copyright
91553Srgrimes *    notice, this list of conditions and the following disclaimer.
101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111553Srgrimes *    notice, this list of conditions and the following disclaimer in the
121553Srgrimes *    documentation and/or other materials provided with the distribution.
131553Srgrimes * 3. All advertising materials mentioning features or use of this software
141553Srgrimes *    must display the following acknowledgement:
151553Srgrimes *	This product includes software developed by the University of
161553Srgrimes *	California, Berkeley and its contributors.
171553Srgrimes * 4. Neither the name of the University nor the names of its contributors
181553Srgrimes *    may be used to endorse or promote products derived from this software
191553Srgrimes *    without specific prior written permission.
201553Srgrimes *
211553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241553Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311553Srgrimes * SUCH DAMAGE.
321553Srgrimes */
331553Srgrimes
341553Srgrimes#ifndef lint
3529451Scharnier#if 0
361553Srgrimesstatic char sccsid[] = "@(#)mkmakefile.c	8.1 (Berkeley) 6/6/93";
3729451Scharnier#endif
3829451Scharnierstatic const char rcsid[] =
3950479Speter  "$FreeBSD: head/usr.sbin/config/mkmakefile.c 61640 2000-06-13 22:28:50Z peter $";
401553Srgrimes#endif /* not lint */
411553Srgrimes
421553Srgrimes/*
431553Srgrimes * Build the makefile for the system, from
441553Srgrimes * the information in the files files and the
451553Srgrimes * additional files for the machine being compiled to.
461553Srgrimes */
471553Srgrimes
4829451Scharnier#include <ctype.h>
4929451Scharnier#include <err.h>
501553Srgrimes#include <stdio.h>
5120458Sjoerg#include <string.h>
5216073Sphk#include "y.tab.h"
531553Srgrimes#include "config.h"
5430638Speter#include "configvers.h"
551553Srgrimes
561553Srgrimes#define next_word(fp, wd) \
5761640Speter	{ char *word = get_word(fp); \
581553Srgrimes	  if (word == (char *)EOF) \
591553Srgrimes		return; \
601553Srgrimes	  else \
611553Srgrimes		wd = word; \
621553Srgrimes	}
631553Srgrimes#define next_quoted_word(fp, wd) \
6461640Speter	{ char *word = get_quoted_word(fp); \
651553Srgrimes	  if (word == (char *)EOF) \
661553Srgrimes		return; \
671553Srgrimes	  else \
681553Srgrimes		wd = word; \
691553Srgrimes	}
701553Srgrimes
7145744Speterstatic struct file_list *fcur;
721553Srgrimes
7361640Speterstatic char *tail(char *);
7461640Speterstatic void do_clean(FILE *);
7561640Speterstatic void do_rules(FILE *);
7661640Speterstatic void do_sfiles(FILE *);
7761640Speterstatic void do_mfiles(FILE *);
7861640Speterstatic void do_cfiles(FILE *);
7961640Speterstatic void do_objs(FILE *);
8061640Speterstatic void do_before_depend(FILE *);
8161640Speterstatic int opteq(char *, char *);
8261640Speterstatic void read_files(void);
8329451Scharnier
841553Srgrimes/*
851553Srgrimes * Lookup a file, by name.
861553Srgrimes */
8745744Speterstatic struct file_list *
8861640Speterfl_lookup(char *file)
891553Srgrimes{
9061640Speter	struct file_list *fp;
911553Srgrimes
921553Srgrimes	for (fp = ftab ; fp != 0; fp = fp->f_next) {
931553Srgrimes		if (eq(fp->f_fn, file))
941553Srgrimes			return (fp);
951553Srgrimes	}
961553Srgrimes	return (0);
971553Srgrimes}
981553Srgrimes
991553Srgrimes/*
1001553Srgrimes * Lookup a file, by final component name.
1011553Srgrimes */
10245744Speterstatic struct file_list *
10361640Speterfltail_lookup(char *file)
1041553Srgrimes{
10561640Speter	struct file_list *fp;
1061553Srgrimes
1071553Srgrimes	for (fp = ftab ; fp != 0; fp = fp->f_next) {
1081553Srgrimes		if (eq(tail(fp->f_fn), tail(file)))
1091553Srgrimes			return (fp);
1101553Srgrimes	}
1111553Srgrimes	return (0);
1121553Srgrimes}
1131553Srgrimes
1141553Srgrimes/*
1151553Srgrimes * Make a new file list entry
1161553Srgrimes */
11745744Speterstatic struct file_list *
11861640Speternew_fent(void)
1191553Srgrimes{
12061640Speter	struct file_list *fp;
1211553Srgrimes
1221553Srgrimes	fp = (struct file_list *) malloc(sizeof *fp);
1231553Srgrimes	bzero(fp, sizeof *fp);
1241553Srgrimes	if (fcur == 0)
1251553Srgrimes		fcur = ftab = fp;
1261553Srgrimes	else
1271553Srgrimes		fcur->f_next = fp;
1281553Srgrimes	fcur = fp;
1291553Srgrimes	return (fp);
1301553Srgrimes}
1311553Srgrimes
1321553Srgrimes/*
1331553Srgrimes * Build the makefile from the skeleton
1341553Srgrimes */
13529451Scharniervoid
13661640Spetermakefile(void)
1371553Srgrimes{
1381553Srgrimes	FILE *ifp, *ofp;
1391553Srgrimes	char line[BUFSIZ];
1401553Srgrimes	struct opt *op;
14130638Speter	int versreq;
14261640Speter	char *s;
1431553Srgrimes
1441553Srgrimes	read_files();
14555614Speter	snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename);
1461553Srgrimes	ifp = fopen(line, "r");
14755614Speter	if (ifp == 0) {
14855614Speter		snprintf(line, sizeof(line), "Makefile.%s", machinename);
14955614Speter		ifp = fopen(line, "r");
15055614Speter	}
15129451Scharnier	if (ifp == 0)
15229451Scharnier		err(1, "%s", line);
15313400Speter	ofp = fopen(path("Makefile.new"), "w");
15429451Scharnier	if (ofp == 0)
15529451Scharnier		err(1, "%s", path("Makefile.new"));
15645744Speter	fprintf(ofp, "KERN_IDENT=%s\n", raisestr(ident));
15711711Sdg	fprintf(ofp, "IDENT=");
15820395Sbde	if (profiling)
1591553Srgrimes		fprintf(ofp, " -DGPROF");
16012772Speter
1611553Srgrimes	if (cputype == 0) {
1621553Srgrimes		printf("cpu type must be specified\n");
1631553Srgrimes		exit(1);
1641553Srgrimes	}
1651553Srgrimes	fprintf(ofp, "\n");
1661553Srgrimes	for (op = mkopt; op; op = op->op_next)
1671553Srgrimes		fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
1681553Srgrimes	if (debugging)
1691553Srgrimes		fprintf(ofp, "DEBUG=-g\n");
17020395Sbde	if (profiling) {
1711553Srgrimes		fprintf(ofp, "PROF=-pg\n");
17220395Sbde		fprintf(ofp, "PROFLEVEL=%d\n", profiling);
17320395Sbde	}
17452653Smarcel	if (*srcdir != '\0')
17552653Smarcel		fprintf(ofp,"S=%s\n", srcdir);
1761553Srgrimes	while (fgets(line, BUFSIZ, ifp) != 0) {
1771553Srgrimes		if (*line != '%') {
1781553Srgrimes			fprintf(ofp, "%s", line);
1791553Srgrimes			continue;
1801553Srgrimes		}
1815325Sgibbs		if (eq(line, "%BEFORE_DEPEND\n"))
1825325Sgibbs			do_before_depend(ofp);
1835325Sgibbs		else if (eq(line, "%OBJS\n"))
1841553Srgrimes			do_objs(ofp);
18538782Snsouch		else if (eq(line, "%MFILES\n"))
18638782Snsouch			do_mfiles(ofp);
1871553Srgrimes		else if (eq(line, "%CFILES\n"))
1881553Srgrimes			do_cfiles(ofp);
18911917Sdg		else if (eq(line, "%SFILES\n"))
19011917Sdg			do_sfiles(ofp);
1911553Srgrimes		else if (eq(line, "%RULES\n"))
1921553Srgrimes			do_rules(ofp);
1936803Sgibbs		else if (eq(line, "%CLEAN\n"))
1946803Sgibbs			do_clean(ofp);
19530638Speter		else if (strncmp(line, "%VERSREQ=", sizeof("%VERSREQ=") - 1) == 0) {
19630638Speter			versreq = atoi(line + sizeof("%VERSREQ=") - 1);
19730638Speter			if (versreq != CONFIGVERS) {
19830638Speter				fprintf(stderr, "WARNING: version of config(8) does not match kernel!\n");
19930638Speter				fprintf(stderr, "config version = %d, ", CONFIGVERS);
20037129Sjkh				fprintf(stderr, "version required = %d\n\n", versreq);
20137129Sjkh				fprintf(stderr, "Make sure that /usr/src/usr.sbin/config is in sync\n");
20237129Sjkh				fprintf(stderr, "with your /usr/src/sys and install a new config binary\n");
20337129Sjkh				fprintf(stderr, "before trying this again.\n\n");
20439307Sgibbs				fprintf(stderr, "If running the new config fails check your config\n");
20539307Sgibbs				fprintf(stderr, "file against the GENERIC or LINT config files for\n");
20639307Sgibbs				fprintf(stderr, "changes in config syntax, or option/device naming\n");
20739307Sgibbs				fprintf(stderr, "conventions\n\n");
20830638Speter			}
20930638Speter		} else
2101553Srgrimes			fprintf(stderr,
2111553Srgrimes			    "Unknown %% construct in generic makefile: %s",
2121553Srgrimes			    line);
2131553Srgrimes	}
2141553Srgrimes	(void) fclose(ifp);
2151553Srgrimes	(void) fclose(ofp);
21613400Speter	moveifchanged(path("Makefile.new"), path("Makefile"));
21734619Seivind
21861640Speter	if (hints) {
21961640Speter		ifp = fopen(hints, "r");
22061640Speter		if (ifp == NULL)
22161640Speter			err(1, "%s", hints);
22261640Speter	} else {
22361640Speter		ifp = NULL;
22461640Speter	}
22561640Speter	ofp = fopen(path("hints.c.new"), "w");
22661640Speter	if (ofp == NULL)
22761640Speter		err(1, "%s", path("hints.c.new"));
22861640Speter	fprintf(ofp, "char static_hints[] = {\n");
22961640Speter	if (ifp) {
23061640Speter		while (fgets(line, BUFSIZ, ifp) != 0) {
23161640Speter			/* zap trailing CR and/or LF */
23261640Speter			while ((s = rindex(line, '\n')) != NULL)
23361640Speter				*s = '\0';
23461640Speter			while ((s = rindex(line, '\r')) != NULL)
23561640Speter				*s = '\0';
23661640Speter			/* remove # comments */
23761640Speter			s = index(line, '#');
23861640Speter			if (s)
23961640Speter				*s = '\0';
24061640Speter			/* remove any whitespace and " characters */
24161640Speter			s = line;
24261640Speter			while (*s) {
24361640Speter				if (*s == ' ' || *s == '\t' || *s == '"') {
24461640Speter					while (*s) {
24561640Speter						s[0] = s[1];
24661640Speter						s++;
24761640Speter					}
24861640Speter					/* start over */
24961640Speter					s = line;
25061640Speter					continue;
25161640Speter				}
25261640Speter				s++;
25361640Speter			}
25461640Speter			/* anything left? */
25561640Speter			if (*line == '\0')
25661640Speter				break;
25761640Speter			fprintf(ofp, "\"%s\\0\"\n", line);
25861640Speter		}
25961640Speter	}
26061640Speter	fprintf(ofp, "\"\\0\"\n};\n");
26161640Speter	if (ifp)
26261640Speter		fclose(ifp);
26361640Speter	fclose(ofp);
26461640Speter	moveifchanged(path("hints.c.new"), path("hints.c"));
26561640Speter
26661523Speter	printf("Don't forget to do a ``make depend''\n");
2671553Srgrimes}
2681553Srgrimes
2691553Srgrimes/*
2701553Srgrimes * Read in the information about files used in making the system.
2711553Srgrimes * Store it in the ftab linked list.
2721553Srgrimes */
27345744Speterstatic void
27461640Speterread_files(void)
2751553Srgrimes{
2761553Srgrimes	FILE *fp;
27761640Speter	struct file_list *tp, *pf;
27861640Speter	struct device *dp;
2791553Srgrimes	struct device *save_dp;
28061640Speter	struct opt *op;
28154490Speter	char *wd, *this, *needs, *special, *depends, *clean, *warn;
28220457Sjoerg	char fname[80];
28348525Speter	int ddwarned = 0;
2848857Srgrimes	int nreqs, first = 1, configdep, isdup, std, filetype,
28561523Speter	    imp_rule, no_obj, needcount, before_depend, mandatory;
2861553Srgrimes
2871553Srgrimes	ftab = 0;
28845775Speter	save_dp = NULL;
28955614Speter	if (ident == NULL) {
29055614Speter		printf("no ident line specified\n");
29155614Speter		exit(1);
29255614Speter	}
29320457Sjoerg	(void) snprintf(fname, sizeof fname, "../../conf/files");
2941553Srgrimesopenit:
2951553Srgrimes	fp = fopen(fname, "r");
29629451Scharnier	if (fp == 0)
29729451Scharnier		err(1, "%s", fname);
2981553Srgrimesnext:
2991553Srgrimes	/*
30061640Speter	 * filename    [ standard | mandatory | optional | count ]
30161523Speter	 *	[ config-dependent ]
30248525Speter	 *	[ dev* | profiling-routine ] [ no-obj ]
3038857Srgrimes	 *	[ compile-with "compile rule" [no-implicit-rule] ]
3046803Sgibbs	 *      [ dependency "dependency-list"] [ before-depend ]
30554490Speter	 *	[ clean "file-list"] [ warning "text warning" ]
3061553Srgrimes	 */
3071553Srgrimes	wd = get_word(fp);
3081553Srgrimes	if (wd == (char *)EOF) {
3091553Srgrimes		(void) fclose(fp);
3101553Srgrimes		if (first == 1) {
31155614Speter			first++;
31255614Speter			(void) snprintf(fname, sizeof fname, "../../conf/files.%s", machinename);
31355614Speter			fp = fopen(fname, "r");
31455614Speter			if (fp != 0)
31555614Speter				goto next;
31620457Sjoerg			(void) snprintf(fname, sizeof fname, "files.%s", machinename);
3171553Srgrimes			goto openit;
3181553Srgrimes		}
3191553Srgrimes		if (first == 2) {
32055614Speter			first++;
32145744Speter			(void) snprintf(fname, sizeof fname, "files.%s", raisestr(ident));
3221553Srgrimes			fp = fopen(fname, "r");
3231553Srgrimes			if (fp != 0)
3241553Srgrimes				goto next;
3251553Srgrimes		}
3261553Srgrimes		return;
3271553Srgrimes	}
3281553Srgrimes	if (wd == 0)
3291553Srgrimes		goto next;
33052098Speter	if (wd[0] == '#')
3311566Srgrimes	{
33252098Speter		while (((wd = get_word(fp)) != (char *)EOF) && wd)
33352098Speter			;
3341566Srgrimes		goto next;
3351566Srgrimes	}
3361553Srgrimes	this = ns(wd);
3371553Srgrimes	next_word(fp, wd);
3381553Srgrimes	if (wd == 0) {
3391553Srgrimes		printf("%s: No type for %s.\n",
3401553Srgrimes		    fname, this);
3411553Srgrimes		exit(1);
3421553Srgrimes	}
3431553Srgrimes	if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags))
34461523Speter		isdup = ISDUP;
3451553Srgrimes	else
3461553Srgrimes		isdup = 0;
3471553Srgrimes	tp = 0;
34854047Sarchie	if (first == 3 && pf == 0 && (tp = fltail_lookup(this)) != 0) {
34954047Sarchie		if (tp->f_type != INVISIBLE || tp->f_flags)
35054047Sarchie			printf("%s: Local file %s overrides %s.\n",
35154047Sarchie			    fname, this, tp->f_fn);
35254047Sarchie		else
35354047Sarchie			printf("%s: Local file %s could override %s"
35454047Sarchie			    " with a different kernel configuration.\n",
35554047Sarchie			    fname, this, tp->f_fn);
35654047Sarchie	}
3571553Srgrimes	nreqs = 0;
3581553Srgrimes	special = 0;
3594571Sgibbs	depends = 0;
3606803Sgibbs	clean = 0;
36154490Speter	warn = 0;
3621553Srgrimes	configdep = 0;
3631553Srgrimes	needs = 0;
36430796Sjoerg	std = mandatory = 0;
3654571Sgibbs	imp_rule = 0;
3664571Sgibbs	no_obj = 0;
36761523Speter	needcount = 0;
3685325Sgibbs	before_depend = 0;
3691553Srgrimes	filetype = NORMAL;
37061523Speter	if (eq(wd, "standard")) {
3711553Srgrimes		std = 1;
37230796Sjoerg	/*
37330796Sjoerg	 * If an entry is marked "mandatory", config will abort if it's
37430796Sjoerg	 * not called by a configuration line in the config file.  Apart
37530796Sjoerg	 * from this, the device is handled like one marked "optional".
37630796Sjoerg	 */
37761523Speter	} else if (eq(wd, "mandatory")) {
37830796Sjoerg		mandatory = 1;
37961523Speter		needcount = 1;
38061523Speter	} else if (eq(wd, "count")) {
38161523Speter		needcount = 1;
38261523Speter	} else if (!eq(wd, "optional")) {
38361523Speter		printf("%s: %s must be count, optional, mandatory or standard\n",
38430796Sjoerg		       fname, this);
3851553Srgrimes		exit(1);
3861553Srgrimes	}
3871553Srgrimesnextparam:
3881553Srgrimes	next_word(fp, wd);
3891553Srgrimes	if (wd == 0)
3901553Srgrimes		goto doneparam;
3911553Srgrimes	if (eq(wd, "config-dependent")) {
3921553Srgrimes		configdep++;
3931553Srgrimes		goto nextparam;
3941553Srgrimes	}
3954571Sgibbs	if (eq(wd, "no-obj")) {
3964571Sgibbs		no_obj++;
3974571Sgibbs		goto nextparam;
3984571Sgibbs	}
3994571Sgibbs	if (eq(wd, "no-implicit-rule")) {
4004571Sgibbs		if (special == 0) {
4014571Sgibbs			printf("%s: alternate rule required when "
4024571Sgibbs			       "\"no-implicit-rule\" is specified.\n",
4034571Sgibbs			       fname);
4044571Sgibbs		}
4054571Sgibbs		imp_rule++;
4064571Sgibbs		goto nextparam;
4074571Sgibbs	}
4085325Sgibbs	if (eq(wd, "before-depend")) {
4095325Sgibbs		before_depend++;
4105325Sgibbs		goto nextparam;
4115325Sgibbs	}
4126803Sgibbs	if (eq(wd, "dependency")) {
4134571Sgibbs		next_quoted_word(fp, wd);
4144571Sgibbs		if (wd == 0) {
4154571Sgibbs			printf("%s: %s missing compile command string.\n",
4168520Srgrimes			       fname, this);
4174571Sgibbs			exit(1);
4184571Sgibbs		}
4194571Sgibbs		depends = ns(wd);
4204571Sgibbs		goto nextparam;
4214571Sgibbs	}
4226803Sgibbs	if (eq(wd, "clean")) {
4235325Sgibbs		next_quoted_word(fp, wd);
4245325Sgibbs		if (wd == 0) {
4256803Sgibbs			printf("%s: %s missing clean file list.\n",
4268520Srgrimes			       fname, this);
4275325Sgibbs			exit(1);
4285325Sgibbs		}
4296803Sgibbs		clean = ns(wd);
4305325Sgibbs		goto nextparam;
4315325Sgibbs	}
4321553Srgrimes	if (eq(wd, "compile-with")) {
4331553Srgrimes		next_quoted_word(fp, wd);
4341553Srgrimes		if (wd == 0) {
4351553Srgrimes			printf("%s: %s missing compile command string.\n",
4368520Srgrimes			       fname, this);
4371553Srgrimes			exit(1);
4381553Srgrimes		}
4391553Srgrimes		special = ns(wd);
4401553Srgrimes		goto nextparam;
4411553Srgrimes	}
44254490Speter	if (eq(wd, "warning")) {
44354490Speter		next_quoted_word(fp, wd);
44454490Speter		if (wd == 0) {
44554490Speter			printf("%s: %s missing warning text string.\n",
44654490Speter				fname, this);
44754490Speter			exit(1);
44854490Speter		}
44954490Speter		warn = ns(wd);
45054490Speter		goto nextparam;
45154490Speter	}
4521553Srgrimes	nreqs++;
45338782Snsouch	if (eq(wd, "local")) {
45438782Snsouch		filetype = LOCAL;
45538782Snsouch		goto nextparam;
45638782Snsouch	}
45738782Snsouch	if (eq(wd, "no-depend")) {
45838782Snsouch		filetype = NODEPEND;
45938782Snsouch		goto nextparam;
46038782Snsouch	}
4611553Srgrimes	if (eq(wd, "device-driver")) {
46248525Speter		if (!ddwarned) {
46348525Speter			printf("%s: `device-driver' flag ignored.\n", fname);
46448525Speter			ddwarned++;
46548525Speter		}
4661553Srgrimes		goto nextparam;
4671553Srgrimes	}
4681553Srgrimes	if (eq(wd, "profiling-routine")) {
4691553Srgrimes		filetype = PROFILING;
4701553Srgrimes		goto nextparam;
4711553Srgrimes	}
4721553Srgrimes	if (needs == 0 && nreqs == 1)
4731553Srgrimes		needs = ns(wd);
4741553Srgrimes	if (isdup)
4751553Srgrimes		goto invis;
4761553Srgrimes	for (dp = dtab; dp != 0; save_dp = dp, dp = dp->d_next)
4771553Srgrimes		if (eq(dp->d_name, wd)) {
47861640Speter			if (std && dp->d_type == DEVICE &&
47952098Speter			    dp->d_count <= 0)
48052098Speter				dp->d_count = 1;
4811553Srgrimes			goto nextparam;
4821553Srgrimes		}
48330796Sjoerg	if (mandatory) {
48430796Sjoerg		printf("%s: mandatory device \"%s\" not found\n",
48530796Sjoerg		       fname, wd);
48630796Sjoerg		exit(1);
48730796Sjoerg	}
4881553Srgrimes	if (std) {
4891553Srgrimes		dp = (struct device *) malloc(sizeof *dp);
49012772Speter		bzero(dp, sizeof *dp);
49161640Speter		dp->d_type = DEVICE;
4921553Srgrimes		dp->d_name = ns(wd);
49352098Speter		dp->d_count = 1;
4941553Srgrimes		save_dp->d_next = dp;
4951553Srgrimes		goto nextparam;
4961553Srgrimes	}
4971553Srgrimes	for (op = opt; op != 0; op = op->op_next)
4981553Srgrimes		if (op->op_value == 0 && opteq(op->op_name, wd)) {
4991553Srgrimes			if (nreqs == 1) {
5001553Srgrimes				free(needs);
5011553Srgrimes				needs = 0;
5021553Srgrimes			}
5031553Srgrimes			goto nextparam;
5041553Srgrimes		}
5051553Srgrimesinvis:
5061553Srgrimes	while ((wd = get_word(fp)) != 0)
5071553Srgrimes		;
5081553Srgrimes	if (tp == 0)
5091553Srgrimes		tp = new_fent();
5101553Srgrimes	tp->f_fn = this;
5111553Srgrimes	tp->f_type = INVISIBLE;
5121553Srgrimes	tp->f_needs = needs;
51361523Speter	tp->f_flags |= isdup;
51461523Speter	if (needcount)
51561523Speter		tp->f_flags |= NEED_COUNT;
5161553Srgrimes	tp->f_special = special;
5174571Sgibbs	tp->f_depends = depends;
5186803Sgibbs	tp->f_clean = clean;
51954490Speter	tp->f_warn = warn;
5201553Srgrimes	goto next;
5211553Srgrimes
5221553Srgrimesdoneparam:
5231553Srgrimes	if (std == 0 && nreqs == 0) {
5241553Srgrimes		printf("%s: what is %s optional on?\n",
5251553Srgrimes		    fname, this);
5261553Srgrimes		exit(1);
5271553Srgrimes	}
5281553Srgrimes
5291553Srgrimes	if (wd) {
5301553Srgrimes		printf("%s: syntax error describing %s\n",
5311553Srgrimes		    fname, this);
5321553Srgrimes		exit(1);
5331553Srgrimes	}
5341553Srgrimes	if (filetype == PROFILING && profiling == 0)
5351553Srgrimes		goto next;
5361553Srgrimes	if (tp == 0)
5371553Srgrimes		tp = new_fent();
5381553Srgrimes	tp->f_fn = this;
5391553Srgrimes	tp->f_type = filetype;
54061523Speter	tp->f_flags &= ~ISDUP;
5411553Srgrimes	if (configdep)
5421553Srgrimes		tp->f_flags |= CONFIGDEP;
5434571Sgibbs	if (imp_rule)
5444571Sgibbs		tp->f_flags |= NO_IMPLCT_RULE;
5454571Sgibbs	if (no_obj)
5464571Sgibbs		tp->f_flags |= NO_OBJ;
5475325Sgibbs	if (before_depend)
5485325Sgibbs		tp->f_flags |= BEFORE_DEPEND;
5495325Sgibbs	if (imp_rule)
5505325Sgibbs		tp->f_flags |= NO_IMPLCT_RULE;
5515325Sgibbs	if (no_obj)
5525325Sgibbs		tp->f_flags |= NO_OBJ;
55361523Speter	if (needcount)
55461523Speter		tp->f_flags |= NEED_COUNT;
5551553Srgrimes	tp->f_needs = needs;
5561553Srgrimes	tp->f_special = special;
5574571Sgibbs	tp->f_depends = depends;
5586803Sgibbs	tp->f_clean = clean;
55954490Speter	tp->f_warn = warn;
5601553Srgrimes	if (pf && pf->f_type == INVISIBLE)
56161523Speter		pf->f_flags |= ISDUP;		/* mark as duplicate */
5621553Srgrimes	goto next;
5631553Srgrimes}
5641553Srgrimes
56545744Speterstatic int
56661640Speteropteq(char *cp, char *dp)
5671553Srgrimes{
5681553Srgrimes	char c, d;
5691553Srgrimes
5701553Srgrimes	for (; ; cp++, dp++) {
5711553Srgrimes		if (*cp != *dp) {
5721553Srgrimes			c = isupper(*cp) ? tolower(*cp) : *cp;
5731553Srgrimes			d = isupper(*dp) ? tolower(*dp) : *dp;
5741553Srgrimes			if (c != d)
5751553Srgrimes				return (0);
5761553Srgrimes		}
5771553Srgrimes		if (*cp == 0)
5781553Srgrimes			return (1);
5791553Srgrimes	}
5801553Srgrimes}
5811553Srgrimes
58245744Speterstatic void
58361640Speterdo_before_depend(FILE *fp)
5845325Sgibbs{
58561640Speter	struct file_list *tp;
58661640Speter	int lpos, len;
5875325Sgibbs
5885325Sgibbs	fputs("BEFORE_DEPEND=", fp);
5895325Sgibbs	lpos = 15;
5905325Sgibbs	for (tp = ftab; tp; tp = tp->f_next)
5915325Sgibbs		if (tp->f_flags & BEFORE_DEPEND) {
5925325Sgibbs			len = strlen(tp->f_fn);
5935325Sgibbs			if ((len = 3 + len) + lpos > 72) {
5945325Sgibbs				lpos = 8;
5955325Sgibbs				fputs("\\\n\t", fp);
5965325Sgibbs			}
5975325Sgibbs			if (tp->f_flags & NO_IMPLCT_RULE)
5985325Sgibbs				fprintf(fp, "%s ", tp->f_fn);
5995325Sgibbs			else
6005325Sgibbs				fprintf(fp, "$S/%s ", tp->f_fn);
6015325Sgibbs			lpos += len + 1;
6025325Sgibbs		}
6035325Sgibbs	if (lpos != 8)
6045325Sgibbs		putc('\n', fp);
6055325Sgibbs}
6065325Sgibbs
60745744Speterstatic void
60861640Speterdo_objs(FILE *fp)
6091553Srgrimes{
61061640Speter	struct file_list *tp;
61161640Speter	int lpos, len;
61261640Speter	char *cp, och, *sp;
6131553Srgrimes
6141553Srgrimes	fprintf(fp, "OBJS=");
6151553Srgrimes	lpos = 6;
6161553Srgrimes	for (tp = ftab; tp != 0; tp = tp->f_next) {
6174571Sgibbs		if (tp->f_type == INVISIBLE || tp->f_flags & NO_OBJ)
6181553Srgrimes			continue;
6191553Srgrimes		sp = tail(tp->f_fn);
6201553Srgrimes		cp = sp + (len = strlen(sp)) - 1;
6211553Srgrimes		och = *cp;
6221553Srgrimes		*cp = 'o';
6231553Srgrimes		if (len + lpos > 72) {
6241553Srgrimes			lpos = 8;
6251553Srgrimes			fprintf(fp, "\\\n\t");
6261553Srgrimes		}
6271553Srgrimes		fprintf(fp, "%s ", sp);
6281553Srgrimes		lpos += len + 1;
6291553Srgrimes		*cp = och;
6301553Srgrimes	}
6311553Srgrimes	if (lpos != 8)
6321553Srgrimes		putc('\n', fp);
6331553Srgrimes}
6341553Srgrimes
63545744Speterstatic void
63661640Speterdo_cfiles(FILE *fp)
6371553Srgrimes{
63861640Speter	struct file_list *tp;
63961640Speter	int lpos, len;
6401553Srgrimes
6411553Srgrimes	fputs("CFILES=", fp);
6421553Srgrimes	lpos = 8;
6431553Srgrimes	for (tp = ftab; tp; tp = tp->f_next)
64438782Snsouch		if (tp->f_type != INVISIBLE && tp->f_type != NODEPEND) {
6451553Srgrimes			len = strlen(tp->f_fn);
6461553Srgrimes			if (tp->f_fn[len - 1] != 'c')
6471553Srgrimes				continue;
6481553Srgrimes			if ((len = 3 + len) + lpos > 72) {
6491553Srgrimes				lpos = 8;
6501553Srgrimes				fputs("\\\n\t", fp);
6511553Srgrimes			}
65238782Snsouch			if (tp->f_type != LOCAL)
65338782Snsouch				fprintf(fp, "$S/%s ", tp->f_fn);
65438782Snsouch			else
65538782Snsouch				fprintf(fp, "%s ", tp->f_fn);
65638782Snsouch
6571553Srgrimes			lpos += len + 1;
6581553Srgrimes		}
6591553Srgrimes	if (lpos != 8)
6601553Srgrimes		putc('\n', fp);
6611553Srgrimes}
6621553Srgrimes
66345744Speterstatic void
66461640Speterdo_mfiles(FILE *fp)
66538782Snsouch{
66661640Speter	struct file_list *tp;
66761640Speter	int lpos, len;
66838782Snsouch
66938782Snsouch	fputs("MFILES=", fp);
67038782Snsouch	lpos = 8;
67138782Snsouch	for (tp = ftab; tp; tp = tp->f_next)
67238782Snsouch		if (tp->f_type != INVISIBLE) {
67338782Snsouch			len = strlen(tp->f_fn);
67438782Snsouch			if (tp->f_fn[len - 1] != 'm' || tp->f_fn[len - 2] != '.')
67538782Snsouch				continue;
67638782Snsouch			if ((len = 3 + len) + lpos > 72) {
67738782Snsouch				lpos = 8;
67838782Snsouch				fputs("\\\n\t", fp);
67938782Snsouch			}
68038782Snsouch			fprintf(fp, "$S/%s ", tp->f_fn);
68138782Snsouch			lpos += len + 1;
68238782Snsouch		}
68338782Snsouch	if (lpos != 8)
68438782Snsouch		putc('\n', fp);
68538782Snsouch}
68638782Snsouch
68745744Speterstatic void
68861640Speterdo_sfiles(FILE *fp)
68911917Sdg{
69061640Speter	struct file_list *tp;
69161640Speter	int lpos, len;
69211917Sdg
69311917Sdg	fputs("SFILES=", fp);
69411917Sdg	lpos = 8;
69511917Sdg	for (tp = ftab; tp; tp = tp->f_next)
69611917Sdg		if (tp->f_type != INVISIBLE) {
69711917Sdg			len = strlen(tp->f_fn);
69811917Sdg			if (tp->f_fn[len - 1] != 'S' && tp->f_fn[len - 1] != 's')
69911917Sdg				continue;
70011917Sdg			if ((len = 3 + len) + lpos > 72) {
70111917Sdg				lpos = 8;
70211917Sdg				fputs("\\\n\t", fp);
70311917Sdg			}
70411917Sdg			fprintf(fp, "$S/%s ", tp->f_fn);
70511917Sdg			lpos += len + 1;
70611917Sdg		}
70711917Sdg	if (lpos != 8)
70811917Sdg		putc('\n', fp);
70911917Sdg}
71011917Sdg
71145744Speterstatic char *
71261640Spetertail(char *fn)
7131553Srgrimes{
71461640Speter	char *cp;
7151553Srgrimes
7161553Srgrimes	cp = rindex(fn, '/');
7171553Srgrimes	if (cp == 0)
7181553Srgrimes		return (fn);
7191553Srgrimes	return (cp+1);
7201553Srgrimes}
7211553Srgrimes
7221553Srgrimes/*
7231553Srgrimes * Create the makerules for each file
7241553Srgrimes * which is part of the system.
7251553Srgrimes * Devices are processed with the special c2 option -i
7261553Srgrimes * which avoids any problem areas with i/o addressing
7271553Srgrimes * (e.g. for the VAX); assembler files are processed by as.
7281553Srgrimes */
72945744Speterstatic void
73061640Speterdo_rules(FILE *f)
7311553Srgrimes{
73261640Speter	char *cp, *np, och, *tp;
73361640Speter	struct file_list *ftp;
7341553Srgrimes	char *special;
7351553Srgrimes
7361553Srgrimes	for (ftp = ftab; ftp != 0; ftp = ftp->f_next) {
7371553Srgrimes		if (ftp->f_type == INVISIBLE)
7381553Srgrimes			continue;
73954490Speter		if (ftp->f_warn)
74054490Speter			printf("WARNING: %s\n", ftp->f_warn);
7411553Srgrimes		cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
7421553Srgrimes		och = *cp;
7434571Sgibbs		if (ftp->f_flags & NO_IMPLCT_RULE) {
7444571Sgibbs			if (ftp->f_depends)
74552098Speter				fprintf(f, "%s: %s\n", np, ftp->f_depends);
7464571Sgibbs			else
74752098Speter				fprintf(f, "%s: \n", np);
7481553Srgrimes		}
7494571Sgibbs		else {
7504571Sgibbs			*cp = '\0';
7514571Sgibbs			if (och == 'o') {
7528857Srgrimes				fprintf(f, "%so:\n\t-cp $S/%so .\n\n",
7534571Sgibbs					tail(np), np);
7544571Sgibbs				continue;
7554571Sgibbs			}
7564571Sgibbs			if (ftp->f_depends)
7578857Srgrimes				fprintf(f, "%so: $S/%s%c %s\n", tail(np),
7584571Sgibbs					np, och, ftp->f_depends);
7594571Sgibbs			else
7608857Srgrimes				fprintf(f, "%so: $S/%s%c\n", tail(np),
7614571Sgibbs					np, och);
7624571Sgibbs		}
7631553Srgrimes		tp = tail(np);
7641553Srgrimes		special = ftp->f_special;
7651553Srgrimes		if (special == 0) {
76645775Speter			char *ftype = NULL;
7671553Srgrimes			static char cmd[128];
7681553Srgrimes
7691553Srgrimes			switch (ftp->f_type) {
7701553Srgrimes
7711553Srgrimes			case NORMAL:
7721553Srgrimes				ftype = "NORMAL";
7731553Srgrimes				break;
7741553Srgrimes
7751553Srgrimes			case PROFILING:
7761553Srgrimes				if (!profiling)
7771553Srgrimes					continue;
7781553Srgrimes				ftype = "PROFILE";
7791553Srgrimes				break;
7801553Srgrimes
7811553Srgrimes			default:
7821553Srgrimes				printf("config: don't know rules for %s\n", np);
7831553Srgrimes				break;
7841553Srgrimes			}
78546021Speter			(void)snprintf(cmd, sizeof(cmd), "${%s_%c%s}", ftype, toupper(och),
7861553Srgrimes				      ftp->f_flags & CONFIGDEP? "_C" : "");
7871553Srgrimes			special = cmd;
7881553Srgrimes		}
7891553Srgrimes		*cp = och;
7901553Srgrimes		fprintf(f, "\t%s\n\n", special);
7911553Srgrimes	}
7921553Srgrimes}
7931553Srgrimes
79445744Speterstatic void
79561640Speterdo_clean(FILE *fp)
7966803Sgibbs{
79761640Speter	struct file_list *tp;
79861640Speter	int lpos, len;
7996803Sgibbs
8006803Sgibbs	fputs("CLEAN=", fp);
8016803Sgibbs	lpos = 7;
8026803Sgibbs	for (tp = ftab; tp; tp = tp->f_next)
8036803Sgibbs		if (tp->f_clean) {
8046803Sgibbs			len = strlen(tp->f_clean);
8056803Sgibbs			if (len + lpos > 72) {
8066803Sgibbs				lpos = 8;
8076803Sgibbs				fputs("\\\n\t", fp);
8086803Sgibbs			}
8096803Sgibbs			fprintf(fp, "%s ", tp->f_clean);
8106803Sgibbs			lpos += len + 1;
8116803Sgibbs		}
8126803Sgibbs	if (lpos != 8)
8136803Sgibbs		putc('\n', fp);
8146803Sgibbs}
8156803Sgibbs
8161553Srgrimeschar *
81761640Speterraisestr(char *str)
8181553Srgrimes{
81961640Speter	char *cp = str;
8201553Srgrimes
8211553Srgrimes	while (*str) {
8221553Srgrimes		if (islower(*str))
8231553Srgrimes			*str = toupper(*str);
8241553Srgrimes		str++;
8251553Srgrimes	}
8261553Srgrimes	return (cp);
8271553Srgrimes}
828