157492Storek /*
2*61818Sbostic  * Copyright (c) 1992, 1993
3*61818Sbostic  *	The Regents of the University of California.  All rights reserved.
457492Storek  *
557492Storek  * This software was developed by the Computer Systems Engineering group
657492Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
757492Storek  * contributed to Berkeley.
857492Storek  *
957492Storek  * All advertising materials mentioning features or use of this software
1057492Storek  * must display the following acknowledgement:
1157492Storek  *	This product includes software developed by the University of
1257492Storek  *	California, Lawrence Berkeley Laboratories.
1357492Storek  *
1457492Storek  * %sccs.include.redist.c%
1557492Storek  *
16*61818Sbostic  *	@(#)mkmakefile.c	8.1 (Berkeley) 06/06/93
1757492Storek  */
1857492Storek 
1957492Storek #include <sys/param.h>
2057492Storek #include <ctype.h>
2157492Storek #include <errno.h>
2257492Storek #include <stdio.h>
2357492Storek #include <stdlib.h>
2457492Storek #include <string.h>
2557492Storek #include "config.h"
2657492Storek 
2757492Storek /*
2857492Storek  * Make the Makefile.
2957492Storek  */
3057492Storek 
3157492Storek static int emitdefs __P((FILE *));
3257492Storek static int emitobjs __P((FILE *));
3357492Storek static int emitcfiles __P((FILE *));
3457492Storek static int emitsfiles __P((FILE *));
3557492Storek static int emitfiles __P((FILE *, int));
3657492Storek static int emitrules __P((FILE *));
3757492Storek static int emitload __P((FILE *));
3857492Storek 
3957492Storek int
mkmakefile()4057492Storek mkmakefile()
4157492Storek {
4257492Storek 	register FILE *ifp, *ofp;
4357492Storek 	register int lineno;
4457492Storek 	register int (*fn) __P((FILE *));
4557492Storek 	register char *ofname;
4657492Storek 	char line[BUFSIZ], ifname[200];
4757492Storek 
4857492Storek 	(void)sprintf(ifname, "Makefile.%s", machine);
4957492Storek 	if ((ifp = fopen(ifname, "r")) == NULL) {
5057492Storek 		(void)fprintf(stderr, "config: cannot read %s: %s\n",
5157492Storek 		    ifname, strerror(errno));
5257492Storek 		return (1);
5357492Storek 	}
5457492Storek 	ofname = path("Makefile");
5557492Storek 	if ((ofp = fopen(ofname, "w")) == NULL) {
5657492Storek 		(void)fprintf(stderr, "config: cannot write %s: %s\n",
5757492Storek 		    ofname, strerror(errno));
5857492Storek 		free(ofname);
5957492Storek 		return (1);
6057492Storek 	}
6157492Storek 	if (emitdefs(ofp) != 0)
6257492Storek 		goto wrerror;
6357492Storek 	lineno = 0;
6457492Storek 	while (fgets(line, sizeof(line), ifp) != NULL) {
6557492Storek 		lineno++;
6657492Storek 		if (line[0] != '%') {
6757492Storek 			if (fputs(line, ofp) < 0)
6857492Storek 				goto wrerror;
6957492Storek 			continue;
7057492Storek 		}
7157492Storek 		if (strcmp(line, "%OBJS\n") == 0)
7257492Storek 			fn = emitobjs;
7357492Storek 		else if (strcmp(line, "%CFILES\n") == 0)
7457492Storek 			fn = emitcfiles;
7557492Storek 		else if (strcmp(line, "%SFILES\n") == 0)
7657492Storek 			fn = emitsfiles;
7757492Storek 		else if (strcmp(line, "%RULES\n") == 0)
7857492Storek 			fn = emitrules;
7957492Storek 		else if (strcmp(line, "%LOAD\n") == 0)
8057492Storek 			fn = emitload;
8157492Storek 		else {
8257492Storek 			xerror(ifname, lineno,
8357492Storek 			    "unknown %% construct ignored: %s", line);
8457492Storek 			continue;
8557492Storek 		}
8657492Storek 		if ((*fn)(ofp))
8757492Storek 			goto wrerror;
8857492Storek 	}
8957492Storek 	if (ferror(ifp)) {
9057492Storek 		(void)fprintf(stderr,
9157492Storek 		    "config: error reading %s (at line %d): %s\n",
9257492Storek 		    ifname, lineno, strerror(errno));
9357492Storek 		goto bad;
9457492Storek 		/* (void)unlink(ofname); */
9557492Storek 		free(ofname);
9657492Storek 		return (1);
9757492Storek 	}
9857492Storek 	if (fclose(ofp)) {
9957492Storek 		ofp = NULL;
10057492Storek 		goto wrerror;
10157492Storek 	}
10257492Storek 	(void)fclose(ifp);
10357492Storek 	free(ofname);
10457492Storek 	return (0);
10557492Storek wrerror:
10657492Storek 	(void)fprintf(stderr, "config: error writing %s: %s\n",
10757492Storek 	    ofname, strerror(errno));
10857492Storek bad:
10957492Storek 	if (ofp != NULL)
11057492Storek 		(void)fclose(ofp);
11157492Storek 	/* (void)unlink(ofname); */
11257492Storek 	free(ofname);
11357492Storek 	return (1);
11457492Storek }
11557492Storek 
11657492Storek static int
emitdefs(fp)11757492Storek emitdefs(fp)
11857492Storek 	register FILE *fp;
11957492Storek {
12057492Storek 	register struct nvlist *nv;
12157492Storek 	register char *sp;
12257492Storek 
12357492Storek 	if (fputs("IDENT=", fp) < 0)
12457492Storek 		return (1);
12557492Storek 	sp = "";
12657492Storek 	for (nv = options; nv != NULL; nv = nv->nv_next) {
12757492Storek 		if (fprintf(fp, "%s-D%s%s%s", sp, nv->nv_name,
12857492Storek 		    nv->nv_str ? "=" : "", nv->nv_str ? nv->nv_str : "") < 0)
12957492Storek 			return (1);
13057492Storek 		sp = " ";
13157492Storek 	}
13257492Storek 	if (putc('\n', fp) < 0)
13357492Storek 		return (1);
13457492Storek 	if (fprintf(fp, "PARAM=-DMAXUSERS=%d\n", maxusers) < 0)
13557492Storek 		return (1);
13657492Storek 	for (nv = mkoptions; nv != NULL; nv = nv->nv_next)
13757492Storek 		if (fprintf(fp, "%s=%s\n", nv->nv_name, nv->nv_str) < 0)
13857492Storek 			return (1);
13957492Storek 	return (0);
14057492Storek }
14157492Storek 
14257492Storek static int
emitobjs(fp)14357492Storek emitobjs(fp)
14457492Storek 	register FILE *fp;
14557492Storek {
14657492Storek 	register struct files *fi;
14757492Storek 	register int lpos, len, sp;
14857492Storek 
14957492Storek 	if (fputs("OBJS=", fp) < 0)
15057492Storek 		return (1);
15157492Storek 	sp = '\t';
15257492Storek 	lpos = 7;
15357492Storek 	for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
15457492Storek 		if ((fi->fi_flags & FI_SEL) == 0)
15557492Storek 			continue;
15657492Storek 		len = strlen(fi->fi_base) + 2;
15757492Storek 		if (lpos + len > 72) {
15857492Storek 			if (fputs(" \\\n", fp) < 0)
15957492Storek 				return (1);
16057492Storek 			sp = '\t';
16157492Storek 			lpos = 7;
16257492Storek 		}
16357492Storek 		if (fprintf(fp, "%c%s.o", sp, fi->fi_base) < 0)
16457492Storek 			return (1);
16557492Storek 		lpos += len + 1;
16657492Storek 		sp = ' ';
16757492Storek 	}
16857492Storek 	if (lpos != 7 && putc('\n', fp) < 0)
16957492Storek 		return (1);
17057492Storek 	return (0);
17157492Storek }
17257492Storek 
17357492Storek static int
emitcfiles(fp)17457492Storek emitcfiles(fp)
17557492Storek 	FILE *fp;
17657492Storek {
17757492Storek 
17857492Storek 	return (emitfiles(fp, 'c'));
17957492Storek }
18057492Storek 
18157492Storek static int
emitsfiles(fp)18257492Storek emitsfiles(fp)
18357492Storek 	FILE *fp;
18457492Storek {
18557492Storek 
18657492Storek 	return (emitfiles(fp, 's'));
18757492Storek }
18857492Storek 
18957492Storek static int
emitfiles(fp,suffix)19057492Storek emitfiles(fp, suffix)
19157492Storek 	register FILE *fp;
19257492Storek 	int suffix;
19357492Storek {
19457492Storek 	register struct files *fi;
19557492Storek 	register struct config *cf;
19657492Storek 	register int lpos, len, sp;
19757492Storek 	char swapname[100];
19857492Storek 
19957492Storek 	if (fprintf(fp, "%cFILES=", toupper(suffix)) < 0)
20057492Storek 		return (1);
20157492Storek 	sp = '\t';
20257492Storek 	lpos = 7;
20357492Storek 	for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
20457492Storek 		if ((fi->fi_flags & FI_SEL) == 0)
20557492Storek 			continue;
20657492Storek 		len = strlen(fi->fi_path);
20757492Storek 		if (fi->fi_path[len - 1] != suffix)
20857492Storek 			continue;
20957492Storek 		if (*fi->fi_path != '/')
21057492Storek 			len += 3;	/* "$S/" */
21157492Storek 		if (lpos + len > 72) {
21257492Storek 			if (fputs(" \\\n", fp) < 0)
21357492Storek 				return (1);
21457492Storek 			sp = '\t';
21557492Storek 			lpos = 7;
21657492Storek 		}
21757492Storek 		if (fprintf(fp, "%c%s%s", sp, *fi->fi_path != '/' ? "$S/" : "",
21857492Storek 		    fi->fi_path) < 0)
21957492Storek 			return (1);
22057492Storek 		lpos += len + 1;
22157492Storek 		sp = ' ';
22257492Storek 	}
22360253Storek 	/*
22460253Storek 	 * The allfiles list does not include the configuration-specific
22560253Storek 	 * C source files.  These files should be eliminated someday, but
22660253Storek 	 * for now, we have to add them to ${CFILES} (and only ${CFILES}).
22760253Storek 	 */
22860253Storek 	if (suffix == 'c') {
22960253Storek 		for (cf = allcf; cf != NULL; cf = cf->cf_next) {
23060253Storek 			if (cf->cf_root == NULL)
23160253Storek 				(void)sprintf(swapname,
23260253Storek 				    "$S/%s/%s/swapgeneric.c",
23360253Storek 				    machine, machine);
23460253Storek 			else
23560253Storek 				(void)sprintf(swapname, "swap%s.c",
23660253Storek 				    cf->cf_name);
23760253Storek 			len = strlen(swapname);
23860253Storek 			if (lpos + len > 72) {
23960253Storek 				if (fputs(" \\\n", fp) < 0)
24060253Storek 					return (1);
24160253Storek 				sp = '\t';
24260253Storek 				lpos = 7;
24360253Storek 			}
24460253Storek 			if (fprintf(fp, "%c%s", sp, swapname) < 0)
24557492Storek 				return (1);
24660253Storek 			lpos += len + 1;
24760253Storek 			sp = ' ';
24857492Storek 		}
24957492Storek 	}
25057492Storek 	if (lpos != 7 && putc('\n', fp) < 0)
25157492Storek 		return (1);
25257492Storek 	return (0);
25357492Storek }
25457492Storek 
25557492Storek /*
25657492Storek  * Emit the make-rules.
25757492Storek  */
25857492Storek static int
emitrules(fp)25957492Storek emitrules(fp)
26057492Storek 	register FILE *fp;
26157492Storek {
26257492Storek 	register struct files *fi;
26357492Storek 	register const char *cp;
26457492Storek 	int ch;
26557492Storek 	char buf[200];
26657492Storek 
26757492Storek 	for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
26857492Storek 		if ((fi->fi_flags & FI_SEL) == 0)
26957492Storek 			continue;
27057492Storek 		if (fprintf(fp, "%s.o: %s%s\n", fi->fi_base,
27157492Storek 		    *fi->fi_path != '/' ? "$S/" : "", fi->fi_path) < 0)
27257492Storek 			return (1);
27357492Storek 		if ((cp = fi->fi_mkrule) == NULL) {
27457492Storek 			cp = fi->fi_flags & FI_DRIVER ? "DRIVER" : "NORMAL";
27557492Storek 			ch = fi->fi_lastc;
27657492Storek 			if (islower(ch))
27757492Storek 				ch = toupper(ch);
27857492Storek 			(void)sprintf(buf, "${%s_%c%s}", cp, ch,
27957492Storek 			    fi->fi_flags & FI_CONFIGDEP ? "_C" : "");
28057492Storek 			cp = buf;
28157492Storek 		}
28257492Storek 		if (fprintf(fp, "\t%s\n\n", cp) < 0)
28357492Storek 			return (1);
28457492Storek 	}
28557492Storek 	return (0);
28657492Storek }
28757492Storek 
28857492Storek /*
28957492Storek  * Emit the load commands.
29057492Storek  *
29157492Storek  * This function is not to be called `spurt'.
29257492Storek  */
29357492Storek static int
emitload(fp)29457492Storek emitload(fp)
29557492Storek 	register FILE *fp;
29657492Storek {
29757492Storek 	register struct config *cf;
29857492Storek 	register const char *nm, *swname;
29957492Storek 	int first;
30057492Storek 
30157492Storek 	if (fputs("all:", fp) < 0)
30257492Storek 		return (1);
30357492Storek 	for (cf = allcf; cf != NULL; cf = cf->cf_next) {
30457492Storek 		if (fprintf(fp, " %s", cf->cf_name) < 0)
30557492Storek 			return (1);
30657492Storek 	}
30757492Storek 	if (fputs("\n\n", fp) < 0)
30857492Storek 		return (1);
30957492Storek 	for (first = 1, cf = allcf; cf != NULL; cf = cf->cf_next) {
31057492Storek 		nm = cf->cf_name;
31157492Storek 		swname = cf->cf_root != NULL ? cf->cf_name : "generic";
31257492Storek 		if (fprintf(fp, "%s: ${SYSTEM_DEP} swap%s.o", nm, swname) < 0)
31357492Storek 			return (1);
31457492Storek 		if (first) {
31557492Storek 			if (fputs(" newvers", fp) < 0)
31657492Storek 				return (1);
31757492Storek 			first = 0;
31857492Storek 		}
31957492Storek 		if (fprintf(fp, "\n\
32057492Storek \t${SYSTEM_LD_HEAD}\n\
32157492Storek \t${SYSTEM_LD} swap%s.o\n\
32257492Storek \t${SYSTEM_LD_TAIL}\n\
32357492Storek \n\
32457492Storek swap%s.o: ", swname, swname) < 0)
32557492Storek 			return (1);
32657492Storek 		if (cf->cf_root != NULL) {
32757492Storek 			if (fprintf(fp, "swap%s.c\n", nm) < 0)
32857492Storek 				return (1);
32957492Storek 		} else {
33057492Storek 			if (fprintf(fp, "$S/%s/%s/swapgeneric.c\n",
33157492Storek 			    machine, machine) < 0)
33257492Storek 				return (1);
33357492Storek 		}
33457492Storek 		if (fputs("\t${NORMAL_C}\n\n", fp) < 0)
33557492Storek 			return (1);
33657492Storek 	}
33757492Storek 	return (0);
33857492Storek }
339