mkmakefile.c revision 82393
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 82393 2001-08-27 05:11:53Z 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>
5269004Simp#include <sys/param.h>
5316073Sphk#include "y.tab.h"
541553Srgrimes#include "config.h"
5530638Speter#include "configvers.h"
561553Srgrimes
571553Srgrimes#define next_word(fp, wd) \
5861640Speter	{ char *word = get_word(fp); \
591553Srgrimes	  if (word == (char *)EOF) \
601553Srgrimes		return; \
611553Srgrimes	  else \
621553Srgrimes		wd = word; \
631553Srgrimes	}
641553Srgrimes#define next_quoted_word(fp, wd) \
6561640Speter	{ char *word = get_quoted_word(fp); \
661553Srgrimes	  if (word == (char *)EOF) \
671553Srgrimes		return; \
681553Srgrimes	  else \
691553Srgrimes		wd = word; \
701553Srgrimes	}
711553Srgrimes
7245744Speterstatic struct file_list *fcur;
731553Srgrimes
7461640Speterstatic char *tail(char *);
7561640Speterstatic void do_clean(FILE *);
7661640Speterstatic void do_rules(FILE *);
7769135Speterstatic void do_xxfiles(char *, FILE *);
7861640Speterstatic void do_objs(FILE *);
7961640Speterstatic void do_before_depend(FILE *);
8072684Speterstatic int opteq(const char *, const char *);
8161640Speterstatic void read_files(void);
8229451Scharnier
831553Srgrimes/*
841553Srgrimes * Lookup a file, by name.
851553Srgrimes */
8645744Speterstatic struct file_list *
8761640Speterfl_lookup(char *file)
881553Srgrimes{
8961640Speter	struct file_list *fp;
901553Srgrimes
911553Srgrimes	for (fp = ftab ; fp != 0; fp = fp->f_next) {
921553Srgrimes		if (eq(fp->f_fn, file))
931553Srgrimes			return (fp);
941553Srgrimes	}
951553Srgrimes	return (0);
961553Srgrimes}
971553Srgrimes
981553Srgrimes/*
991553Srgrimes * Make a new file list entry
1001553Srgrimes */
10145744Speterstatic struct file_list *
10261640Speternew_fent(void)
1031553Srgrimes{
10461640Speter	struct file_list *fp;
1051553Srgrimes
1061553Srgrimes	fp = (struct file_list *) malloc(sizeof *fp);
1071553Srgrimes	bzero(fp, sizeof *fp);
1081553Srgrimes	if (fcur == 0)
1091553Srgrimes		fcur = ftab = fp;
1101553Srgrimes	else
1111553Srgrimes		fcur->f_next = fp;
1121553Srgrimes	fcur = fp;
1131553Srgrimes	return (fp);
1141553Srgrimes}
1151553Srgrimes
1161553Srgrimes/*
1171553Srgrimes * Build the makefile from the skeleton
1181553Srgrimes */
11929451Scharniervoid
12061640Spetermakefile(void)
1211553Srgrimes{
1221553Srgrimes	FILE *ifp, *ofp;
1231553Srgrimes	char line[BUFSIZ];
1241553Srgrimes	struct opt *op;
12530638Speter	int versreq;
12661640Speter	char *s;
1271553Srgrimes
1281553Srgrimes	read_files();
12955614Speter	snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename);
1301553Srgrimes	ifp = fopen(line, "r");
13155614Speter	if (ifp == 0) {
13255614Speter		snprintf(line, sizeof(line), "Makefile.%s", machinename);
13355614Speter		ifp = fopen(line, "r");
13455614Speter	}
13529451Scharnier	if (ifp == 0)
13629451Scharnier		err(1, "%s", line);
13713400Speter	ofp = fopen(path("Makefile.new"), "w");
13829451Scharnier	if (ofp == 0)
13929451Scharnier		err(1, "%s", path("Makefile.new"));
14045744Speter	fprintf(ofp, "KERN_IDENT=%s\n", raisestr(ident));
14111711Sdg	fprintf(ofp, "IDENT=");
14220395Sbde	if (profiling)
1431553Srgrimes		fprintf(ofp, " -DGPROF");
14412772Speter
1451553Srgrimes	if (cputype == 0) {
1461553Srgrimes		printf("cpu type must be specified\n");
1471553Srgrimes		exit(1);
1481553Srgrimes	}
1491553Srgrimes	fprintf(ofp, "\n");
1501553Srgrimes	for (op = mkopt; op; op = op->op_next)
1511553Srgrimes		fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
1521553Srgrimes	if (debugging)
1531553Srgrimes		fprintf(ofp, "DEBUG=-g\n");
15420395Sbde	if (profiling) {
1551553Srgrimes		fprintf(ofp, "PROF=-pg\n");
15620395Sbde		fprintf(ofp, "PROFLEVEL=%d\n", profiling);
15720395Sbde	}
15852653Smarcel	if (*srcdir != '\0')
15952653Smarcel		fprintf(ofp,"S=%s\n", srcdir);
1601553Srgrimes	while (fgets(line, BUFSIZ, ifp) != 0) {
1611553Srgrimes		if (*line != '%') {
1621553Srgrimes			fprintf(ofp, "%s", line);
1631553Srgrimes			continue;
1641553Srgrimes		}
1655325Sgibbs		if (eq(line, "%BEFORE_DEPEND\n"))
1665325Sgibbs			do_before_depend(ofp);
1675325Sgibbs		else if (eq(line, "%OBJS\n"))
1681553Srgrimes			do_objs(ofp);
16969135Speter		else if (strncmp(line, "%FILES.", 7) == 0)
17069135Speter			do_xxfiles(line, ofp);
1711553Srgrimes		else if (eq(line, "%RULES\n"))
1721553Srgrimes			do_rules(ofp);
1736803Sgibbs		else if (eq(line, "%CLEAN\n"))
1746803Sgibbs			do_clean(ofp);
17530638Speter		else if (strncmp(line, "%VERSREQ=", sizeof("%VERSREQ=") - 1) == 0) {
17630638Speter			versreq = atoi(line + sizeof("%VERSREQ=") - 1);
17730638Speter			if (versreq != CONFIGVERS) {
17871363Speter				fprintf(stderr, "ERROR: version of config(8) does not match kernel!\n");
17930638Speter				fprintf(stderr, "config version = %d, ", CONFIGVERS);
18037129Sjkh				fprintf(stderr, "version required = %d\n\n", versreq);
18137129Sjkh				fprintf(stderr, "Make sure that /usr/src/usr.sbin/config is in sync\n");
18237129Sjkh				fprintf(stderr, "with your /usr/src/sys and install a new config binary\n");
18337129Sjkh				fprintf(stderr, "before trying this again.\n\n");
18439307Sgibbs				fprintf(stderr, "If running the new config fails check your config\n");
18539307Sgibbs				fprintf(stderr, "file against the GENERIC or LINT config files for\n");
18639307Sgibbs				fprintf(stderr, "changes in config syntax, or option/device naming\n");
18739307Sgibbs				fprintf(stderr, "conventions\n\n");
18871363Speter				exit(1);
18930638Speter			}
19030638Speter		} else
1911553Srgrimes			fprintf(stderr,
1921553Srgrimes			    "Unknown %% construct in generic makefile: %s",
1931553Srgrimes			    line);
1941553Srgrimes	}
1951553Srgrimes	(void) fclose(ifp);
1961553Srgrimes	(void) fclose(ofp);
19713400Speter	moveifchanged(path("Makefile.new"), path("Makefile"));
19834619Seivind
19961640Speter	if (hints) {
20061640Speter		ifp = fopen(hints, "r");
20161640Speter		if (ifp == NULL)
20261640Speter			err(1, "%s", hints);
20361640Speter	} else {
20461640Speter		ifp = NULL;
20561640Speter	}
20661640Speter	ofp = fopen(path("hints.c.new"), "w");
20761640Speter	if (ofp == NULL)
20861640Speter		err(1, "%s", path("hints.c.new"));
20965091Speter	fprintf(ofp, "int hintmode = %d;\n", hintmode);
21061640Speter	fprintf(ofp, "char static_hints[] = {\n");
21161640Speter	if (ifp) {
21261640Speter		while (fgets(line, BUFSIZ, ifp) != 0) {
21361640Speter			/* zap trailing CR and/or LF */
21461640Speter			while ((s = rindex(line, '\n')) != NULL)
21561640Speter				*s = '\0';
21661640Speter			while ((s = rindex(line, '\r')) != NULL)
21761640Speter				*s = '\0';
21861640Speter			/* remove # comments */
21961640Speter			s = index(line, '#');
22061640Speter			if (s)
22161640Speter				*s = '\0';
22261640Speter			/* remove any whitespace and " characters */
22361640Speter			s = line;
22461640Speter			while (*s) {
22561640Speter				if (*s == ' ' || *s == '\t' || *s == '"') {
22661640Speter					while (*s) {
22761640Speter						s[0] = s[1];
22861640Speter						s++;
22961640Speter					}
23061640Speter					/* start over */
23161640Speter					s = line;
23261640Speter					continue;
23361640Speter				}
23461640Speter				s++;
23561640Speter			}
23661640Speter			/* anything left? */
23761640Speter			if (*line == '\0')
23861652Speter				continue;
23961640Speter			fprintf(ofp, "\"%s\\0\"\n", line);
24061640Speter		}
24161640Speter	}
24261640Speter	fprintf(ofp, "\"\\0\"\n};\n");
24361640Speter	if (ifp)
24461640Speter		fclose(ifp);
24561640Speter	fclose(ofp);
24661640Speter	moveifchanged(path("hints.c.new"), path("hints.c"));
24782393Speter
24882393Speter	if (env) {
24982393Speter		ifp = fopen(env, "r");
25082393Speter		if (ifp == NULL)
25182393Speter			err(1, "%s", env);
25282393Speter	} else {
25382393Speter		ifp = NULL;
25482393Speter	}
25582393Speter	ofp = fopen(path("env.c.new"), "w");
25682393Speter	if (ofp == NULL)
25782393Speter		err(1, "%s", path("env.c.new"));
25882393Speter	fprintf(ofp, "int envmode = %d;\n", envmode);
25982393Speter	fprintf(ofp, "char static_env[] = {\n");
26082393Speter	if (ifp) {
26182393Speter		while (fgets(line, BUFSIZ, ifp) != 0) {
26282393Speter			/* zap trailing CR and/or LF */
26382393Speter			while ((s = rindex(line, '\n')) != NULL)
26482393Speter				*s = '\0';
26582393Speter			while ((s = rindex(line, '\r')) != NULL)
26682393Speter				*s = '\0';
26782393Speter			/* remove # comments */
26882393Speter			s = index(line, '#');
26982393Speter			if (s)
27082393Speter				*s = '\0';
27182393Speter			/* remove any whitespace and " characters */
27282393Speter			s = line;
27382393Speter			while (*s) {
27482393Speter				if (*s == ' ' || *s == '\t' || *s == '"') {
27582393Speter					while (*s) {
27682393Speter						s[0] = s[1];
27782393Speter						s++;
27882393Speter					}
27982393Speter					/* start over */
28082393Speter					s = line;
28182393Speter					continue;
28282393Speter				}
28382393Speter				s++;
28482393Speter			}
28582393Speter			/* anything left? */
28682393Speter			if (*line == '\0')
28782393Speter				continue;
28882393Speter			fprintf(ofp, "\"%s\\0\"\n", line);
28982393Speter		}
29082393Speter	}
29182393Speter	fprintf(ofp, "\"\\0\"\n};\n");
29282393Speter	if (ifp)
29382393Speter		fclose(ifp);
29482393Speter	fclose(ofp);
29582393Speter	moveifchanged(path("env.c.new"), path("env.c"));
2961553Srgrimes}
2971553Srgrimes
2981553Srgrimes/*
2991553Srgrimes * Read in the information about files used in making the system.
3001553Srgrimes * Store it in the ftab linked list.
3011553Srgrimes */
30245744Speterstatic void
30361640Speterread_files(void)
3041553Srgrimes{
3051553Srgrimes	FILE *fp;
30661640Speter	struct file_list *tp, *pf;
30761640Speter	struct device *dp;
30861640Speter	struct opt *op;
30973199Speter	char *wd, *this, *needs, *compilewith, *depends, *clean, *warning;
31069004Simp	char fname[MAXPATHLEN];
31173204Speter	int nreqs, first = 1, isdup, std, filetype,
31261523Speter	    imp_rule, no_obj, needcount, before_depend, mandatory;
3131553Srgrimes
3141553Srgrimes	ftab = 0;
31555614Speter	if (ident == NULL) {
31655614Speter		printf("no ident line specified\n");
31755614Speter		exit(1);
31855614Speter	}
31969004Simp	(void) snprintf(fname, sizeof(fname), "../../conf/files");
3201553Srgrimesopenit:
3211553Srgrimes	fp = fopen(fname, "r");
32229451Scharnier	if (fp == 0)
32329451Scharnier		err(1, "%s", fname);
3241553Srgrimesnext:
3251553Srgrimes	/*
32661640Speter	 * filename    [ standard | mandatory | optional | count ]
32748525Speter	 *	[ dev* | profiling-routine ] [ no-obj ]
3288857Srgrimes	 *	[ compile-with "compile rule" [no-implicit-rule] ]
3296803Sgibbs	 *      [ dependency "dependency-list"] [ before-depend ]
33054490Speter	 *	[ clean "file-list"] [ warning "text warning" ]
3311553Srgrimes	 */
3321553Srgrimes	wd = get_word(fp);
3331553Srgrimes	if (wd == (char *)EOF) {
3341553Srgrimes		(void) fclose(fp);
3351553Srgrimes		if (first == 1) {
33655614Speter			first++;
33769004Simp			(void) snprintf(fname, sizeof(fname),
33869004Simp			    "../../conf/files.%s", machinename);
33955614Speter			fp = fopen(fname, "r");
34055614Speter			if (fp != 0)
34155614Speter				goto next;
34269004Simp			(void) snprintf(fname, sizeof(fname),
34369004Simp			    "files.%s", machinename);
3441553Srgrimes			goto openit;
3451553Srgrimes		}
3461553Srgrimes		return;
3471553Srgrimes	}
3481553Srgrimes	if (wd == 0)
3491553Srgrimes		goto next;
35052098Speter	if (wd[0] == '#')
3511566Srgrimes	{
35252098Speter		while (((wd = get_word(fp)) != (char *)EOF) && wd)
35352098Speter			;
3541566Srgrimes		goto next;
3551566Srgrimes	}
3561553Srgrimes	this = ns(wd);
3571553Srgrimes	next_word(fp, wd);
3581553Srgrimes	if (wd == 0) {
3591553Srgrimes		printf("%s: No type for %s.\n",
3601553Srgrimes		    fname, this);
3611553Srgrimes		exit(1);
3621553Srgrimes	}
3631553Srgrimes	if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags))
36461523Speter		isdup = ISDUP;
3651553Srgrimes	else
3661553Srgrimes		isdup = 0;
3671553Srgrimes	tp = 0;
3681553Srgrimes	nreqs = 0;
36973199Speter	compilewith = 0;
3704571Sgibbs	depends = 0;
3716803Sgibbs	clean = 0;
37272684Speter	warning = 0;
3731553Srgrimes	needs = 0;
37430796Sjoerg	std = mandatory = 0;
3754571Sgibbs	imp_rule = 0;
3764571Sgibbs	no_obj = 0;
37761523Speter	needcount = 0;
3785325Sgibbs	before_depend = 0;
3791553Srgrimes	filetype = NORMAL;
38061523Speter	if (eq(wd, "standard")) {
3811553Srgrimes		std = 1;
38230796Sjoerg	/*
38330796Sjoerg	 * If an entry is marked "mandatory", config will abort if it's
38430796Sjoerg	 * not called by a configuration line in the config file.  Apart
38530796Sjoerg	 * from this, the device is handled like one marked "optional".
38630796Sjoerg	 */
38761523Speter	} else if (eq(wd, "mandatory")) {
38830796Sjoerg		mandatory = 1;
38961523Speter	} else if (eq(wd, "count")) {
39061523Speter		needcount = 1;
39161523Speter	} else if (!eq(wd, "optional")) {
39261523Speter		printf("%s: %s must be count, optional, mandatory or standard\n",
39330796Sjoerg		       fname, this);
3941553Srgrimes		exit(1);
3951553Srgrimes	}
3961553Srgrimesnextparam:
3971553Srgrimes	next_word(fp, wd);
3981553Srgrimes	if (wd == 0)
3991553Srgrimes		goto doneparam;
4004571Sgibbs	if (eq(wd, "no-obj")) {
4014571Sgibbs		no_obj++;
4024571Sgibbs		goto nextparam;
4034571Sgibbs	}
4044571Sgibbs	if (eq(wd, "no-implicit-rule")) {
40573199Speter		if (compilewith == 0) {
4064571Sgibbs			printf("%s: alternate rule required when "
4074571Sgibbs			       "\"no-implicit-rule\" is specified.\n",
4084571Sgibbs			       fname);
4094571Sgibbs		}
4104571Sgibbs		imp_rule++;
4114571Sgibbs		goto nextparam;
4124571Sgibbs	}
4135325Sgibbs	if (eq(wd, "before-depend")) {
4145325Sgibbs		before_depend++;
4155325Sgibbs		goto nextparam;
4165325Sgibbs	}
4176803Sgibbs	if (eq(wd, "dependency")) {
4184571Sgibbs		next_quoted_word(fp, wd);
4194571Sgibbs		if (wd == 0) {
4204571Sgibbs			printf("%s: %s missing compile command string.\n",
4218520Srgrimes			       fname, this);
4224571Sgibbs			exit(1);
4234571Sgibbs		}
4244571Sgibbs		depends = ns(wd);
4254571Sgibbs		goto nextparam;
4264571Sgibbs	}
4276803Sgibbs	if (eq(wd, "clean")) {
4285325Sgibbs		next_quoted_word(fp, wd);
4295325Sgibbs		if (wd == 0) {
4306803Sgibbs			printf("%s: %s missing clean file list.\n",
4318520Srgrimes			       fname, this);
4325325Sgibbs			exit(1);
4335325Sgibbs		}
4346803Sgibbs		clean = ns(wd);
4355325Sgibbs		goto nextparam;
4365325Sgibbs	}
4371553Srgrimes	if (eq(wd, "compile-with")) {
4381553Srgrimes		next_quoted_word(fp, wd);
4391553Srgrimes		if (wd == 0) {
4401553Srgrimes			printf("%s: %s missing compile command string.\n",
4418520Srgrimes			       fname, this);
4421553Srgrimes			exit(1);
4431553Srgrimes		}
44473199Speter		compilewith = ns(wd);
4451553Srgrimes		goto nextparam;
4461553Srgrimes	}
44754490Speter	if (eq(wd, "warning")) {
44854490Speter		next_quoted_word(fp, wd);
44954490Speter		if (wd == 0) {
45054490Speter			printf("%s: %s missing warning text string.\n",
45154490Speter				fname, this);
45254490Speter			exit(1);
45354490Speter		}
45472684Speter		warning = ns(wd);
45554490Speter		goto nextparam;
45654490Speter	}
4571553Srgrimes	nreqs++;
45838782Snsouch	if (eq(wd, "local")) {
45938782Snsouch		filetype = LOCAL;
46038782Snsouch		goto nextparam;
46138782Snsouch	}
46238782Snsouch	if (eq(wd, "no-depend")) {
46338782Snsouch		filetype = NODEPEND;
46438782Snsouch		goto nextparam;
46538782Snsouch	}
4661553Srgrimes	if (eq(wd, "profiling-routine")) {
4671553Srgrimes		filetype = PROFILING;
4681553Srgrimes		goto nextparam;
4691553Srgrimes	}
4701553Srgrimes	if (needs == 0 && nreqs == 1)
4711553Srgrimes		needs = ns(wd);
4721553Srgrimes	if (isdup)
4731553Srgrimes		goto invis;
47473193Speter	for (dp = dtab; dp != 0; dp = dp->d_next)
4751553Srgrimes		if (eq(dp->d_name, wd)) {
47671879Speter			if (std && dp->d_count <= 0)
47752098Speter				dp->d_count = 1;
4781553Srgrimes			goto nextparam;
4791553Srgrimes		}
48030796Sjoerg	if (mandatory) {
48130796Sjoerg		printf("%s: mandatory device \"%s\" not found\n",
48230796Sjoerg		       fname, wd);
48330796Sjoerg		exit(1);
48430796Sjoerg	}
4851553Srgrimes	if (std) {
48673193Speter		printf("standard entry %s has a device keyword - %s!\n",
48773193Speter		       this, wd);
48873193Speter		exit(1);
4891553Srgrimes	}
4901553Srgrimes	for (op = opt; op != 0; op = op->op_next)
4911553Srgrimes		if (op->op_value == 0 && opteq(op->op_name, wd)) {
4921553Srgrimes			if (nreqs == 1) {
4931553Srgrimes				free(needs);
4941553Srgrimes				needs = 0;
4951553Srgrimes			}
4961553Srgrimes			goto nextparam;
4971553Srgrimes		}
4981553Srgrimesinvis:
4991553Srgrimes	while ((wd = get_word(fp)) != 0)
5001553Srgrimes		;
5011553Srgrimes	if (tp == 0)
5021553Srgrimes		tp = new_fent();
5031553Srgrimes	tp->f_fn = this;
5041553Srgrimes	tp->f_type = INVISIBLE;
5051553Srgrimes	tp->f_needs = needs;
50661523Speter	tp->f_flags |= isdup;
50761523Speter	if (needcount)
50861523Speter		tp->f_flags |= NEED_COUNT;
50973199Speter	tp->f_compilewith = compilewith;
5104571Sgibbs	tp->f_depends = depends;
5116803Sgibbs	tp->f_clean = clean;
51272684Speter	tp->f_warn = warning;
5131553Srgrimes	goto next;
5141553Srgrimes
5151553Srgrimesdoneparam:
5161553Srgrimes	if (std == 0 && nreqs == 0) {
5171553Srgrimes		printf("%s: what is %s optional on?\n",
5181553Srgrimes		    fname, this);
5191553Srgrimes		exit(1);
5201553Srgrimes	}
5211553Srgrimes
5221553Srgrimes	if (wd) {
5231553Srgrimes		printf("%s: syntax error describing %s\n",
5241553Srgrimes		    fname, this);
5251553Srgrimes		exit(1);
5261553Srgrimes	}
5271553Srgrimes	if (filetype == PROFILING && profiling == 0)
5281553Srgrimes		goto next;
5291553Srgrimes	if (tp == 0)
5301553Srgrimes		tp = new_fent();
5311553Srgrimes	tp->f_fn = this;
5321553Srgrimes	tp->f_type = filetype;
53361523Speter	tp->f_flags &= ~ISDUP;
5344571Sgibbs	if (imp_rule)
5354571Sgibbs		tp->f_flags |= NO_IMPLCT_RULE;
5364571Sgibbs	if (no_obj)
5374571Sgibbs		tp->f_flags |= NO_OBJ;
5385325Sgibbs	if (before_depend)
5395325Sgibbs		tp->f_flags |= BEFORE_DEPEND;
54061523Speter	if (needcount)
54161523Speter		tp->f_flags |= NEED_COUNT;
5421553Srgrimes	tp->f_needs = needs;
54373199Speter	tp->f_compilewith = compilewith;
5444571Sgibbs	tp->f_depends = depends;
5456803Sgibbs	tp->f_clean = clean;
54672684Speter	tp->f_warn = warning;
5471553Srgrimes	if (pf && pf->f_type == INVISIBLE)
54861523Speter		pf->f_flags |= ISDUP;		/* mark as duplicate */
5491553Srgrimes	goto next;
5501553Srgrimes}
5511553Srgrimes
55245744Speterstatic int
55372684Speteropteq(const char *cp, const char *dp)
5541553Srgrimes{
5551553Srgrimes	char c, d;
5561553Srgrimes
5571553Srgrimes	for (; ; cp++, dp++) {
5581553Srgrimes		if (*cp != *dp) {
5591553Srgrimes			c = isupper(*cp) ? tolower(*cp) : *cp;
5601553Srgrimes			d = isupper(*dp) ? tolower(*dp) : *dp;
5611553Srgrimes			if (c != d)
5621553Srgrimes				return (0);
5631553Srgrimes		}
5641553Srgrimes		if (*cp == 0)
5651553Srgrimes			return (1);
5661553Srgrimes	}
5671553Srgrimes}
5681553Srgrimes
56945744Speterstatic void
57061640Speterdo_before_depend(FILE *fp)
5715325Sgibbs{
57261640Speter	struct file_list *tp;
57361640Speter	int lpos, len;
5745325Sgibbs
5755325Sgibbs	fputs("BEFORE_DEPEND=", fp);
5765325Sgibbs	lpos = 15;
5775325Sgibbs	for (tp = ftab; tp; tp = tp->f_next)
5785325Sgibbs		if (tp->f_flags & BEFORE_DEPEND) {
5795325Sgibbs			len = strlen(tp->f_fn);
5805325Sgibbs			if ((len = 3 + len) + lpos > 72) {
5815325Sgibbs				lpos = 8;
5825325Sgibbs				fputs("\\\n\t", fp);
5835325Sgibbs			}
5845325Sgibbs			if (tp->f_flags & NO_IMPLCT_RULE)
5855325Sgibbs				fprintf(fp, "%s ", tp->f_fn);
5865325Sgibbs			else
5875325Sgibbs				fprintf(fp, "$S/%s ", tp->f_fn);
5885325Sgibbs			lpos += len + 1;
5895325Sgibbs		}
5905325Sgibbs	if (lpos != 8)
5915325Sgibbs		putc('\n', fp);
5925325Sgibbs}
5935325Sgibbs
59445744Speterstatic void
59561640Speterdo_objs(FILE *fp)
5961553Srgrimes{
59761640Speter	struct file_list *tp;
59861640Speter	int lpos, len;
59961640Speter	char *cp, och, *sp;
6001553Srgrimes
6011553Srgrimes	fprintf(fp, "OBJS=");
6021553Srgrimes	lpos = 6;
6031553Srgrimes	for (tp = ftab; tp != 0; tp = tp->f_next) {
6044571Sgibbs		if (tp->f_type == INVISIBLE || tp->f_flags & NO_OBJ)
6051553Srgrimes			continue;
6061553Srgrimes		sp = tail(tp->f_fn);
6071553Srgrimes		cp = sp + (len = strlen(sp)) - 1;
6081553Srgrimes		och = *cp;
6091553Srgrimes		*cp = 'o';
6101553Srgrimes		if (len + lpos > 72) {
6111553Srgrimes			lpos = 8;
6121553Srgrimes			fprintf(fp, "\\\n\t");
6131553Srgrimes		}
6141553Srgrimes		fprintf(fp, "%s ", sp);
6151553Srgrimes		lpos += len + 1;
6161553Srgrimes		*cp = och;
6171553Srgrimes	}
6181553Srgrimes	if (lpos != 8)
6191553Srgrimes		putc('\n', fp);
6201553Srgrimes}
6211553Srgrimes
62245744Speterstatic void
62369135Speterdo_xxfiles(char *tag, FILE *fp)
6241553Srgrimes{
62561640Speter	struct file_list *tp;
62669135Speter	int lpos, len, slen;
62769135Speter	char *suff, *SUFF;
6281553Srgrimes
62969135Speter	if (tag[strlen(tag) - 1] == '\n')
63069135Speter		tag[strlen(tag) - 1] = '\0';
63169135Speter
63269135Speter	suff = ns(tag + 7);
63369135Speter	SUFF = ns(suff);
63469135Speter	raisestr(SUFF);
63569135Speter	slen = strlen(suff);
63669135Speter
63769135Speter	fprintf(fp, "%sFILES=", SUFF);
6381553Srgrimes	lpos = 8;
6391553Srgrimes	for (tp = ftab; tp; tp = tp->f_next)
64038782Snsouch		if (tp->f_type != INVISIBLE && tp->f_type != NODEPEND) {
6411553Srgrimes			len = strlen(tp->f_fn);
64269135Speter			if (tp->f_fn[len - slen - 1] != '.')
6431553Srgrimes				continue;
64469135Speter			if (strcasecmp(&tp->f_fn[len - slen], suff) != 0)
64569135Speter				continue;
6461553Srgrimes			if ((len = 3 + len) + lpos > 72) {
6471553Srgrimes				lpos = 8;
6481553Srgrimes				fputs("\\\n\t", fp);
6491553Srgrimes			}
65038782Snsouch			if (tp->f_type != LOCAL)
65138782Snsouch				fprintf(fp, "$S/%s ", tp->f_fn);
65238782Snsouch			else
65338782Snsouch				fprintf(fp, "%s ", tp->f_fn);
6541553Srgrimes			lpos += len + 1;
6551553Srgrimes		}
6561553Srgrimes	if (lpos != 8)
6571553Srgrimes		putc('\n', fp);
6581553Srgrimes}
6591553Srgrimes
66045744Speterstatic char *
66161640Spetertail(char *fn)
6621553Srgrimes{
66361640Speter	char *cp;
6641553Srgrimes
6651553Srgrimes	cp = rindex(fn, '/');
6661553Srgrimes	if (cp == 0)
6671553Srgrimes		return (fn);
6681553Srgrimes	return (cp+1);
6691553Srgrimes}
6701553Srgrimes
6711553Srgrimes/*
6721553Srgrimes * Create the makerules for each file
6731553Srgrimes * which is part of the system.
6741553Srgrimes */
67545744Speterstatic void
67661640Speterdo_rules(FILE *f)
6771553Srgrimes{
67861640Speter	char *cp, *np, och, *tp;
67961640Speter	struct file_list *ftp;
68073199Speter	char *compilewith;
6811553Srgrimes
6821553Srgrimes	for (ftp = ftab; ftp != 0; ftp = ftp->f_next) {
6831553Srgrimes		if (ftp->f_type == INVISIBLE)
6841553Srgrimes			continue;
68554490Speter		if (ftp->f_warn)
68654490Speter			printf("WARNING: %s\n", ftp->f_warn);
6871553Srgrimes		cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
6881553Srgrimes		och = *cp;
6894571Sgibbs		if (ftp->f_flags & NO_IMPLCT_RULE) {
6904571Sgibbs			if (ftp->f_depends)
69152098Speter				fprintf(f, "%s: %s\n", np, ftp->f_depends);
6924571Sgibbs			else
69352098Speter				fprintf(f, "%s: \n", np);
6941553Srgrimes		}
6954571Sgibbs		else {
6964571Sgibbs			*cp = '\0';
6974571Sgibbs			if (och == 'o') {
6988857Srgrimes				fprintf(f, "%so:\n\t-cp $S/%so .\n\n",
6994571Sgibbs					tail(np), np);
7004571Sgibbs				continue;
7014571Sgibbs			}
7024571Sgibbs			if (ftp->f_depends)
7038857Srgrimes				fprintf(f, "%so: $S/%s%c %s\n", tail(np),
7044571Sgibbs					np, och, ftp->f_depends);
7054571Sgibbs			else
7068857Srgrimes				fprintf(f, "%so: $S/%s%c\n", tail(np),
7074571Sgibbs					np, och);
7084571Sgibbs		}
7091553Srgrimes		tp = tail(np);
71073199Speter		compilewith = ftp->f_compilewith;
71173199Speter		if (compilewith == 0) {
71272684Speter			const char *ftype = NULL;
7131553Srgrimes			static char cmd[128];
7141553Srgrimes
7151553Srgrimes			switch (ftp->f_type) {
7161553Srgrimes
7171553Srgrimes			case NORMAL:
7181553Srgrimes				ftype = "NORMAL";
7191553Srgrimes				break;
7201553Srgrimes
7211553Srgrimes			case PROFILING:
7221553Srgrimes				if (!profiling)
7231553Srgrimes					continue;
7241553Srgrimes				ftype = "PROFILE";
7251553Srgrimes				break;
7261553Srgrimes
7271553Srgrimes			default:
7281553Srgrimes				printf("config: don't know rules for %s\n", np);
7291553Srgrimes				break;
7301553Srgrimes			}
73173204Speter			snprintf(cmd, sizeof(cmd), "${%s_%c}", ftype,
73273204Speter			    toupper(och));
73373199Speter			compilewith = cmd;
7341553Srgrimes		}
7351553Srgrimes		*cp = och;
73673199Speter		fprintf(f, "\t%s\n\n", compilewith);
7371553Srgrimes	}
7381553Srgrimes}
7391553Srgrimes
74045744Speterstatic void
74161640Speterdo_clean(FILE *fp)
7426803Sgibbs{
74361640Speter	struct file_list *tp;
74461640Speter	int lpos, len;
7456803Sgibbs
7466803Sgibbs	fputs("CLEAN=", fp);
7476803Sgibbs	lpos = 7;
7486803Sgibbs	for (tp = ftab; tp; tp = tp->f_next)
7496803Sgibbs		if (tp->f_clean) {
7506803Sgibbs			len = strlen(tp->f_clean);
7516803Sgibbs			if (len + lpos > 72) {
7526803Sgibbs				lpos = 8;
7536803Sgibbs				fputs("\\\n\t", fp);
7546803Sgibbs			}
7556803Sgibbs			fprintf(fp, "%s ", tp->f_clean);
7566803Sgibbs			lpos += len + 1;
7576803Sgibbs		}
7586803Sgibbs	if (lpos != 8)
7596803Sgibbs		putc('\n', fp);
7606803Sgibbs}
7616803Sgibbs
7621553Srgrimeschar *
76361640Speterraisestr(char *str)
7641553Srgrimes{
76561640Speter	char *cp = str;
7661553Srgrimes
7671553Srgrimes	while (*str) {
7681553Srgrimes		if (islower(*str))
7691553Srgrimes			*str = toupper(*str);
7701553Srgrimes		str++;
7711553Srgrimes	}
7721553Srgrimes	return (cp);
7731553Srgrimes}
774