mkmakefile.c revision 214654
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 * 4. Neither the name of the University nor the names of its contributors
141553Srgrimes *    may be used to endorse or promote products derived from this software
151553Srgrimes *    without specific prior written permission.
161553Srgrimes *
171553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201553Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271553Srgrimes * SUCH DAMAGE.
281553Srgrimes */
291553Srgrimes
301553Srgrimes#ifndef lint
3129451Scharnier#if 0
321553Srgrimesstatic char sccsid[] = "@(#)mkmakefile.c	8.1 (Berkeley) 6/6/93";
3329451Scharnier#endif
3429451Scharnierstatic const char rcsid[] =
3550479Speter  "$FreeBSD: head/usr.sbin/config/mkmakefile.c 214654 2010-11-02 05:27:05Z obrien $";
361553Srgrimes#endif /* not lint */
371553Srgrimes
381553Srgrimes/*
391553Srgrimes * Build the makefile for the system, from
401553Srgrimes * the information in the files files and the
411553Srgrimes * additional files for the machine being compiled to.
421553Srgrimes */
431553Srgrimes
4429451Scharnier#include <ctype.h>
4529451Scharnier#include <err.h>
461553Srgrimes#include <stdio.h>
4720458Sjoerg#include <string.h>
4869004Simp#include <sys/param.h>
4916073Sphk#include "y.tab.h"
501553Srgrimes#include "config.h"
5130638Speter#include "configvers.h"
521553Srgrimes
531553Srgrimes#define next_word(fp, wd) \
5461640Speter	{ char *word = get_word(fp); \
551553Srgrimes	  if (word == (char *)EOF) \
561553Srgrimes		return; \
571553Srgrimes	  else \
581553Srgrimes		wd = word; \
591553Srgrimes	}
601553Srgrimes#define next_quoted_word(fp, wd) \
6161640Speter	{ char *word = get_quoted_word(fp); \
621553Srgrimes	  if (word == (char *)EOF) \
631553Srgrimes		return; \
641553Srgrimes	  else \
651553Srgrimes		wd = word; \
661553Srgrimes	}
671553Srgrimes
6861640Speterstatic char *tail(char *);
6961640Speterstatic void do_clean(FILE *);
7061640Speterstatic void do_rules(FILE *);
7169135Speterstatic void do_xxfiles(char *, FILE *);
7261640Speterstatic void do_objs(FILE *);
7361640Speterstatic void do_before_depend(FILE *);
7472684Speterstatic int opteq(const char *, const char *);
7561640Speterstatic void read_files(void);
7629451Scharnier
771553Srgrimes/*
781553Srgrimes * Lookup a file, by name.
791553Srgrimes */
8045744Speterstatic struct file_list *
8161640Speterfl_lookup(char *file)
821553Srgrimes{
8361640Speter	struct file_list *fp;
841553Srgrimes
85110895Sru	STAILQ_FOREACH(fp, &ftab, f_next) {
861553Srgrimes		if (eq(fp->f_fn, file))
871553Srgrimes			return (fp);
881553Srgrimes	}
891553Srgrimes	return (0);
901553Srgrimes}
911553Srgrimes
921553Srgrimes/*
931553Srgrimes * Make a new file list entry
941553Srgrimes */
9545744Speterstatic struct file_list *
9661640Speternew_fent(void)
971553Srgrimes{
9861640Speter	struct file_list *fp;
991553Srgrimes
100159362Sdelphij	fp = (struct file_list *) calloc(1, sizeof *fp);
101205880Sru	if (fp == NULL)
102205880Sru		err(EXIT_FAILURE, "calloc");
103110895Sru	STAILQ_INSERT_TAIL(&ftab, fp, f_next);
1041553Srgrimes	return (fp);
1051553Srgrimes}
1061553Srgrimes
1071553Srgrimes/*
108207260Simp * Open the correct Makefile and return it, or error out.
1091553Srgrimes */
110207260SimpFILE *
111207260Simpopen_makefile_template(void)
1121553Srgrimes{
113207260Simp	FILE *ifp;
1141553Srgrimes	char line[BUFSIZ];
1151553Srgrimes
11655614Speter	snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename);
1171553Srgrimes	ifp = fopen(line, "r");
11855614Speter	if (ifp == 0) {
11955614Speter		snprintf(line, sizeof(line), "Makefile.%s", machinename);
12055614Speter		ifp = fopen(line, "r");
12155614Speter	}
12229451Scharnier	if (ifp == 0)
12329451Scharnier		err(1, "%s", line);
124207260Simp	return (ifp);
125207260Simp}
12612772Speter
127207260Simp/*
128207260Simp * Build the makefile from the skeleton
129207260Simp */
130207260Simpvoid
131207260Simpmakefile(void)
132207260Simp{
133207260Simp	FILE *ifp, *ofp;
134207260Simp	char line[BUFSIZ];
135207260Simp	struct opt *op, *t;
136207260Simp
137207260Simp	read_files();
138207260Simp	ifp = open_makefile_template();
13999923Sbde	ofp = fopen(path("Makefile.new"), "w");
14099923Sbde	if (ofp == 0)
14199923Sbde		err(1, "%s", path("Makefile.new"));
142113951Sdes	fprintf(ofp, "KERN_IDENT=%s\n", ident);
143185186Sthompsa	SLIST_FOREACH_SAFE(op, &mkopt, op_next, t) {
144185186Sthompsa		fprintf(ofp, "%s=%s", op->op_name, op->op_value);
145185186Sthompsa		while ((op = SLIST_NEXT(op, op_append)) != NULL)
146185186Sthompsa			fprintf(ofp, " %s", op->op_value);
147185186Sthompsa		fprintf(ofp, "\n");
148185186Sthompsa	}
1491553Srgrimes	if (debugging)
1501553Srgrimes		fprintf(ofp, "DEBUG=-g\n");
15199923Sbde	if (profiling)
15220395Sbde		fprintf(ofp, "PROFLEVEL=%d\n", profiling);
15352653Smarcel	if (*srcdir != '\0')
15452653Smarcel		fprintf(ofp,"S=%s\n", srcdir);
1551553Srgrimes	while (fgets(line, BUFSIZ, ifp) != 0) {
1561553Srgrimes		if (*line != '%') {
1571553Srgrimes			fprintf(ofp, "%s", line);
1581553Srgrimes			continue;
1591553Srgrimes		}
1605325Sgibbs		if (eq(line, "%BEFORE_DEPEND\n"))
1615325Sgibbs			do_before_depend(ofp);
1625325Sgibbs		else if (eq(line, "%OBJS\n"))
1631553Srgrimes			do_objs(ofp);
16469135Speter		else if (strncmp(line, "%FILES.", 7) == 0)
16569135Speter			do_xxfiles(line, ofp);
1661553Srgrimes		else if (eq(line, "%RULES\n"))
1671553Srgrimes			do_rules(ofp);
1686803Sgibbs		else if (eq(line, "%CLEAN\n"))
1696803Sgibbs			do_clean(ofp);
170207260Simp		else if (strncmp(line, "%VERSREQ=", 9) == 0)
171207260Simp			line[0] = '\0'; /* handled elsewhere */
172207260Simp		else
1731553Srgrimes			fprintf(stderr,
1741553Srgrimes			    "Unknown %% construct in generic makefile: %s",
1751553Srgrimes			    line);
1761553Srgrimes	}
1771553Srgrimes	(void) fclose(ifp);
1781553Srgrimes	(void) fclose(ofp);
17913400Speter	moveifchanged(path("Makefile.new"), path("Makefile"));
180153888Sru}
18134619Seivind
182153888Sru/*
183153888Sru * Build hints.c from the skeleton
184153888Sru */
185153888Sruvoid
186153888Srumakehints(void)
187153888Sru{
188163640Simp	FILE *ifp, *ofp;
189153888Sru	char line[BUFSIZ];
190153888Sru	char *s;
191163638Simp	struct hint *hint;
192153888Sru
19361640Speter	ofp = fopen(path("hints.c.new"), "w");
19461640Speter	if (ofp == NULL)
19561640Speter		err(1, "%s", path("hints.c.new"));
19683594Speter	fprintf(ofp, "#include <sys/types.h>\n");
19783594Speter	fprintf(ofp, "#include <sys/systm.h>\n");
19883594Speter	fprintf(ofp, "\n");
19965091Speter	fprintf(ofp, "int hintmode = %d;\n", hintmode);
20061640Speter	fprintf(ofp, "char static_hints[] = {\n");
201163638Simp	STAILQ_FOREACH(hint, &hints, hint_next) {
202163638Simp		ifp = fopen(hint->hint_name, "r");
203163638Simp		if (ifp == NULL)
204163638Simp			err(1, "%s", hint->hint_name);
20561640Speter		while (fgets(line, BUFSIZ, ifp) != 0) {
20661640Speter			/* zap trailing CR and/or LF */
20761640Speter			while ((s = rindex(line, '\n')) != NULL)
20861640Speter				*s = '\0';
20961640Speter			while ((s = rindex(line, '\r')) != NULL)
21061640Speter				*s = '\0';
21161640Speter			/* remove # comments */
21261640Speter			s = index(line, '#');
21361640Speter			if (s)
21461640Speter				*s = '\0';
21561640Speter			/* remove any whitespace and " characters */
21661640Speter			s = line;
21761640Speter			while (*s) {
21861640Speter				if (*s == ' ' || *s == '\t' || *s == '"') {
21961640Speter					while (*s) {
22061640Speter						s[0] = s[1];
22161640Speter						s++;
22261640Speter					}
22361640Speter					/* start over */
22461640Speter					s = line;
22561640Speter					continue;
22661640Speter				}
22761640Speter				s++;
22861640Speter			}
22961640Speter			/* anything left? */
23061640Speter			if (*line == '\0')
23161652Speter				continue;
23261640Speter			fprintf(ofp, "\"%s\\0\"\n", line);
23361640Speter		}
234163640Simp		fclose(ifp);
23561640Speter	}
23661640Speter	fprintf(ofp, "\"\\0\"\n};\n");
23761640Speter	fclose(ofp);
23861640Speter	moveifchanged(path("hints.c.new"), path("hints.c"));
239153888Sru}
24082393Speter
241153888Sru/*
242153888Sru * Build env.c from the skeleton
243153888Sru */
244153888Sruvoid
245153888Srumakeenv(void)
246153888Sru{
247153888Sru	FILE *ifp, *ofp;
248153888Sru	char line[BUFSIZ];
249153888Sru	char *s;
250153888Sru
25182393Speter	if (env) {
25282393Speter		ifp = fopen(env, "r");
25382393Speter		if (ifp == NULL)
25482393Speter			err(1, "%s", env);
25582393Speter	} else {
25682393Speter		ifp = NULL;
25782393Speter	}
25882393Speter	ofp = fopen(path("env.c.new"), "w");
25982393Speter	if (ofp == NULL)
26082393Speter		err(1, "%s", path("env.c.new"));
26183594Speter	fprintf(ofp, "#include <sys/types.h>\n");
26283594Speter	fprintf(ofp, "#include <sys/systm.h>\n");
26383594Speter	fprintf(ofp, "\n");
26482393Speter	fprintf(ofp, "int envmode = %d;\n", envmode);
26582393Speter	fprintf(ofp, "char static_env[] = {\n");
26682393Speter	if (ifp) {
26782393Speter		while (fgets(line, BUFSIZ, ifp) != 0) {
26882393Speter			/* zap trailing CR and/or LF */
26982393Speter			while ((s = rindex(line, '\n')) != NULL)
27082393Speter				*s = '\0';
27182393Speter			while ((s = rindex(line, '\r')) != NULL)
27282393Speter				*s = '\0';
27382393Speter			/* remove # comments */
27482393Speter			s = index(line, '#');
27582393Speter			if (s)
27682393Speter				*s = '\0';
27782393Speter			/* remove any whitespace and " characters */
27882393Speter			s = line;
27982393Speter			while (*s) {
28082393Speter				if (*s == ' ' || *s == '\t' || *s == '"') {
28182393Speter					while (*s) {
28282393Speter						s[0] = s[1];
28382393Speter						s++;
28482393Speter					}
28582393Speter					/* start over */
28682393Speter					s = line;
28782393Speter					continue;
28882393Speter				}
28982393Speter				s++;
29082393Speter			}
29182393Speter			/* anything left? */
29282393Speter			if (*line == '\0')
29382393Speter				continue;
29482393Speter			fprintf(ofp, "\"%s\\0\"\n", line);
29582393Speter		}
29682393Speter	}
29782393Speter	fprintf(ofp, "\"\\0\"\n};\n");
29882393Speter	if (ifp)
29982393Speter		fclose(ifp);
30082393Speter	fclose(ofp);
30182393Speter	moveifchanged(path("env.c.new"), path("env.c"));
3021553Srgrimes}
3031553Srgrimes
304129119Scognetstatic void
305129073Scognetread_file(char *fname)
3061553Srgrimes{
307162936Sru	char ifname[MAXPATHLEN];
3081553Srgrimes	FILE *fp;
309152811Sru	struct file_list *tp;
31061640Speter	struct device *dp;
31161640Speter	struct opt *op;
312152811Sru	char *wd, *this, *compilewith, *depends, *clean, *warning;
313153889Sru	int compile, match, nreqs, std, filetype,
314134542Speter	    imp_rule, no_obj, before_depend, mandatory, nowerror;
3151553Srgrimes
3161553Srgrimes	fp = fopen(fname, "r");
31729451Scharnier	if (fp == 0)
31829451Scharnier		err(1, "%s", fname);
3191553Srgrimesnext:
3201553Srgrimes	/*
321162936Sru	 * include "filename"
322134542Speter	 * filename    [ standard | mandatory | optional ]
323152862Sru	 *	[ dev* [ | dev* ... ] | profiling-routine ] [ no-obj ]
3248857Srgrimes	 *	[ compile-with "compile rule" [no-implicit-rule] ]
3256803Sgibbs	 *      [ dependency "dependency-list"] [ before-depend ]
32654490Speter	 *	[ clean "file-list"] [ warning "text warning" ]
3271553Srgrimes	 */
3281553Srgrimes	wd = get_word(fp);
3291553Srgrimes	if (wd == (char *)EOF) {
3301553Srgrimes		(void) fclose(fp);
3311553Srgrimes		return;
332129073Scognet	}
3331553Srgrimes	if (wd == 0)
3341553Srgrimes		goto next;
33552098Speter	if (wd[0] == '#')
3361566Srgrimes	{
33752098Speter		while (((wd = get_word(fp)) != (char *)EOF) && wd)
33852098Speter			;
3391566Srgrimes		goto next;
3401566Srgrimes	}
341162936Sru	if (eq(wd, "include")) {
342162936Sru		next_quoted_word(fp, wd);
343162936Sru		if (wd == 0) {
344210144Simp			fprintf(stderr, "%s: missing include filename.\n",
345210144Simp			    fname);
346162936Sru			exit(1);
347162936Sru		}
348162936Sru		(void) snprintf(ifname, sizeof(ifname), "../../%s", wd);
349162936Sru		read_file(ifname);
350162936Sru		while (((wd = get_word(fp)) != (char *)EOF) && wd)
351162936Sru			;
352162936Sru		goto next;
353162936Sru	}
3541553Srgrimes	this = ns(wd);
3551553Srgrimes	next_word(fp, wd);
3561553Srgrimes	if (wd == 0) {
357210144Simp		fprintf(stderr, "%s: No type for %s.\n", fname, this);
3581553Srgrimes		exit(1);
3591553Srgrimes	}
360152811Sru	tp = fl_lookup(this);
361152862Sru	compile = 0;
362152862Sru	match = 1;
3631553Srgrimes	nreqs = 0;
36473199Speter	compilewith = 0;
3654571Sgibbs	depends = 0;
3666803Sgibbs	clean = 0;
36772684Speter	warning = 0;
36830796Sjoerg	std = mandatory = 0;
3694571Sgibbs	imp_rule = 0;
3704571Sgibbs	no_obj = 0;
3715325Sgibbs	before_depend = 0;
37291002Speter	nowerror = 0;
3731553Srgrimes	filetype = NORMAL;
37461523Speter	if (eq(wd, "standard")) {
3751553Srgrimes		std = 1;
37630796Sjoerg	/*
37730796Sjoerg	 * If an entry is marked "mandatory", config will abort if it's
37830796Sjoerg	 * not called by a configuration line in the config file.  Apart
37930796Sjoerg	 * from this, the device is handled like one marked "optional".
38030796Sjoerg	 */
38161523Speter	} else if (eq(wd, "mandatory")) {
38230796Sjoerg		mandatory = 1;
38361523Speter	} else if (!eq(wd, "optional")) {
384210144Simp		fprintf(stderr,
385214654Sobrien		    "%s: \"%s\" %s must be optional, mandatory or standard\n",
386214654Sobrien		    fname, wd, this);
3871553Srgrimes		exit(1);
3881553Srgrimes	}
3891553Srgrimesnextparam:
3901553Srgrimes	next_word(fp, wd);
391113397Sphk	if (wd == 0) {
392152862Sru		compile += match;
393152862Sru		if (compile && tp == NULL)
394152862Sru			goto doneparam;
395152862Sru		goto next;
396113397Sphk	}
397152862Sru	if (eq(wd, "|")) {
398152862Sru		if (nreqs == 0) {
399210144Simp			fprintf(stderr, "%s: syntax error describing %s\n",
400152862Sru			    fname, this);
401152862Sru			exit(1);
402152862Sru		}
403152862Sru		compile += match;
404152862Sru		match = 1;
405152862Sru		nreqs = 0;
406152862Sru		goto nextparam;
407152862Sru	}
4084571Sgibbs	if (eq(wd, "no-obj")) {
4094571Sgibbs		no_obj++;
4104571Sgibbs		goto nextparam;
4114571Sgibbs	}
4124571Sgibbs	if (eq(wd, "no-implicit-rule")) {
41373199Speter		if (compilewith == 0) {
414210144Simp			fprintf(stderr, "%s: alternate rule required when "
415210144Simp			    "\"no-implicit-rule\" is specified.\n",
416210144Simp			    fname);
4174571Sgibbs		}
4184571Sgibbs		imp_rule++;
4194571Sgibbs		goto nextparam;
4204571Sgibbs	}
4215325Sgibbs	if (eq(wd, "before-depend")) {
4225325Sgibbs		before_depend++;
4235325Sgibbs		goto nextparam;
4245325Sgibbs	}
4256803Sgibbs	if (eq(wd, "dependency")) {
4264571Sgibbs		next_quoted_word(fp, wd);
4274571Sgibbs		if (wd == 0) {
428210144Simp			fprintf(stderr,
429210144Simp			    "%s: %s missing compile command string.\n",
430210144Simp			    fname, this);
4314571Sgibbs			exit(1);
4324571Sgibbs		}
4334571Sgibbs		depends = ns(wd);
4344571Sgibbs		goto nextparam;
4354571Sgibbs	}
4366803Sgibbs	if (eq(wd, "clean")) {
4375325Sgibbs		next_quoted_word(fp, wd);
4385325Sgibbs		if (wd == 0) {
439210144Simp			fprintf(stderr, "%s: %s missing clean file list.\n",
440210144Simp			    fname, this);
4415325Sgibbs			exit(1);
4425325Sgibbs		}
4436803Sgibbs		clean = ns(wd);
4445325Sgibbs		goto nextparam;
4455325Sgibbs	}
4461553Srgrimes	if (eq(wd, "compile-with")) {
4471553Srgrimes		next_quoted_word(fp, wd);
4481553Srgrimes		if (wd == 0) {
449210144Simp			fprintf(stderr,
450210144Simp			    "%s: %s missing compile command string.\n",
451210144Simp			    fname, this);
4521553Srgrimes			exit(1);
4531553Srgrimes		}
45473199Speter		compilewith = ns(wd);
4551553Srgrimes		goto nextparam;
4561553Srgrimes	}
45754490Speter	if (eq(wd, "warning")) {
45854490Speter		next_quoted_word(fp, wd);
45954490Speter		if (wd == 0) {
460210144Simp			fprintf(stderr,
461210144Simp			    "%s: %s missing warning text string.\n",
462210144Simp			    fname, this);
46354490Speter			exit(1);
46454490Speter		}
46572684Speter		warning = ns(wd);
46654490Speter		goto nextparam;
46754490Speter	}
4681553Srgrimes	nreqs++;
46938782Snsouch	if (eq(wd, "local")) {
47038782Snsouch		filetype = LOCAL;
47138782Snsouch		goto nextparam;
47238782Snsouch	}
47338782Snsouch	if (eq(wd, "no-depend")) {
47438782Snsouch		filetype = NODEPEND;
47538782Snsouch		goto nextparam;
47638782Snsouch	}
4771553Srgrimes	if (eq(wd, "profiling-routine")) {
4781553Srgrimes		filetype = PROFILING;
4791553Srgrimes		goto nextparam;
4801553Srgrimes	}
48191002Speter	if (eq(wd, "nowerror")) {
48291002Speter		nowerror = 1;
48391002Speter		goto nextparam;
48491002Speter	}
485110895Sru	STAILQ_FOREACH(dp, &dtab, d_next)
486152811Sru		if (eq(dp->d_name, wd)) {
487152811Sru			dp->d_done |= DEVDONE;
488153889Sru			goto nextparam;
489152811Sru		}
49030796Sjoerg	if (mandatory) {
491210144Simp		fprintf(stderr, "%s: mandatory device \"%s\" not found\n",
49230796Sjoerg		       fname, wd);
49330796Sjoerg		exit(1);
49430796Sjoerg	}
4951553Srgrimes	if (std) {
496210144Simp		fprintf(stderr,
497210144Simp		    "standard entry %s has a device keyword - %s!\n",
498210144Simp		    this, wd);
49973193Speter		exit(1);
5001553Srgrimes	}
501110895Sru	SLIST_FOREACH(op, &opt, op_next)
502152811Sru		if (op->op_value == 0 && opteq(op->op_name, wd))
5031553Srgrimes			goto nextparam;
504152862Sru	match = 0;
505152862Sru	goto nextparam;
5061553Srgrimes
5071553Srgrimesdoneparam:
5081553Srgrimes	if (std == 0 && nreqs == 0) {
509210144Simp		fprintf(stderr, "%s: what is %s optional on?\n",
5101553Srgrimes		    fname, this);
5111553Srgrimes		exit(1);
5121553Srgrimes	}
5131553Srgrimes
5141553Srgrimes	if (wd) {
515210144Simp		fprintf(stderr, "%s: syntax error describing %s\n",
5161553Srgrimes		    fname, this);
5171553Srgrimes		exit(1);
5181553Srgrimes	}
5191553Srgrimes	if (filetype == PROFILING && profiling == 0)
5201553Srgrimes		goto next;
521152811Sru	tp = new_fent();
5221553Srgrimes	tp->f_fn = this;
5231553Srgrimes	tp->f_type = filetype;
5244571Sgibbs	if (imp_rule)
5254571Sgibbs		tp->f_flags |= NO_IMPLCT_RULE;
5264571Sgibbs	if (no_obj)
5274571Sgibbs		tp->f_flags |= NO_OBJ;
5285325Sgibbs	if (before_depend)
5295325Sgibbs		tp->f_flags |= BEFORE_DEPEND;
53091002Speter	if (nowerror)
53191002Speter		tp->f_flags |= NOWERROR;
53273199Speter	tp->f_compilewith = compilewith;
5334571Sgibbs	tp->f_depends = depends;
5346803Sgibbs	tp->f_clean = clean;
53572684Speter	tp->f_warn = warning;
5361553Srgrimes	goto next;
5371553Srgrimes}
5381553Srgrimes
539129073Scognet/*
540129073Scognet * Read in the information about files used in making the system.
541129073Scognet * Store it in the ftab linked list.
542129073Scognet */
543129073Scognetstatic void
544129073Scognetread_files(void)
545129073Scognet{
546129073Scognet	char fname[MAXPATHLEN];
547129073Scognet	struct files_name *nl, *tnl;
548129073Scognet
549129073Scognet	(void) snprintf(fname, sizeof(fname), "../../conf/files");
550129073Scognet	read_file(fname);
551129073Scognet	(void) snprintf(fname, sizeof(fname),
552129073Scognet		       	"../../conf/files.%s", machinename);
553129073Scognet	read_file(fname);
554129073Scognet	for (nl = STAILQ_FIRST(&fntab); nl != NULL; nl = tnl) {
555129073Scognet		read_file(nl->f_name);
556129073Scognet		tnl = STAILQ_NEXT(nl, f_next);
557129073Scognet		free(nl->f_name);
558129073Scognet		free(nl);
559129073Scognet	}
560129073Scognet}
561129073Scognet
56245744Speterstatic int
56372684Speteropteq(const char *cp, const char *dp)
5641553Srgrimes{
5651553Srgrimes	char c, d;
5661553Srgrimes
5671553Srgrimes	for (; ; cp++, dp++) {
5681553Srgrimes		if (*cp != *dp) {
5691553Srgrimes			c = isupper(*cp) ? tolower(*cp) : *cp;
5701553Srgrimes			d = isupper(*dp) ? tolower(*dp) : *dp;
5711553Srgrimes			if (c != d)
5721553Srgrimes				return (0);
5731553Srgrimes		}
5741553Srgrimes		if (*cp == 0)
5751553Srgrimes			return (1);
5761553Srgrimes	}
5771553Srgrimes}
5781553Srgrimes
57945744Speterstatic void
58061640Speterdo_before_depend(FILE *fp)
5815325Sgibbs{
58261640Speter	struct file_list *tp;
58361640Speter	int lpos, len;
5845325Sgibbs
5855325Sgibbs	fputs("BEFORE_DEPEND=", fp);
5865325Sgibbs	lpos = 15;
587110895Sru	STAILQ_FOREACH(tp, &ftab, f_next)
5885325Sgibbs		if (tp->f_flags & BEFORE_DEPEND) {
5895325Sgibbs			len = strlen(tp->f_fn);
5905325Sgibbs			if ((len = 3 + len) + lpos > 72) {
5915325Sgibbs				lpos = 8;
5925325Sgibbs				fputs("\\\n\t", fp);
5935325Sgibbs			}
5945325Sgibbs			if (tp->f_flags & NO_IMPLCT_RULE)
5955325Sgibbs				fprintf(fp, "%s ", tp->f_fn);
5965325Sgibbs			else
5975325Sgibbs				fprintf(fp, "$S/%s ", tp->f_fn);
5985325Sgibbs			lpos += len + 1;
5995325Sgibbs		}
6005325Sgibbs	if (lpos != 8)
6015325Sgibbs		putc('\n', fp);
6025325Sgibbs}
6035325Sgibbs
60445744Speterstatic void
60561640Speterdo_objs(FILE *fp)
6061553Srgrimes{
60761640Speter	struct file_list *tp;
60861640Speter	int lpos, len;
60961640Speter	char *cp, och, *sp;
6101553Srgrimes
6111553Srgrimes	fprintf(fp, "OBJS=");
6121553Srgrimes	lpos = 6;
613110895Sru	STAILQ_FOREACH(tp, &ftab, f_next) {
614152811Sru		if (tp->f_flags & NO_OBJ)
6151553Srgrimes			continue;
6161553Srgrimes		sp = tail(tp->f_fn);
6171553Srgrimes		cp = sp + (len = strlen(sp)) - 1;
6181553Srgrimes		och = *cp;
6191553Srgrimes		*cp = 'o';
6201553Srgrimes		if (len + lpos > 72) {
6211553Srgrimes			lpos = 8;
6221553Srgrimes			fprintf(fp, "\\\n\t");
6231553Srgrimes		}
6241553Srgrimes		fprintf(fp, "%s ", sp);
6251553Srgrimes		lpos += len + 1;
6261553Srgrimes		*cp = och;
6271553Srgrimes	}
6281553Srgrimes	if (lpos != 8)
6291553Srgrimes		putc('\n', fp);
6301553Srgrimes}
6311553Srgrimes
63245744Speterstatic void
63369135Speterdo_xxfiles(char *tag, FILE *fp)
6341553Srgrimes{
63561640Speter	struct file_list *tp;
63669135Speter	int lpos, len, slen;
63769135Speter	char *suff, *SUFF;
6381553Srgrimes
63969135Speter	if (tag[strlen(tag) - 1] == '\n')
64069135Speter		tag[strlen(tag) - 1] = '\0';
64169135Speter
64269135Speter	suff = ns(tag + 7);
64369135Speter	SUFF = ns(suff);
64469135Speter	raisestr(SUFF);
64569135Speter	slen = strlen(suff);
64669135Speter
64769135Speter	fprintf(fp, "%sFILES=", SUFF);
6481553Srgrimes	lpos = 8;
649110895Sru	STAILQ_FOREACH(tp, &ftab, f_next)
650152811Sru		if (tp->f_type != NODEPEND) {
6511553Srgrimes			len = strlen(tp->f_fn);
65269135Speter			if (tp->f_fn[len - slen - 1] != '.')
6531553Srgrimes				continue;
65469135Speter			if (strcasecmp(&tp->f_fn[len - slen], suff) != 0)
65569135Speter				continue;
6561553Srgrimes			if ((len = 3 + len) + lpos > 72) {
6571553Srgrimes				lpos = 8;
6581553Srgrimes				fputs("\\\n\t", fp);
6591553Srgrimes			}
66038782Snsouch			if (tp->f_type != LOCAL)
66138782Snsouch				fprintf(fp, "$S/%s ", tp->f_fn);
66238782Snsouch			else
66338782Snsouch				fprintf(fp, "%s ", tp->f_fn);
6641553Srgrimes			lpos += len + 1;
6651553Srgrimes		}
6661553Srgrimes	if (lpos != 8)
6671553Srgrimes		putc('\n', fp);
6681553Srgrimes}
6691553Srgrimes
67045744Speterstatic char *
67161640Spetertail(char *fn)
6721553Srgrimes{
67361640Speter	char *cp;
6741553Srgrimes
6751553Srgrimes	cp = rindex(fn, '/');
6761553Srgrimes	if (cp == 0)
6771553Srgrimes		return (fn);
6781553Srgrimes	return (cp+1);
6791553Srgrimes}
6801553Srgrimes
6811553Srgrimes/*
6821553Srgrimes * Create the makerules for each file
6831553Srgrimes * which is part of the system.
6841553Srgrimes */
68545744Speterstatic void
68661640Speterdo_rules(FILE *f)
6871553Srgrimes{
688160495Sstefanf	char *cp, *np, och;
68961640Speter	struct file_list *ftp;
69073199Speter	char *compilewith;
691209135Simp	char cmd[128];
6921553Srgrimes
693110895Sru	STAILQ_FOREACH(ftp, &ftab, f_next) {
69454490Speter		if (ftp->f_warn)
695210144Simp			fprintf(stderr, "WARNING: %s\n", ftp->f_warn);
6961553Srgrimes		cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
6971553Srgrimes		och = *cp;
6984571Sgibbs		if (ftp->f_flags & NO_IMPLCT_RULE) {
6994571Sgibbs			if (ftp->f_depends)
70052098Speter				fprintf(f, "%s: %s\n", np, ftp->f_depends);
7014571Sgibbs			else
70252098Speter				fprintf(f, "%s: \n", np);
7031553Srgrimes		}
7044571Sgibbs		else {
7054571Sgibbs			*cp = '\0';
7064571Sgibbs			if (och == 'o') {
7078857Srgrimes				fprintf(f, "%so:\n\t-cp $S/%so .\n\n",
7084571Sgibbs					tail(np), np);
7094571Sgibbs				continue;
7104571Sgibbs			}
711116450Smarkm			if (ftp->f_depends) {
712116450Smarkm				fprintf(f, "%sln: $S/%s%c %s\n", tail(np),
713116450Smarkm					np, och, ftp->f_depends);
714116450Smarkm				fprintf(f, "\t${NORMAL_LINT}\n\n");
7158857Srgrimes				fprintf(f, "%so: $S/%s%c %s\n", tail(np),
7164571Sgibbs					np, och, ftp->f_depends);
717116450Smarkm			}
718116450Smarkm			else {
719116450Smarkm				fprintf(f, "%sln: $S/%s%c\n", tail(np),
720116450Smarkm					np, och);
721116450Smarkm				fprintf(f, "\t${NORMAL_LINT}\n\n");
7228857Srgrimes				fprintf(f, "%so: $S/%s%c\n", tail(np),
7234571Sgibbs					np, och);
724116450Smarkm			}
7254571Sgibbs		}
72673199Speter		compilewith = ftp->f_compilewith;
72773199Speter		if (compilewith == 0) {
72872684Speter			const char *ftype = NULL;
7291553Srgrimes
7301553Srgrimes			switch (ftp->f_type) {
7311553Srgrimes			case NORMAL:
7321553Srgrimes				ftype = "NORMAL";
7331553Srgrimes				break;
7341553Srgrimes			case PROFILING:
7351553Srgrimes				if (!profiling)
7361553Srgrimes					continue;
7371553Srgrimes				ftype = "PROFILE";
7381553Srgrimes				break;
7391553Srgrimes			default:
740210144Simp				fprintf(stderr,
741210144Simp				    "config: don't know rules for %s\n", np);
7421553Srgrimes				break;
7431553Srgrimes			}
744209135Simp			snprintf(cmd, sizeof(cmd),
745209135Simp			    "${%s_%c%s}\n\t@${NORMAL_CTFCONVERT}", ftype,
74691002Speter			    toupper(och),
74791002Speter			    ftp->f_flags & NOWERROR ? "_NOWERROR" : "");
74873199Speter			compilewith = cmd;
7491553Srgrimes		}
7501553Srgrimes		*cp = och;
75173199Speter		fprintf(f, "\t%s\n\n", compilewith);
7521553Srgrimes	}
7531553Srgrimes}
7541553Srgrimes
75545744Speterstatic void
75661640Speterdo_clean(FILE *fp)
7576803Sgibbs{
75861640Speter	struct file_list *tp;
75961640Speter	int lpos, len;
7606803Sgibbs
7616803Sgibbs	fputs("CLEAN=", fp);
7626803Sgibbs	lpos = 7;
763110895Sru	STAILQ_FOREACH(tp, &ftab, f_next)
7646803Sgibbs		if (tp->f_clean) {
7656803Sgibbs			len = strlen(tp->f_clean);
7666803Sgibbs			if (len + lpos > 72) {
7676803Sgibbs				lpos = 8;
7686803Sgibbs				fputs("\\\n\t", fp);
7696803Sgibbs			}
7706803Sgibbs			fprintf(fp, "%s ", tp->f_clean);
7716803Sgibbs			lpos += len + 1;
7726803Sgibbs		}
7736803Sgibbs	if (lpos != 8)
7746803Sgibbs		putc('\n', fp);
7756803Sgibbs}
7766803Sgibbs
7771553Srgrimeschar *
77861640Speterraisestr(char *str)
7791553Srgrimes{
78061640Speter	char *cp = str;
7811553Srgrimes
7821553Srgrimes	while (*str) {
7831553Srgrimes		if (islower(*str))
7841553Srgrimes			*str = toupper(*str);
7851553Srgrimes		str++;
7861553Srgrimes	}
7871553Srgrimes	return (cp);
7881553Srgrimes}
789