mkmakefile.c revision 55614
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 55614 2000-01-08 16:48:12Z 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) \
571553Srgrimes	{ register 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) \
641553Srgrimes	{ register 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
7345744Speterstatic char *tail __P((char *));
7445744Speterstatic void do_clean __P((FILE *));
7545744Speterstatic void do_rules __P((FILE *));
7645744Speterstatic void do_sfiles __P((FILE *));
7745744Speterstatic void do_mfiles __P((FILE *));
7845744Speterstatic void do_cfiles __P((FILE *));
7945744Speterstatic void do_objs __P((FILE *));
8045744Speterstatic void do_before_depend __P((FILE *));
8145744Speterstatic int opteq __P((char *, char *));
8245744Speterstatic void read_files __P((void));
8329451Scharnier
841553Srgrimes/*
851553Srgrimes * Lookup a file, by name.
861553Srgrimes */
8745744Speterstatic struct file_list *
881553Srgrimesfl_lookup(file)
891553Srgrimes	register char *file;
901553Srgrimes{
911553Srgrimes	register struct file_list *fp;
921553Srgrimes
931553Srgrimes	for (fp = ftab ; fp != 0; fp = fp->f_next) {
941553Srgrimes		if (eq(fp->f_fn, file))
951553Srgrimes			return (fp);
961553Srgrimes	}
971553Srgrimes	return (0);
981553Srgrimes}
991553Srgrimes
1001553Srgrimes/*
1011553Srgrimes * Lookup a file, by final component name.
1021553Srgrimes */
10345744Speterstatic struct file_list *
1041553Srgrimesfltail_lookup(file)
1051553Srgrimes	register char *file;
1061553Srgrimes{
1071553Srgrimes	register struct file_list *fp;
1081553Srgrimes
1091553Srgrimes	for (fp = ftab ; fp != 0; fp = fp->f_next) {
1101553Srgrimes		if (eq(tail(fp->f_fn), tail(file)))
1111553Srgrimes			return (fp);
1121553Srgrimes	}
1131553Srgrimes	return (0);
1141553Srgrimes}
1151553Srgrimes
1161553Srgrimes/*
1171553Srgrimes * Make a new file list entry
1181553Srgrimes */
11945744Speterstatic struct file_list *
1201553Srgrimesnew_fent()
1211553Srgrimes{
1221553Srgrimes	register struct file_list *fp;
1231553Srgrimes
1241553Srgrimes	fp = (struct file_list *) malloc(sizeof *fp);
1251553Srgrimes	bzero(fp, sizeof *fp);
1261553Srgrimes	if (fcur == 0)
1271553Srgrimes		fcur = ftab = fp;
1281553Srgrimes	else
1291553Srgrimes		fcur->f_next = fp;
1301553Srgrimes	fcur = fp;
1311553Srgrimes	return (fp);
1321553Srgrimes}
1331553Srgrimes
1341553Srgrimes/*
1351553Srgrimes * Build the makefile from the skeleton
1361553Srgrimes */
13729451Scharniervoid
1381553Srgrimesmakefile()
1391553Srgrimes{
1401553Srgrimes	FILE *ifp, *ofp;
1411553Srgrimes	char line[BUFSIZ];
1421553Srgrimes	struct opt *op;
14312772Speter	int warn_make_clean = 0;
14430638Speter	int versreq;
1451553Srgrimes
1461553Srgrimes	read_files();
14755614Speter	snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename);
1481553Srgrimes	ifp = fopen(line, "r");
14955614Speter	if (ifp == 0) {
15055614Speter		snprintf(line, sizeof(line), "Makefile.%s", machinename);
15155614Speter		ifp = fopen(line, "r");
15255614Speter	}
15329451Scharnier	if (ifp == 0)
15429451Scharnier		err(1, "%s", line);
15513400Speter	ofp = fopen(path("Makefile.new"), "w");
15629451Scharnier	if (ofp == 0)
15729451Scharnier		err(1, "%s", path("Makefile.new"));
15845744Speter	fprintf(ofp, "KERN_IDENT=%s\n", raisestr(ident));
15911711Sdg	fprintf(ofp, "IDENT=");
16020395Sbde	if (profiling)
1611553Srgrimes		fprintf(ofp, " -DGPROF");
16212772Speter
1631553Srgrimes	if (cputype == 0) {
1641553Srgrimes		printf("cpu type must be specified\n");
1651553Srgrimes		exit(1);
1661553Srgrimes	}
16712772Speter	for (op = opt; op; op = op->op_next) {
16812772Speter		if (!op->op_ownfile) {
16912772Speter			warn_make_clean++;
17012772Speter			if (op->op_value)
17112772Speter				fprintf(ofp, " -D%s=%s", op->op_name, op->op_value);
17212772Speter			else
17312772Speter				fprintf(ofp, " -D%s", op->op_name);
17433538Seivind			printf("%s:%d: unknown option \"%s\"\n",
17533538Seivind				   PREFIX, op->op_line, op->op_name);
17612772Speter		}
17712772Speter	}
1781553Srgrimes	fprintf(ofp, "\n");
1791553Srgrimes	for (op = mkopt; op; op = op->op_next)
1801553Srgrimes		fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
1811553Srgrimes	if (debugging)
1821553Srgrimes		fprintf(ofp, "DEBUG=-g\n");
18320395Sbde	if (profiling) {
1841553Srgrimes		fprintf(ofp, "PROF=-pg\n");
18520395Sbde		fprintf(ofp, "PROFLEVEL=%d\n", profiling);
18620395Sbde	}
18752653Smarcel	if (*srcdir != '\0')
18852653Smarcel		fprintf(ofp,"S=%s\n", srcdir);
1891553Srgrimes	while (fgets(line, BUFSIZ, ifp) != 0) {
1901553Srgrimes		if (*line != '%') {
1911553Srgrimes			fprintf(ofp, "%s", line);
1921553Srgrimes			continue;
1931553Srgrimes		}
1945325Sgibbs		if (eq(line, "%BEFORE_DEPEND\n"))
1955325Sgibbs			do_before_depend(ofp);
1965325Sgibbs		else if (eq(line, "%OBJS\n"))
1971553Srgrimes			do_objs(ofp);
19838782Snsouch		else if (eq(line, "%MFILES\n"))
19938782Snsouch			do_mfiles(ofp);
2001553Srgrimes		else if (eq(line, "%CFILES\n"))
2011553Srgrimes			do_cfiles(ofp);
20211917Sdg		else if (eq(line, "%SFILES\n"))
20311917Sdg			do_sfiles(ofp);
2041553Srgrimes		else if (eq(line, "%RULES\n"))
2051553Srgrimes			do_rules(ofp);
2066803Sgibbs		else if (eq(line, "%CLEAN\n"))
2076803Sgibbs			do_clean(ofp);
20830638Speter		else if (strncmp(line, "%VERSREQ=", sizeof("%VERSREQ=") - 1) == 0) {
20930638Speter			versreq = atoi(line + sizeof("%VERSREQ=") - 1);
21030638Speter			if (versreq != CONFIGVERS) {
21130638Speter				fprintf(stderr, "WARNING: version of config(8) does not match kernel!\n");
21230638Speter				fprintf(stderr, "config version = %d, ", CONFIGVERS);
21337129Sjkh				fprintf(stderr, "version required = %d\n\n", versreq);
21437129Sjkh				fprintf(stderr, "Make sure that /usr/src/usr.sbin/config is in sync\n");
21537129Sjkh				fprintf(stderr, "with your /usr/src/sys and install a new config binary\n");
21637129Sjkh				fprintf(stderr, "before trying this again.\n\n");
21739307Sgibbs				fprintf(stderr, "If running the new config fails check your config\n");
21839307Sgibbs				fprintf(stderr, "file against the GENERIC or LINT config files for\n");
21939307Sgibbs				fprintf(stderr, "changes in config syntax, or option/device naming\n");
22039307Sgibbs				fprintf(stderr, "conventions\n\n");
22130638Speter			}
22230638Speter		} else
2231553Srgrimes			fprintf(stderr,
2241553Srgrimes			    "Unknown %% construct in generic makefile: %s",
2251553Srgrimes			    line);
2261553Srgrimes	}
2271553Srgrimes	(void) fclose(ifp);
2281553Srgrimes	(void) fclose(ofp);
22913400Speter	moveifchanged(path("Makefile.new"), path("Makefile"));
23034619Seivind
23134619Seivind	if (warn_make_clean != 0 && old_config_present) {
23234619Seivind		printf(
23334619Seivind		"Unknown option%s used - it is VERY important that you do\n",
23434619Seivind			(warn_make_clean > 1 ? "s" : ""));
23534619Seivind		printf("         make clean && make depend\n");
23634619Seivind		printf("before recompiling\n");
23734619Seivind	} else
23834619Seivind		printf("Don't forget to do a ``make depend''\n");
2391553Srgrimes}
2401553Srgrimes
2411553Srgrimes/*
2421553Srgrimes * Read in the information about files used in making the system.
2431553Srgrimes * Store it in the ftab linked list.
2441553Srgrimes */
24545744Speterstatic void
2461553Srgrimesread_files()
2471553Srgrimes{
2481553Srgrimes	FILE *fp;
2491553Srgrimes	register struct file_list *tp, *pf;
2501553Srgrimes	register struct device *dp;
2511553Srgrimes	struct device *save_dp;
2521553Srgrimes	register struct opt *op;
25354490Speter	char *wd, *this, *needs, *special, *depends, *clean, *warn;
25420457Sjoerg	char fname[80];
25548525Speter	int ddwarned = 0;
2568857Srgrimes	int nreqs, first = 1, configdep, isdup, std, filetype,
25730796Sjoerg	    imp_rule, no_obj, before_depend, mandatory;
2581553Srgrimes
2591553Srgrimes	ftab = 0;
26045775Speter	save_dp = NULL;
26155614Speter	if (ident == NULL) {
26255614Speter		printf("no ident line specified\n");
26355614Speter		exit(1);
26455614Speter	}
26520457Sjoerg	(void) snprintf(fname, sizeof fname, "../../conf/files");
2661553Srgrimesopenit:
2671553Srgrimes	fp = fopen(fname, "r");
26829451Scharnier	if (fp == 0)
26929451Scharnier		err(1, "%s", fname);
2701553Srgrimesnext:
2711553Srgrimes	/*
27230796Sjoerg	 * filename    [ standard | mandatory | optional ] [ config-dependent ]
27348525Speter	 *	[ dev* | profiling-routine ] [ no-obj ]
2748857Srgrimes	 *	[ compile-with "compile rule" [no-implicit-rule] ]
2756803Sgibbs	 *      [ dependency "dependency-list"] [ before-depend ]
27654490Speter	 *	[ clean "file-list"] [ warning "text warning" ]
2771553Srgrimes	 */
2781553Srgrimes	wd = get_word(fp);
2791553Srgrimes	if (wd == (char *)EOF) {
2801553Srgrimes		(void) fclose(fp);
2811553Srgrimes		if (first == 1) {
28255614Speter			first++;
28355614Speter			(void) snprintf(fname, sizeof fname, "../../conf/files.%s", machinename);
28455614Speter			fp = fopen(fname, "r");
28555614Speter			if (fp != 0)
28655614Speter				goto next;
28720457Sjoerg			(void) snprintf(fname, sizeof fname, "files.%s", machinename);
2881553Srgrimes			goto openit;
2891553Srgrimes		}
2901553Srgrimes		if (first == 2) {
29155614Speter			first++;
29245744Speter			(void) snprintf(fname, sizeof fname, "files.%s", raisestr(ident));
2931553Srgrimes			fp = fopen(fname, "r");
2941553Srgrimes			if (fp != 0)
2951553Srgrimes				goto next;
2961553Srgrimes		}
2971553Srgrimes		return;
2981553Srgrimes	}
2991553Srgrimes	if (wd == 0)
3001553Srgrimes		goto next;
30152098Speter	if (wd[0] == '#')
3021566Srgrimes	{
30352098Speter		while (((wd = get_word(fp)) != (char *)EOF) && wd)
30452098Speter			;
3051566Srgrimes		goto next;
3061566Srgrimes	}
3071553Srgrimes	this = ns(wd);
3081553Srgrimes	next_word(fp, wd);
3091553Srgrimes	if (wd == 0) {
3101553Srgrimes		printf("%s: No type for %s.\n",
3111553Srgrimes		    fname, this);
3121553Srgrimes		exit(1);
3131553Srgrimes	}
3141553Srgrimes	if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags))
3151553Srgrimes		isdup = 1;
3161553Srgrimes	else
3171553Srgrimes		isdup = 0;
3181553Srgrimes	tp = 0;
31954047Sarchie	if (first == 3 && pf == 0 && (tp = fltail_lookup(this)) != 0) {
32054047Sarchie		if (tp->f_type != INVISIBLE || tp->f_flags)
32154047Sarchie			printf("%s: Local file %s overrides %s.\n",
32254047Sarchie			    fname, this, tp->f_fn);
32354047Sarchie		else
32454047Sarchie			printf("%s: Local file %s could override %s"
32554047Sarchie			    " with a different kernel configuration.\n",
32654047Sarchie			    fname, this, tp->f_fn);
32754047Sarchie	}
3281553Srgrimes	nreqs = 0;
3291553Srgrimes	special = 0;
3304571Sgibbs	depends = 0;
3316803Sgibbs	clean = 0;
33254490Speter	warn = 0;
3331553Srgrimes	configdep = 0;
3341553Srgrimes	needs = 0;
33530796Sjoerg	std = mandatory = 0;
3364571Sgibbs	imp_rule = 0;
3374571Sgibbs	no_obj = 0;
3385325Sgibbs	before_depend = 0;
3391553Srgrimes	filetype = NORMAL;
3401553Srgrimes	if (eq(wd, "standard"))
3411553Srgrimes		std = 1;
34230796Sjoerg	/*
34330796Sjoerg	 * If an entry is marked "mandatory", config will abort if it's
34430796Sjoerg	 * not called by a configuration line in the config file.  Apart
34530796Sjoerg	 * from this, the device is handled like one marked "optional".
34630796Sjoerg	 */
34730796Sjoerg	else if (eq(wd, "mandatory"))
34830796Sjoerg		mandatory = 1;
3491553Srgrimes	else if (!eq(wd, "optional")) {
35030796Sjoerg		printf("%s: %s must be optional, mandatory or standard\n",
35130796Sjoerg		       fname, this);
3521553Srgrimes		exit(1);
3531553Srgrimes	}
3541553Srgrimesnextparam:
3551553Srgrimes	next_word(fp, wd);
3561553Srgrimes	if (wd == 0)
3571553Srgrimes		goto doneparam;
3581553Srgrimes	if (eq(wd, "config-dependent")) {
3591553Srgrimes		configdep++;
3601553Srgrimes		goto nextparam;
3611553Srgrimes	}
3624571Sgibbs	if (eq(wd, "no-obj")) {
3634571Sgibbs		no_obj++;
3644571Sgibbs		goto nextparam;
3654571Sgibbs	}
3664571Sgibbs	if (eq(wd, "no-implicit-rule")) {
3674571Sgibbs		if (special == 0) {
3684571Sgibbs			printf("%s: alternate rule required when "
3694571Sgibbs			       "\"no-implicit-rule\" is specified.\n",
3704571Sgibbs			       fname);
3714571Sgibbs		}
3724571Sgibbs		imp_rule++;
3734571Sgibbs		goto nextparam;
3744571Sgibbs	}
3755325Sgibbs	if (eq(wd, "before-depend")) {
3765325Sgibbs		before_depend++;
3775325Sgibbs		goto nextparam;
3785325Sgibbs	}
3796803Sgibbs	if (eq(wd, "dependency")) {
3804571Sgibbs		next_quoted_word(fp, wd);
3814571Sgibbs		if (wd == 0) {
3824571Sgibbs			printf("%s: %s missing compile command string.\n",
3838520Srgrimes			       fname, this);
3844571Sgibbs			exit(1);
3854571Sgibbs		}
3864571Sgibbs		depends = ns(wd);
3874571Sgibbs		goto nextparam;
3884571Sgibbs	}
3896803Sgibbs	if (eq(wd, "clean")) {
3905325Sgibbs		next_quoted_word(fp, wd);
3915325Sgibbs		if (wd == 0) {
3926803Sgibbs			printf("%s: %s missing clean file list.\n",
3938520Srgrimes			       fname, this);
3945325Sgibbs			exit(1);
3955325Sgibbs		}
3966803Sgibbs		clean = ns(wd);
3975325Sgibbs		goto nextparam;
3985325Sgibbs	}
3991553Srgrimes	if (eq(wd, "compile-with")) {
4001553Srgrimes		next_quoted_word(fp, wd);
4011553Srgrimes		if (wd == 0) {
4021553Srgrimes			printf("%s: %s missing compile command string.\n",
4038520Srgrimes			       fname, this);
4041553Srgrimes			exit(1);
4051553Srgrimes		}
4061553Srgrimes		special = ns(wd);
4071553Srgrimes		goto nextparam;
4081553Srgrimes	}
40954490Speter	if (eq(wd, "warning")) {
41054490Speter		next_quoted_word(fp, wd);
41154490Speter		if (wd == 0) {
41254490Speter			printf("%s: %s missing warning text string.\n",
41354490Speter				fname, this);
41454490Speter			exit(1);
41554490Speter		}
41654490Speter		warn = ns(wd);
41754490Speter		goto nextparam;
41854490Speter	}
4191553Srgrimes	nreqs++;
42038782Snsouch	if (eq(wd, "local")) {
42138782Snsouch		filetype = LOCAL;
42238782Snsouch		goto nextparam;
42338782Snsouch	}
42438782Snsouch	if (eq(wd, "no-depend")) {
42538782Snsouch		filetype = NODEPEND;
42638782Snsouch		goto nextparam;
42738782Snsouch	}
4281553Srgrimes	if (eq(wd, "device-driver")) {
42948525Speter		if (!ddwarned) {
43048525Speter			printf("%s: `device-driver' flag ignored.\n", fname);
43148525Speter			ddwarned++;
43248525Speter		}
4331553Srgrimes		goto nextparam;
4341553Srgrimes	}
4351553Srgrimes	if (eq(wd, "profiling-routine")) {
4361553Srgrimes		filetype = PROFILING;
4371553Srgrimes		goto nextparam;
4381553Srgrimes	}
4391553Srgrimes	if (needs == 0 && nreqs == 1)
4401553Srgrimes		needs = ns(wd);
4411553Srgrimes	if (isdup)
4421553Srgrimes		goto invis;
4431553Srgrimes	for (dp = dtab; dp != 0; save_dp = dp, dp = dp->d_next)
4441553Srgrimes		if (eq(dp->d_name, wd)) {
4451553Srgrimes			if (std && dp->d_type == PSEUDO_DEVICE &&
44652098Speter			    dp->d_count <= 0)
44752098Speter				dp->d_count = 1;
4481553Srgrimes			goto nextparam;
4491553Srgrimes		}
45030796Sjoerg	if (mandatory) {
45130796Sjoerg		printf("%s: mandatory device \"%s\" not found\n",
45230796Sjoerg		       fname, wd);
45330796Sjoerg		exit(1);
45430796Sjoerg	}
4551553Srgrimes	if (std) {
4561553Srgrimes		dp = (struct device *) malloc(sizeof *dp);
45712772Speter		bzero(dp, sizeof *dp);
4581553Srgrimes		init_dev(dp);
4591553Srgrimes		dp->d_name = ns(wd);
4601553Srgrimes		dp->d_type = PSEUDO_DEVICE;
46152098Speter		dp->d_count = 1;
4621553Srgrimes		save_dp->d_next = dp;
4631553Srgrimes		goto nextparam;
4641553Srgrimes	}
4651553Srgrimes	for (op = opt; op != 0; op = op->op_next)
4661553Srgrimes		if (op->op_value == 0 && opteq(op->op_name, wd)) {
4671553Srgrimes			if (nreqs == 1) {
4681553Srgrimes				free(needs);
4691553Srgrimes				needs = 0;
4701553Srgrimes			}
4711553Srgrimes			goto nextparam;
4721553Srgrimes		}
4731553Srgrimesinvis:
4741553Srgrimes	while ((wd = get_word(fp)) != 0)
4751553Srgrimes		;
4761553Srgrimes	if (tp == 0)
4771553Srgrimes		tp = new_fent();
4781553Srgrimes	tp->f_fn = this;
4791553Srgrimes	tp->f_type = INVISIBLE;
4801553Srgrimes	tp->f_needs = needs;
4811553Srgrimes	tp->f_flags = isdup;
4821553Srgrimes	tp->f_special = special;
4834571Sgibbs	tp->f_depends = depends;
4846803Sgibbs	tp->f_clean = clean;
48554490Speter	tp->f_warn = warn;
4861553Srgrimes	goto next;
4871553Srgrimes
4881553Srgrimesdoneparam:
4891553Srgrimes	if (std == 0 && nreqs == 0) {
4901553Srgrimes		printf("%s: what is %s optional on?\n",
4911553Srgrimes		    fname, this);
4921553Srgrimes		exit(1);
4931553Srgrimes	}
4941553Srgrimes
4951553Srgrimes	if (wd) {
4961553Srgrimes		printf("%s: syntax error describing %s\n",
4971553Srgrimes		    fname, this);
4981553Srgrimes		exit(1);
4991553Srgrimes	}
5001553Srgrimes	if (filetype == PROFILING && profiling == 0)
5011553Srgrimes		goto next;
5021553Srgrimes	if (tp == 0)
5031553Srgrimes		tp = new_fent();
5041553Srgrimes	tp->f_fn = this;
5051553Srgrimes	tp->f_type = filetype;
5061553Srgrimes	tp->f_flags = 0;
5071553Srgrimes	if (configdep)
5081553Srgrimes		tp->f_flags |= CONFIGDEP;
5094571Sgibbs	if (imp_rule)
5104571Sgibbs		tp->f_flags |= NO_IMPLCT_RULE;
5114571Sgibbs	if (no_obj)
5124571Sgibbs		tp->f_flags |= NO_OBJ;
5135325Sgibbs	if (before_depend)
5145325Sgibbs		tp->f_flags |= BEFORE_DEPEND;
5155325Sgibbs	if (imp_rule)
5165325Sgibbs		tp->f_flags |= NO_IMPLCT_RULE;
5175325Sgibbs	if (no_obj)
5185325Sgibbs		tp->f_flags |= NO_OBJ;
5191553Srgrimes	tp->f_needs = needs;
5201553Srgrimes	tp->f_special = special;
5214571Sgibbs	tp->f_depends = depends;
5226803Sgibbs	tp->f_clean = clean;
52354490Speter	tp->f_warn = warn;
5241553Srgrimes	if (pf && pf->f_type == INVISIBLE)
5251553Srgrimes		pf->f_flags = 1;		/* mark as duplicate */
5261553Srgrimes	goto next;
5271553Srgrimes}
5281553Srgrimes
52945744Speterstatic int
5301553Srgrimesopteq(cp, dp)
5311553Srgrimes	char *cp, *dp;
5321553Srgrimes{
5331553Srgrimes	char c, d;
5341553Srgrimes
5351553Srgrimes	for (; ; cp++, dp++) {
5361553Srgrimes		if (*cp != *dp) {
5371553Srgrimes			c = isupper(*cp) ? tolower(*cp) : *cp;
5381553Srgrimes			d = isupper(*dp) ? tolower(*dp) : *dp;
5391553Srgrimes			if (c != d)
5401553Srgrimes				return (0);
5411553Srgrimes		}
5421553Srgrimes		if (*cp == 0)
5431553Srgrimes			return (1);
5441553Srgrimes	}
5451553Srgrimes}
5461553Srgrimes
54745744Speterstatic void
5485325Sgibbsdo_before_depend(fp)
5495325Sgibbs	FILE *fp;
5505325Sgibbs{
55129451Scharnier	register struct file_list *tp;
5525325Sgibbs	register int lpos, len;
5535325Sgibbs
5545325Sgibbs	fputs("BEFORE_DEPEND=", fp);
5555325Sgibbs	lpos = 15;
5565325Sgibbs	for (tp = ftab; tp; tp = tp->f_next)
5575325Sgibbs		if (tp->f_flags & BEFORE_DEPEND) {
5585325Sgibbs			len = strlen(tp->f_fn);
5595325Sgibbs			if ((len = 3 + len) + lpos > 72) {
5605325Sgibbs				lpos = 8;
5615325Sgibbs				fputs("\\\n\t", fp);
5625325Sgibbs			}
5635325Sgibbs			if (tp->f_flags & NO_IMPLCT_RULE)
5645325Sgibbs				fprintf(fp, "%s ", tp->f_fn);
5655325Sgibbs			else
5665325Sgibbs				fprintf(fp, "$S/%s ", tp->f_fn);
5675325Sgibbs			lpos += len + 1;
5685325Sgibbs		}
5695325Sgibbs	if (lpos != 8)
5705325Sgibbs		putc('\n', fp);
5715325Sgibbs}
5725325Sgibbs
57345744Speterstatic void
5741553Srgrimesdo_objs(fp)
5751553Srgrimes	FILE *fp;
5761553Srgrimes{
57746821Speter	register struct file_list *tp;
5781553Srgrimes	register int lpos, len;
5791553Srgrimes	register char *cp, och, *sp;
5801553Srgrimes
5811553Srgrimes	fprintf(fp, "OBJS=");
5821553Srgrimes	lpos = 6;
5831553Srgrimes	for (tp = ftab; tp != 0; tp = tp->f_next) {
5844571Sgibbs		if (tp->f_type == INVISIBLE || tp->f_flags & NO_OBJ)
5851553Srgrimes			continue;
5861553Srgrimes		sp = tail(tp->f_fn);
5871553Srgrimes		cp = sp + (len = strlen(sp)) - 1;
5881553Srgrimes		och = *cp;
5891553Srgrimes		*cp = 'o';
5901553Srgrimes		if (len + lpos > 72) {
5911553Srgrimes			lpos = 8;
5921553Srgrimes			fprintf(fp, "\\\n\t");
5931553Srgrimes		}
5941553Srgrimes		fprintf(fp, "%s ", sp);
5951553Srgrimes		lpos += len + 1;
5961553Srgrimes		*cp = och;
5971553Srgrimes	}
5981553Srgrimes	if (lpos != 8)
5991553Srgrimes		putc('\n', fp);
6001553Srgrimes}
6011553Srgrimes
60245744Speterstatic void
6031553Srgrimesdo_cfiles(fp)
6041553Srgrimes	FILE *fp;
6051553Srgrimes{
60646821Speter	register struct file_list *tp;
6071553Srgrimes	register int lpos, len;
6081553Srgrimes
6091553Srgrimes	fputs("CFILES=", fp);
6101553Srgrimes	lpos = 8;
6111553Srgrimes	for (tp = ftab; tp; tp = tp->f_next)
61238782Snsouch		if (tp->f_type != INVISIBLE && tp->f_type != NODEPEND) {
6131553Srgrimes			len = strlen(tp->f_fn);
6141553Srgrimes			if (tp->f_fn[len - 1] != 'c')
6151553Srgrimes				continue;
6161553Srgrimes			if ((len = 3 + len) + lpos > 72) {
6171553Srgrimes				lpos = 8;
6181553Srgrimes				fputs("\\\n\t", fp);
6191553Srgrimes			}
62038782Snsouch			if (tp->f_type != LOCAL)
62138782Snsouch				fprintf(fp, "$S/%s ", tp->f_fn);
62238782Snsouch			else
62338782Snsouch				fprintf(fp, "%s ", tp->f_fn);
62438782Snsouch
6251553Srgrimes			lpos += len + 1;
6261553Srgrimes		}
6271553Srgrimes	if (lpos != 8)
6281553Srgrimes		putc('\n', fp);
6291553Srgrimes}
6301553Srgrimes
63145744Speterstatic void
63238782Snsouchdo_mfiles(fp)
63338782Snsouch	FILE *fp;
63438782Snsouch{
63538782Snsouch	register struct file_list *tp;
63638782Snsouch	register int lpos, len;
63738782Snsouch
63838782Snsouch	fputs("MFILES=", fp);
63938782Snsouch	lpos = 8;
64038782Snsouch	for (tp = ftab; tp; tp = tp->f_next)
64138782Snsouch		if (tp->f_type != INVISIBLE) {
64238782Snsouch			len = strlen(tp->f_fn);
64338782Snsouch			if (tp->f_fn[len - 1] != 'm' || tp->f_fn[len - 2] != '.')
64438782Snsouch				continue;
64538782Snsouch			if ((len = 3 + len) + lpos > 72) {
64638782Snsouch				lpos = 8;
64738782Snsouch				fputs("\\\n\t", fp);
64838782Snsouch			}
64938782Snsouch			fprintf(fp, "$S/%s ", tp->f_fn);
65038782Snsouch			lpos += len + 1;
65138782Snsouch		}
65238782Snsouch	if (lpos != 8)
65338782Snsouch		putc('\n', fp);
65438782Snsouch}
65538782Snsouch
65645744Speterstatic void
65711917Sdgdo_sfiles(fp)
65811917Sdg	FILE *fp;
65911917Sdg{
66011917Sdg	register struct file_list *tp;
66111917Sdg	register int lpos, len;
66211917Sdg
66311917Sdg	fputs("SFILES=", fp);
66411917Sdg	lpos = 8;
66511917Sdg	for (tp = ftab; tp; tp = tp->f_next)
66611917Sdg		if (tp->f_type != INVISIBLE) {
66711917Sdg			len = strlen(tp->f_fn);
66811917Sdg			if (tp->f_fn[len - 1] != 'S' && tp->f_fn[len - 1] != 's')
66911917Sdg				continue;
67011917Sdg			if ((len = 3 + len) + lpos > 72) {
67111917Sdg				lpos = 8;
67211917Sdg				fputs("\\\n\t", fp);
67311917Sdg			}
67411917Sdg			fprintf(fp, "$S/%s ", tp->f_fn);
67511917Sdg			lpos += len + 1;
67611917Sdg		}
67711917Sdg	if (lpos != 8)
67811917Sdg		putc('\n', fp);
67911917Sdg}
68011917Sdg
68111917Sdg
68245744Speterstatic char *
6831553Srgrimestail(fn)
6841553Srgrimes	char *fn;
6851553Srgrimes{
6861553Srgrimes	register char *cp;
6871553Srgrimes
6881553Srgrimes	cp = rindex(fn, '/');
6891553Srgrimes	if (cp == 0)
6901553Srgrimes		return (fn);
6911553Srgrimes	return (cp+1);
6921553Srgrimes}
6931553Srgrimes
6941553Srgrimes/*
6951553Srgrimes * Create the makerules for each file
6961553Srgrimes * which is part of the system.
6971553Srgrimes * Devices are processed with the special c2 option -i
6981553Srgrimes * which avoids any problem areas with i/o addressing
6991553Srgrimes * (e.g. for the VAX); assembler files are processed by as.
7001553Srgrimes */
70145744Speterstatic void
7021553Srgrimesdo_rules(f)
7031553Srgrimes	FILE *f;
7041553Srgrimes{
7051553Srgrimes	register char *cp, *np, och, *tp;
7061553Srgrimes	register struct file_list *ftp;
7071553Srgrimes	char *special;
7081553Srgrimes
7091553Srgrimes	for (ftp = ftab; ftp != 0; ftp = ftp->f_next) {
7101553Srgrimes		if (ftp->f_type == INVISIBLE)
7111553Srgrimes			continue;
71254490Speter		if (ftp->f_warn)
71354490Speter			printf("WARNING: %s\n", ftp->f_warn);
7141553Srgrimes		cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
7151553Srgrimes		och = *cp;
7164571Sgibbs		if (ftp->f_flags & NO_IMPLCT_RULE) {
7174571Sgibbs			if (ftp->f_depends)
71852098Speter				fprintf(f, "%s: %s\n", np, ftp->f_depends);
7194571Sgibbs			else
72052098Speter				fprintf(f, "%s: \n", np);
7211553Srgrimes		}
7224571Sgibbs		else {
7234571Sgibbs			*cp = '\0';
7244571Sgibbs			if (och == 'o') {
7258857Srgrimes				fprintf(f, "%so:\n\t-cp $S/%so .\n\n",
7264571Sgibbs					tail(np), np);
7274571Sgibbs				continue;
7284571Sgibbs			}
7294571Sgibbs			if (ftp->f_depends)
7308857Srgrimes				fprintf(f, "%so: $S/%s%c %s\n", tail(np),
7314571Sgibbs					np, och, ftp->f_depends);
7324571Sgibbs			else
7338857Srgrimes				fprintf(f, "%so: $S/%s%c\n", tail(np),
7344571Sgibbs					np, och);
7354571Sgibbs		}
7361553Srgrimes		tp = tail(np);
7371553Srgrimes		special = ftp->f_special;
7381553Srgrimes		if (special == 0) {
73945775Speter			char *ftype = NULL;
7401553Srgrimes			static char cmd[128];
7411553Srgrimes
7421553Srgrimes			switch (ftp->f_type) {
7431553Srgrimes
7441553Srgrimes			case NORMAL:
7451553Srgrimes				ftype = "NORMAL";
7461553Srgrimes				break;
7471553Srgrimes
7481553Srgrimes			case PROFILING:
7491553Srgrimes				if (!profiling)
7501553Srgrimes					continue;
7511553Srgrimes				ftype = "PROFILE";
7521553Srgrimes				break;
7531553Srgrimes
7541553Srgrimes			default:
7551553Srgrimes				printf("config: don't know rules for %s\n", np);
7561553Srgrimes				break;
7571553Srgrimes			}
75846021Speter			(void)snprintf(cmd, sizeof(cmd), "${%s_%c%s}", ftype, toupper(och),
7591553Srgrimes				      ftp->f_flags & CONFIGDEP? "_C" : "");
7601553Srgrimes			special = cmd;
7611553Srgrimes		}
7621553Srgrimes		*cp = och;
7631553Srgrimes		fprintf(f, "\t%s\n\n", special);
7641553Srgrimes	}
7651553Srgrimes}
7661553Srgrimes
76745744Speterstatic void
7686803Sgibbsdo_clean(fp)
7696803Sgibbs	FILE *fp;
7706803Sgibbs{
77129451Scharnier	register struct file_list *tp;
7726803Sgibbs	register int lpos, len;
7736803Sgibbs
7746803Sgibbs	fputs("CLEAN=", fp);
7756803Sgibbs	lpos = 7;
7766803Sgibbs	for (tp = ftab; tp; tp = tp->f_next)
7776803Sgibbs		if (tp->f_clean) {
7786803Sgibbs			len = strlen(tp->f_clean);
7796803Sgibbs			if (len + lpos > 72) {
7806803Sgibbs				lpos = 8;
7816803Sgibbs				fputs("\\\n\t", fp);
7826803Sgibbs			}
7836803Sgibbs			fprintf(fp, "%s ", tp->f_clean);
7846803Sgibbs			lpos += len + 1;
7856803Sgibbs		}
7866803Sgibbs	if (lpos != 8)
7876803Sgibbs		putc('\n', fp);
7886803Sgibbs}
7896803Sgibbs
7901553Srgrimeschar *
79145744Speterraisestr(str)
7921553Srgrimes	register char *str;
7931553Srgrimes{
7941553Srgrimes	register char *cp = str;
7951553Srgrimes
7961553Srgrimes	while (*str) {
7971553Srgrimes		if (islower(*str))
7981553Srgrimes			*str = toupper(*str);
7991553Srgrimes		str++;
8001553Srgrimes	}
8011553Srgrimes	return (cp);
8021553Srgrimes}
803