mkmakefile.c revision 162936
1331722Seadler/*
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
311553Srgrimes#if 0
3229780Scharnierstatic char sccsid[] = "@(#)mkmakefile.c	8.1 (Berkeley) 6/6/93";
331553Srgrimes#endif
341553Srgrimesstatic const char rcsid[] =
351553Srgrimes  "$FreeBSD: head/usr.sbin/config/mkmakefile.c 162936 2006-10-01 17:17:29Z ru $";
361553Srgrimes#endif /* not lint */
37117280Scharnier
38117587Sgad/*
3915637Sjoerg * Build the makefile for the system, from
40117587Sgad * the information in the files files and the
4129780Scharnier * additional files for the machine being compiled to.
421553Srgrimes */
43117554Sgad
44117280Scharnier#include <ctype.h>
45117280Scharnier#include <err.h>
461553Srgrimes#include <stdio.h>
471553Srgrimes#include <string.h>
481553Srgrimes#include <sys/param.h>
491553Srgrimes#include "y.tab.h"
501553Srgrimes#include "config.h"
511553Srgrimes#include "configvers.h"
521553Srgrimes
531553Srgrimes#define next_word(fp, wd) \
541553Srgrimes	{ 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) \
611553Srgrimes	{ char *word = get_quoted_word(fp); \
621553Srgrimes	  if (word == (char *)EOF) \
631553Srgrimes		return; \
641553Srgrimes	  else \
651553Srgrimes		wd = word; \
661553Srgrimes	}
671553Srgrimes
681553Srgrimesstatic char *tail(char *);
691553Srgrimesstatic void do_clean(FILE *);
701553Srgrimesstatic void do_rules(FILE *);
711553Srgrimesstatic void do_xxfiles(char *, FILE *);
721553Srgrimesstatic void do_objs(FILE *);
731553Srgrimesstatic void do_before_depend(FILE *);
741553Srgrimesstatic int opteq(const char *, const char *);
751553Srgrimesstatic void read_files(void);
761553Srgrimes
771553Srgrimes/*
781553Srgrimes * Lookup a file, by name.
791553Srgrimes */
801553Srgrimesstatic struct file_list *
8115637Sjoergfl_lookup(char *file)
821553Srgrimes{
8315703Sjoerg	struct file_list *fp;
841553Srgrimes
851553Srgrimes	STAILQ_FOREACH(fp, &ftab, f_next) {
861553Srgrimes		if (eq(fp->f_fn, file))
871553Srgrimes			return (fp);
881553Srgrimes	}
8928621Sjoerg	return (0);
901553Srgrimes}
911553Srgrimes
921553Srgrimes/*
931553Srgrimes * Make a new file list entry
941553Srgrimes */
951553Srgrimesstatic struct file_list *
9628621Sjoergnew_fent(void)
971553Srgrimes{
981553Srgrimes	struct file_list *fp;
991553Srgrimes
1001553Srgrimes	fp = (struct file_list *) calloc(1, sizeof *fp);
1011553Srgrimes	STAILQ_INSERT_TAIL(&ftab, fp, f_next);
1021553Srgrimes	return (fp);
1031553Srgrimes}
10495070Sgad
1051553Srgrimes/*
1061553Srgrimes * Build the makefile from the skeleton
10778146Sgad */
10878146Sgadvoid
10978146Sgadmakefile(void)
11078146Sgad{
11178146Sgad	FILE *ifp, *ofp;
11278749Sgad	char line[BUFSIZ];
11378146Sgad	struct opt *op;
11498776Sgad	int versreq;
11578302Sgad
11678146Sgad	read_files();
1171553Srgrimes	snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename);
11870098Sume	ifp = fopen(line, "r");
119173412Skevlo	if (ifp == 0) {
120173412Skevlo		snprintf(line, sizeof(line), "Makefile.%s", machinename);
12170098Sume		ifp = fopen(line, "r");
12227618Simp	}
12327618Simp	if (ifp == 0)
12478749Sgad		err(1, "%s", line);
12578749Sgad
12698776Sgad	ofp = fopen(path("Makefile.new"), "w");
12778749Sgad	if (ofp == 0)
1281553Srgrimes		err(1, "%s", path("Makefile.new"));
12978146Sgad	fprintf(ofp, "KERN_IDENT=%s\n", ident);
1301553Srgrimes	SLIST_FOREACH(op, &mkopt, op_next)
13180170Sgad		fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
1321553Srgrimes	if (debugging)
1331553Srgrimes		fprintf(ofp, "DEBUG=-g\n");
13470098Sume	if (profiling)
13580170Sgad		fprintf(ofp, "PROFLEVEL=%d\n", profiling);
13631492Swollman	if (*srcdir != '\0')
13728621Sjoerg		fprintf(ofp,"S=%s\n", srcdir);
13870098Sume	while (fgets(line, BUFSIZ, ifp) != 0) {
1391553Srgrimes		if (*line != '%') {
14027618Simp			fprintf(ofp, "%s", line);
14127618Simp			continue;
14278749Sgad		}
14378749Sgad		if (eq(line, "%BEFORE_DEPEND\n"))
14468742Sgad			do_before_depend(ofp);
14578300Sgad		else if (eq(line, "%OBJS\n"))
1461553Srgrimes			do_objs(ofp);
14778280Sgad		else if (strncmp(line, "%FILES.", 7) == 0)
14827618Simp			do_xxfiles(line, ofp);
14928621Sjoerg		else if (eq(line, "%RULES\n"))
15028621Sjoerg			do_rules(ofp);
15127618Simp		else if (eq(line, "%CLEAN\n"))
15228621Sjoerg			do_clean(ofp);
15395070Sgad		else if (strncmp(line, "%VERSREQ=", sizeof("%VERSREQ=") - 1) == 0) {
15428621Sjoerg			versreq = atoi(line + sizeof("%VERSREQ=") - 1);
15578749Sgad			if (MAJOR_VERS(versreq) != MAJOR_VERS(CONFIGVERS) ||
15678749Sgad			    versreq > CONFIGVERS) {
15778749Sgad				fprintf(stderr, "ERROR: version of config(8) does not match kernel!\n");
15878749Sgad				fprintf(stderr, "config version = %d, ", CONFIGVERS);
15928621Sjoerg				fprintf(stderr, "version required = %d\n\n", versreq);
16068742Sgad				fprintf(stderr, "Make sure that /usr/src/usr.sbin/config is in sync\n");
16128621Sjoerg				fprintf(stderr, "with your /usr/src/sys and install a new config binary\n");
16228621Sjoerg				fprintf(stderr, "before trying this again.\n\n");
16328621Sjoerg				fprintf(stderr, "If running the new config fails check your config\n");
16428621Sjoerg				fprintf(stderr, "file against the GENERIC or LINT config files for\n");
16595070Sgad				fprintf(stderr, "changes in config syntax, or option/device naming\n");
16695070Sgad				fprintf(stderr, "conventions\n\n");
16795070Sgad				exit(1);
16895070Sgad			}
16995070Sgad		} else
17095070Sgad			fprintf(stderr,
17195070Sgad			    "Unknown %% construct in generic makefile: %s",
17258777Ssheldonh			    line);
17380122Sgad	}
17480122Sgad	(void) fclose(ifp);
17580122Sgad	(void) fclose(ofp);
17680122Sgad	moveifchanged(path("Makefile.new"), path("Makefile"));
17780122Sgad}
17880122Sgad
17980122Sgad/*
18080122Sgad * Build hints.c from the skeleton
18180122Sgad */
18280122Sgadvoid
18380122Sgadmakehints(void)
18480122Sgad{
18580122Sgad	FILE *ifp, *ofp;
18678749Sgad	char line[BUFSIZ];
18778749Sgad	char *s;
18878749Sgad
18978749Sgad	if (hints) {
19070098Sume		ifp = fopen(hints, "r");
19170098Sume		if (ifp == NULL)
19270098Sume			err(1, "%s", hints);
19370098Sume	} else {
19470098Sume		ifp = NULL;
19574127Sgad	}
19670098Sume	ofp = fopen(path("hints.c.new"), "w");
19770098Sume	if (ofp == NULL)
19874127Sgad		err(1, "%s", path("hints.c.new"));
19974127Sgad	fprintf(ofp, "#include <sys/types.h>\n");
20074127Sgad	fprintf(ofp, "#include <sys/systm.h>\n");
20170098Sume	fprintf(ofp, "\n");
20280122Sgad	fprintf(ofp, "int hintmode = %d;\n", hintmode);
20380122Sgad	fprintf(ofp, "char static_hints[] = {\n");
20480122Sgad	if (ifp) {
20580122Sgad		while (fgets(line, BUFSIZ, ifp) != 0) {
20680122Sgad			/* zap trailing CR and/or LF */
20780122Sgad			while ((s = rindex(line, '\n')) != NULL)
20880122Sgad				*s = '\0';
20980122Sgad			while ((s = rindex(line, '\r')) != NULL)
21080122Sgad				*s = '\0';
21180122Sgad			/* remove # comments */
21228621Sjoerg			s = index(line, '#');
21328621Sjoerg			if (s)
21428621Sjoerg				*s = '\0';
21570098Sume			/* remove any whitespace and " characters */
21670098Sume			s = line;
21728621Sjoerg			while (*s) {
21828621Sjoerg				if (*s == ' ' || *s == '\t' || *s == '"') {
21928621Sjoerg					while (*s) {
22028621Sjoerg						s[0] = s[1];
22128621Sjoerg						s++;
22228621Sjoerg					}
22328621Sjoerg					/* start over */
22428621Sjoerg					s = line;
22528621Sjoerg					continue;
22628621Sjoerg				}
22728621Sjoerg				s++;
22828621Sjoerg			}
22928621Sjoerg			/* anything left? */
23028621Sjoerg			if (*line == '\0')
23128621Sjoerg				continue;
23228621Sjoerg			fprintf(ofp, "\"%s\\0\"\n", line);
23328621Sjoerg		}
23428621Sjoerg	}
2351553Srgrimes	fprintf(ofp, "\"\\0\"\n};\n");
2361553Srgrimes	if (ifp)
23728621Sjoerg		fclose(ifp);
23828621Sjoerg	fclose(ofp);
23928621Sjoerg	moveifchanged(path("hints.c.new"), path("hints.c"));
24031492Swollman}
24131492Swollman
24231492Swollman/*
24331492Swollman * Build env.c from the skeleton
24431492Swollman */
24531492Swollmanvoid
24631492Swollmanmakeenv(void)
24731492Swollman{
24831492Swollman	FILE *ifp, *ofp;
24931492Swollman	char line[BUFSIZ];
25031492Swollman	char *s;
25131492Swollman
25231492Swollman	if (env) {
25331492Swollman		ifp = fopen(env, "r");
25431492Swollman		if (ifp == NULL)
25531492Swollman			err(1, "%s", env);
25631492Swollman	} else {
25731492Swollman		ifp = NULL;
25831492Swollman	}
25931492Swollman	ofp = fopen(path("env.c.new"), "w");
26031492Swollman	if (ofp == NULL)
26131492Swollman		err(1, "%s", path("env.c.new"));
26231492Swollman	fprintf(ofp, "#include <sys/types.h>\n");
26331492Swollman	fprintf(ofp, "#include <sys/systm.h>\n");
26431492Swollman	fprintf(ofp, "\n");
2651553Srgrimes	fprintf(ofp, "int envmode = %d;\n", envmode);
2661553Srgrimes	fprintf(ofp, "char static_env[] = {\n");
2671553Srgrimes	if (ifp) {
2681553Srgrimes		while (fgets(line, BUFSIZ, ifp) != 0) {
2691553Srgrimes			/* zap trailing CR and/or LF */
2701553Srgrimes			while ((s = rindex(line, '\n')) != NULL)
2711553Srgrimes				*s = '\0';
2721553Srgrimes			while ((s = rindex(line, '\r')) != NULL)
27395070Sgad				*s = '\0';
27495070Sgad			/* remove # comments */
2751553Srgrimes			s = index(line, '#');
27631492Swollman			if (s)
27731492Swollman				*s = '\0';
27831492Swollman			/* remove any whitespace and " characters */
27931492Swollman			s = line;
28031492Swollman			while (*s) {
28131492Swollman				if (*s == ' ' || *s == '\t' || *s == '"') {
28231492Swollman					while (*s) {
28331492Swollman						s[0] = s[1];
28431492Swollman						s++;
2851553Srgrimes					}
28695068Sgad					/* start over */
2871553Srgrimes					s = line;
2881553Srgrimes					continue;
2891553Srgrimes				}
2901553Srgrimes				s++;
29131492Swollman			}
2921553Srgrimes			/* anything left? */
2931553Srgrimes			if (*line == '\0')
2941553Srgrimes				continue;
2951553Srgrimes			fprintf(ofp, "\"%s\\0\"\n", line);
2961553Srgrimes		}
2971553Srgrimes	}
2981553Srgrimes	fprintf(ofp, "\"\\0\"\n};\n");
2991553Srgrimes	if (ifp)
3001553Srgrimes		fclose(ifp);
3011553Srgrimes	fclose(ofp);
3021553Srgrimes	moveifchanged(path("env.c.new"), path("env.c"));
3031553Srgrimes}
3041553Srgrimes
3051553Srgrimesstatic void
3061553Srgrimesread_file(char *fname)
3071553Srgrimes{
3081553Srgrimes	char ifname[MAXPATHLEN];
3091553Srgrimes	FILE *fp;
3101553Srgrimes	struct file_list *tp;
3111553Srgrimes	struct device *dp;
3121553Srgrimes	struct opt *op;
31331492Swollman	char *wd, *this, *compilewith, *depends, *clean, *warning;
31431492Swollman	int compile, match, nreqs, std, filetype,
31531492Swollman	    imp_rule, no_obj, before_depend, mandatory, nowerror;
31631492Swollman
31731492Swollman	fp = fopen(fname, "r");
31831492Swollman	if (fp == 0)
31931492Swollman		err(1, "%s", fname);
32031492Swollmannext:
32119202Simp	/*
3221553Srgrimes	 * include "filename"
3231553Srgrimes	 * filename    [ standard | mandatory | optional ]
3241553Srgrimes	 *	[ dev* [ | dev* ... ] | profiling-routine ] [ no-obj ]
3251553Srgrimes	 *	[ compile-with "compile rule" [no-implicit-rule] ]
3261553Srgrimes	 *      [ dependency "dependency-list"] [ before-depend ]
3271553Srgrimes	 *	[ clean "file-list"] [ warning "text warning" ]
3281553Srgrimes	 */
3291553Srgrimes	wd = get_word(fp);
3301553Srgrimes	if (wd == (char *)EOF) {
3311553Srgrimes		(void) fclose(fp);
3321553Srgrimes		return;
3331553Srgrimes	}
3341553Srgrimes	if (wd == 0)
3351553Srgrimes		goto next;
33619202Simp	if (wd[0] == '#')
33731492Swollman	{
3381553Srgrimes		while (((wd = get_word(fp)) != (char *)EOF) && wd)
3391553Srgrimes			;
3401553Srgrimes		goto next;
34195070Sgad	}
34278302Sgad	if (eq(wd, "include")) {
34370098Sume		next_quoted_word(fp, wd);
34470098Sume		if (wd == 0) {
34570098Sume			printf("%s: missing include filename.\n", fname);
34670098Sume			exit(1);
34770098Sume		}
34870098Sume		(void) snprintf(ifname, sizeof(ifname), "../../%s", wd);
3491553Srgrimes		read_file(ifname);
3501553Srgrimes		while (((wd = get_word(fp)) != (char *)EOF) && wd)
3511553Srgrimes			;
3521553Srgrimes		goto next;
3531553Srgrimes	}
3541553Srgrimes	this = ns(wd);
3551553Srgrimes	next_word(fp, wd);
35668742Sgad	if (wd == 0) {
35768742Sgad		printf("%s: No type for %s.\n",
35831492Swollman		    fname, this);
35931492Swollman		exit(1);
36031492Swollman	}
3611553Srgrimes	tp = fl_lookup(this);
36278302Sgad	compile = 0;
3631553Srgrimes	match = 1;
3641553Srgrimes	nreqs = 0;
3651553Srgrimes	compilewith = 0;
3661553Srgrimes	depends = 0;
3671553Srgrimes	clean = 0;
3681553Srgrimes	warning = 0;
3691553Srgrimes	std = mandatory = 0;
3701553Srgrimes	imp_rule = 0;
3711553Srgrimes	no_obj = 0;
37278302Sgad	before_depend = 0;
37378302Sgad	nowerror = 0;
3741553Srgrimes	filetype = NORMAL;
3751553Srgrimes	if (eq(wd, "standard")) {
3761553Srgrimes		std = 1;
3771553Srgrimes	/*
37870098Sume	 * If an entry is marked "mandatory", config will abort if it's
37970098Sume	 * not called by a configuration line in the config file.  Apart
38070098Sume	 * from this, the device is handled like one marked "optional".
38170098Sume	 */
38270098Sume	} else if (eq(wd, "mandatory")) {
38370098Sume		mandatory = 1;
38470098Sume	} else if (!eq(wd, "optional")) {
38570098Sume		printf("%s: %s must be optional, mandatory or standard\n",
38670098Sume		       fname, this);
3871553Srgrimes		exit(1);
3881553Srgrimes	}
3891553Srgrimesnextparam:
3901553Srgrimes	next_word(fp, wd);
3911553Srgrimes	if (wd == 0) {
3921553Srgrimes		compile += match;
3931553Srgrimes		if (compile && tp == NULL)
39479735Sgad			goto doneparam;
39579735Sgad		goto next;
39679735Sgad	}
39779735Sgad	if (eq(wd, "|")) {
39879735Sgad		if (nreqs == 0) {
39979735Sgad			printf("%s: syntax error describing %s\n",
4001553Srgrimes			    fname, this);
4011553Srgrimes			exit(1);
4021553Srgrimes		}
4031553Srgrimes		compile += match;
4041553Srgrimes		match = 1;
40595070Sgad		nreqs = 0;
40670098Sume		goto nextparam;
40770098Sume	}
40858777Ssheldonh	if (eq(wd, "no-obj")) {
409118881Sgad		no_obj++;
4101553Srgrimes		goto nextparam;
4111553Srgrimes	}
41270098Sume	if (eq(wd, "no-implicit-rule")) {
4131553Srgrimes		if (compilewith == 0) {
41478749Sgad			printf("%s: alternate rule required when "
41578749Sgad			       "\"no-implicit-rule\" is specified.\n",
4161553Srgrimes			       fname);
4171553Srgrimes		}
4181553Srgrimes		imp_rule++;
4191553Srgrimes		goto nextparam;
4201553Srgrimes	}
4211553Srgrimes	if (eq(wd, "before-depend")) {
4221553Srgrimes		before_depend++;
4231553Srgrimes		goto nextparam;
4241553Srgrimes	}
4251553Srgrimes	if (eq(wd, "dependency")) {
42678146Sgad		next_quoted_word(fp, wd);
4271553Srgrimes		if (wd == 0) {
42897781Sgad			printf("%s: %s missing compile command string.\n",
4291553Srgrimes			       fname, this);
43097781Sgad			exit(1);
4311553Srgrimes		}
4321553Srgrimes		depends = ns(wd);
4331553Srgrimes		goto nextparam;
4341553Srgrimes	}
43578146Sgad	if (eq(wd, "clean")) {
4361553Srgrimes		next_quoted_word(fp, wd);
43766414Swollman		if (wd == 0) {
43866414Swollman			printf("%s: %s missing clean file list.\n",
43966414Swollman			       fname, this);
44066414Swollman			exit(1);
44166414Swollman		}
44266414Swollman		clean = ns(wd);
44366414Swollman		goto nextparam;
44466414Swollman	}
44566414Swollman	if (eq(wd, "compile-with")) {
4461553Srgrimes		next_quoted_word(fp, wd);
4471553Srgrimes		if (wd == 0) {
4481553Srgrimes			printf("%s: %s missing compile command string.\n",
4491553Srgrimes			       fname, this);
4501553Srgrimes			exit(1);
4511553Srgrimes		}
4521553Srgrimes		compilewith = ns(wd);
4531553Srgrimes		goto nextparam;
4541553Srgrimes	}
4551553Srgrimes	if (eq(wd, "warning")) {
4561553Srgrimes		next_quoted_word(fp, wd);
4571553Srgrimes		if (wd == 0) {
4581553Srgrimes			printf("%s: %s missing warning text string.\n",
45978300Sgad				fname, this);
46078300Sgad			exit(1);
4611553Srgrimes		}
46278146Sgad		warning = ns(wd);
4631553Srgrimes		goto nextparam;
4641553Srgrimes	}
4651553Srgrimes	nreqs++;
4661553Srgrimes	if (eq(wd, "local")) {
4671553Srgrimes		filetype = LOCAL;
4681553Srgrimes		goto nextparam;
4691553Srgrimes	}
4701553Srgrimes	if (eq(wd, "no-depend")) {
4711553Srgrimes		filetype = NODEPEND;
47278146Sgad		goto nextparam;
4731553Srgrimes	}
47431492Swollman	if (eq(wd, "profiling-routine")) {
47531492Swollman		filetype = PROFILING;
47631492Swollman		goto nextparam;
47731492Swollman	}
4781553Srgrimes	if (eq(wd, "nowerror")) {
47931492Swollman		nowerror = 1;
48031492Swollman		goto nextparam;
4811553Srgrimes	}
4821553Srgrimes	STAILQ_FOREACH(dp, &dtab, d_next)
4831553Srgrimes		if (eq(dp->d_name, wd)) {
4841553Srgrimes			dp->d_done |= DEVDONE;
48531492Swollman			goto nextparam;
48680113Sgad		}
4871553Srgrimes	if (mandatory) {
48831492Swollman		printf("%s: mandatory device \"%s\" not found\n",
4891553Srgrimes		       fname, wd);
4901553Srgrimes		exit(1);
4911553Srgrimes	}
4921553Srgrimes	if (std) {
4931553Srgrimes		printf("standard entry %s has a device keyword - %s!\n",
4941553Srgrimes		       this, wd);
4951553Srgrimes		exit(1);
4961553Srgrimes	}
49778300Sgad	SLIST_FOREACH(op, &opt, op_next)
4981553Srgrimes		if (op->op_value == 0 && opteq(op->op_name, wd))
4991553Srgrimes			goto nextparam;
50078300Sgad	match = 0;
5011553Srgrimes	goto nextparam;
5021553Srgrimes
50331492Swollmandoneparam:
50431492Swollman	if (std == 0 && nreqs == 0) {
5051553Srgrimes		printf("%s: what is %s optional on?\n",
50631492Swollman		    fname, this);
5071553Srgrimes		exit(1);
5081553Srgrimes	}
5091553Srgrimes
5101553Srgrimes	if (wd) {
51131492Swollman		printf("%s: syntax error describing %s\n",
5121553Srgrimes		    fname, this);
51331492Swollman		exit(1);
51431492Swollman	}
51531492Swollman	if (filetype == PROFILING && profiling == 0)
5161553Srgrimes		goto next;
5171553Srgrimes	tp = new_fent();
5181553Srgrimes	tp->f_fn = this;
5191553Srgrimes	tp->f_type = filetype;
5201553Srgrimes	if (imp_rule)
5211553Srgrimes		tp->f_flags |= NO_IMPLCT_RULE;
5221553Srgrimes	if (no_obj)
5231553Srgrimes		tp->f_flags |= NO_OBJ;
5241553Srgrimes	if (before_depend)
5251553Srgrimes		tp->f_flags |= BEFORE_DEPEND;
5261553Srgrimes	if (nowerror)
5271553Srgrimes		tp->f_flags |= NOWERROR;
5281553Srgrimes	tp->f_compilewith = compilewith;
52931492Swollman	tp->f_depends = depends;
5301553Srgrimes	tp->f_clean = clean;
5311553Srgrimes	tp->f_warn = warning;
5321553Srgrimes	goto next;
53331492Swollman}
5341553Srgrimes
5351553Srgrimes/*
5361553Srgrimes * Read in the information about files used in making the system.
53731492Swollman * Store it in the ftab linked list.
53831492Swollman */
53979739Sgadstatic void
54031492Swollmanread_files(void)
5411553Srgrimes{
54231492Swollman	char fname[MAXPATHLEN];
5431553Srgrimes	struct files_name *nl, *tnl;
5441553Srgrimes
5451553Srgrimes	(void) snprintf(fname, sizeof(fname), "../../conf/files");
5461553Srgrimes	read_file(fname);
5471553Srgrimes	(void) snprintf(fname, sizeof(fname),
5481553Srgrimes		       	"../../conf/files.%s", machinename);
5491553Srgrimes	read_file(fname);
5501553Srgrimes	for (nl = STAILQ_FIRST(&fntab); nl != NULL; nl = tnl) {
5511553Srgrimes		read_file(nl->f_name);
5521553Srgrimes		tnl = STAILQ_NEXT(nl, f_next);
5531553Srgrimes		free(nl->f_name);
5541553Srgrimes		free(nl);
5551553Srgrimes	}
5561553Srgrimes}
5571553Srgrimes
5581553Srgrimesstatic int
5591553Srgrimesopteq(const char *cp, const char *dp)
5601553Srgrimes{
5611553Srgrimes	char c, d;
5621553Srgrimes
5631553Srgrimes	for (; ; cp++, dp++) {
5641553Srgrimes		if (*cp != *dp) {
5651553Srgrimes			c = isupper(*cp) ? tolower(*cp) : *cp;
56631492Swollman			d = isupper(*dp) ? tolower(*dp) : *dp;
5671553Srgrimes			if (c != d)
5681553Srgrimes				return (0);
5691553Srgrimes		}
57031492Swollman		if (*cp == 0)
5711553Srgrimes			return (1);
5721553Srgrimes	}
5731553Srgrimes}
57431492Swollman
5751553Srgrimesstatic void
5761553Srgrimesdo_before_depend(FILE *fp)
57731492Swollman{
5781553Srgrimes	struct file_list *tp;
5791553Srgrimes	int lpos, len;
5801553Srgrimes
5811553Srgrimes	fputs("BEFORE_DEPEND=", fp);
5821553Srgrimes	lpos = 15;
5831553Srgrimes	STAILQ_FOREACH(tp, &ftab, f_next)
5841553Srgrimes		if (tp->f_flags & BEFORE_DEPEND) {
5851553Srgrimes			len = strlen(tp->f_fn);
58678146Sgad			if ((len = 3 + len) + lpos > 72) {
5871553Srgrimes				lpos = 8;
58831492Swollman				fputs("\\\n\t", fp);
58931492Swollman			}
5901553Srgrimes			if (tp->f_flags & NO_IMPLCT_RULE)
59131492Swollman				fprintf(fp, "%s ", tp->f_fn);
59231492Swollman			else
59331492Swollman				fprintf(fp, "$S/%s ", tp->f_fn);
59431492Swollman			lpos += len + 1;
59531492Swollman		}
59631492Swollman	if (lpos != 8)
59725856Sbrian		putc('\n', fp);
59815637Sjoerg}
59968742Sgad
60068742Sgadstatic void
6011553Srgrimesdo_objs(FILE *fp)
60268742Sgad{
60368742Sgad	struct file_list *tp;
6041553Srgrimes	int lpos, len;
6051553Srgrimes	char *cp, och, *sp;
60631492Swollman
60731492Swollman	fprintf(fp, "OBJS=");
60831492Swollman	lpos = 6;
60915637Sjoerg	STAILQ_FOREACH(tp, &ftab, f_next) {
6101553Srgrimes		if (tp->f_flags & NO_OBJ)
61131492Swollman			continue;
61231492Swollman		sp = tail(tp->f_fn);
61331492Swollman		cp = sp + (len = strlen(sp)) - 1;
61431492Swollman		och = *cp;
61531492Swollman		*cp = 'o';
61631492Swollman		if (len + lpos > 72) {
61768742Sgad			lpos = 8;
61878317Sgad			fprintf(fp, "\\\n\t");
61931492Swollman		}
6201553Srgrimes		fprintf(fp, "%s ", sp);
6211553Srgrimes		lpos += len + 1;
6221553Srgrimes		*cp = och;
62315637Sjoerg	}
62415637Sjoerg	if (lpos != 8)
62515637Sjoerg		putc('\n', fp);
62615637Sjoerg}
62778146Sgad
62815637Sjoergstatic void
62915637Sjoergdo_xxfiles(char *tag, FILE *fp)
63015637Sjoerg{
63115637Sjoerg	struct file_list *tp;
63215637Sjoerg	int lpos, len, slen;
63331492Swollman	char *suff, *SUFF;
63415637Sjoerg
63515637Sjoerg	if (tag[strlen(tag) - 1] == '\n')
63615637Sjoerg		tag[strlen(tag) - 1] = '\0';
63715637Sjoerg
63815637Sjoerg	suff = ns(tag + 7);
63915637Sjoerg	SUFF = ns(suff);
64015637Sjoerg	raisestr(SUFF);
64115637Sjoerg	slen = strlen(suff);
64215637Sjoerg
64315637Sjoerg	fprintf(fp, "%sFILES=", SUFF);
64415637Sjoerg	lpos = 8;
64515637Sjoerg	STAILQ_FOREACH(tp, &ftab, f_next)
6461553Srgrimes		if (tp->f_type != NODEPEND) {
6471553Srgrimes			len = strlen(tp->f_fn);
6481553Srgrimes			if (tp->f_fn[len - slen - 1] != '.')
64978749Sgad				continue;
65078749Sgad			if (strcasecmp(&tp->f_fn[len - slen], suff) != 0)
6511553Srgrimes				continue;
6521553Srgrimes			if ((len = 3 + len) + lpos > 72) {
65378749Sgad				lpos = 8;
6541553Srgrimes				fputs("\\\n\t", fp);
65570098Sume			}
6561553Srgrimes			if (tp->f_type != LOCAL)
65778300Sgad				fprintf(fp, "$S/%s ", tp->f_fn);
65870098Sume			else
65998776Sgad				fprintf(fp, "%s ", tp->f_fn);
660298592Sgad			lpos += len + 1;
6611553Srgrimes		}
66278749Sgad	if (lpos != 8)
66378749Sgad		putc('\n', fp);
6641553Srgrimes}
66578300Sgad
66678300Sgadstatic char *
66770098Sumetail(char *fn)
66878749Sgad{
66978300Sgad	char *cp;
670146188Sume
67198776Sgad	cp = rindex(fn, '/');
67298776Sgad	if (cp == 0)
67398776Sgad		return (fn);
67498776Sgad	return (cp+1);
67598776Sgad}
67698776Sgad
67798776Sgad/*
67898776Sgad * Create the makerules for each file
67998776Sgad * which is part of the system.
68098776Sgad */
68198776Sgadstatic void
68298776Sgaddo_rules(FILE *f)
68398776Sgad{
68498776Sgad	char *cp, *np, och;
68598776Sgad	struct file_list *ftp;
68698776Sgad	char *compilewith;
68798776Sgad
68870098Sume	STAILQ_FOREACH(ftp, &ftab, f_next) {
6891553Srgrimes		if (ftp->f_warn)
69078300Sgad			printf("WARNING: %s\n", ftp->f_warn);
69178300Sgad		cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
69298776Sgad		och = *cp;
69370098Sume		if (ftp->f_flags & NO_IMPLCT_RULE) {
69470098Sume			if (ftp->f_depends)
69578300Sgad				fprintf(f, "%s: %s\n", np, ftp->f_depends);
696146188Sume			else
69798776Sgad				fprintf(f, "%s: \n", np);
69898776Sgad		}
69998776Sgad		else {
70098776Sgad			*cp = '\0';
70198776Sgad			if (och == 'o') {
70298776Sgad				fprintf(f, "%so:\n\t-cp $S/%so .\n\n",
70398776Sgad					tail(np), np);
70478300Sgad				continue;
7051553Srgrimes			}
70670098Sume			if (ftp->f_depends) {
70770098Sume				fprintf(f, "%sln: $S/%s%c %s\n", tail(np),
70870098Sume					np, och, ftp->f_depends);
70970098Sume				fprintf(f, "\t${NORMAL_LINT}\n\n");
71070098Sume				fprintf(f, "%so: $S/%s%c %s\n", tail(np),
71178300Sgad					np, och, ftp->f_depends);
71270098Sume			}
71398776Sgad			else {
71498776Sgad				fprintf(f, "%sln: $S/%s%c\n", tail(np),
71598776Sgad					np, och);
71678749Sgad				fprintf(f, "\t${NORMAL_LINT}\n\n");
71798776Sgad				fprintf(f, "%so: $S/%s%c\n", tail(np),
71898776Sgad					np, och);
71998776Sgad			}
72070098Sume		}
72170098Sume		compilewith = ftp->f_compilewith;
72219202Simp		if (compilewith == 0) {
72370098Sume			const char *ftype = NULL;
72470098Sume			static char cmd[128];
72570098Sume
72678300Sgad			switch (ftp->f_type) {
72770098Sume
72898776Sgad			case NORMAL:
72998776Sgad				ftype = "NORMAL";
73098776Sgad				break;
73198776Sgad
73298776Sgad			case PROFILING:
73398776Sgad				if (!profiling)
73470098Sume					continue;
73570098Sume				ftype = "PROFILE";
73670098Sume				break;
73770098Sume
738146188Sume			default:
73970098Sume				printf("config: don't know rules for %s\n", np);
74019202Simp				break;
74119202Simp			}
74270098Sume			snprintf(cmd, sizeof(cmd), "${%s_%c%s}", ftype,
74370098Sume			    toupper(och),
74498776Sgad			    ftp->f_flags & NOWERROR ? "_NOWERROR" : "");
74598776Sgad			compilewith = cmd;
74698776Sgad		}
74798776Sgad		*cp = och;
74878749Sgad		fprintf(f, "\t%s\n\n", compilewith);
74998776Sgad	}
75098776Sgad}
75198776Sgad
75219202Simpstatic void
75378749Sgaddo_clean(FILE *fp)
7541553Srgrimes{
7551553Srgrimes	struct file_list *tp;
7561553Srgrimes	int lpos, len;
75770098Sume
7581553Srgrimes	fputs("CLEAN=", fp);
75978749Sgad	lpos = 7;
7601553Srgrimes	STAILQ_FOREACH(tp, &ftab, f_next)
7611553Srgrimes		if (tp->f_clean) {
7621553Srgrimes			len = strlen(tp->f_clean);
76378749Sgad			if (len + lpos > 72) {
76478749Sgad				lpos = 8;
7651553Srgrimes				fputs("\\\n\t", fp);
7661553Srgrimes			}
7671553Srgrimes			fprintf(fp, "%s ", tp->f_clean);
76898776Sgad			lpos += len + 1;
76998776Sgad		}
77098776Sgad	if (lpos != 8)
77178749Sgad		putc('\n', fp);
77298776Sgad}
77398776Sgad
77498776Sgadchar *
77598776Sgadraisestr(char *str)
77678749Sgad{
77778749Sgad	char *cp = str;
77878749Sgad
77978749Sgad	while (*str) {
78078749Sgad		if (islower(*str))
78178749Sgad			*str = toupper(*str);
78278749Sgad		str++;
78398776Sgad	}
78498776Sgad	return (cp);
78598776Sgad}
78698776Sgad