1*57492Storek /*
2*57492Storek  * Copyright (c) 1992 The Regents of the University of California.
3*57492Storek  * All rights reserved.
4*57492Storek  *
5*57492Storek  * This software was developed by the Computer Systems Engineering group
6*57492Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7*57492Storek  * contributed to Berkeley.
8*57492Storek  *
9*57492Storek  * All advertising materials mentioning features or use of this software
10*57492Storek  * must display the following acknowledgement:
11*57492Storek  *	This product includes software developed by the University of
12*57492Storek  *	California, Lawrence Berkeley Laboratories.
13*57492Storek  *
14*57492Storek  * %sccs.include.redist.c%
15*57492Storek  *
16*57492Storek  *	@(#)mkmakefile.c	5.1 (Berkeley) 01/12/93
17*57492Storek  *
18*57492Storek  * from: $Header: mkmakefile.c,v 1.6 93/01/12 03:58:45 torek Exp $
19*57492Storek  */
20*57492Storek 
21*57492Storek #include <sys/param.h>
22*57492Storek #include <ctype.h>
23*57492Storek #include <errno.h>
24*57492Storek #include <stdio.h>
25*57492Storek #include <stdlib.h>
26*57492Storek #include <string.h>
27*57492Storek #include "config.h"
28*57492Storek 
29*57492Storek /*
30*57492Storek  * Make the Makefile.
31*57492Storek  */
32*57492Storek 
33*57492Storek static int emitdefs __P((FILE *));
34*57492Storek static int emitobjs __P((FILE *));
35*57492Storek static int emitcfiles __P((FILE *));
36*57492Storek static int emitsfiles __P((FILE *));
37*57492Storek static int emitfiles __P((FILE *, int));
38*57492Storek static int emitrules __P((FILE *));
39*57492Storek static int emitload __P((FILE *));
40*57492Storek 
41*57492Storek int
42*57492Storek mkmakefile()
43*57492Storek {
44*57492Storek 	register FILE *ifp, *ofp;
45*57492Storek 	register int lineno;
46*57492Storek 	register int (*fn) __P((FILE *));
47*57492Storek 	register char *ofname;
48*57492Storek 	char line[BUFSIZ], ifname[200];
49*57492Storek 
50*57492Storek 	(void)sprintf(ifname, "Makefile.%s", machine);
51*57492Storek 	if ((ifp = fopen(ifname, "r")) == NULL) {
52*57492Storek 		(void)fprintf(stderr, "config: cannot read %s: %s\n",
53*57492Storek 		    ifname, strerror(errno));
54*57492Storek 		return (1);
55*57492Storek 	}
56*57492Storek 	ofname = path("Makefile");
57*57492Storek 	if ((ofp = fopen(ofname, "w")) == NULL) {
58*57492Storek 		(void)fprintf(stderr, "config: cannot write %s: %s\n",
59*57492Storek 		    ofname, strerror(errno));
60*57492Storek 		free(ofname);
61*57492Storek 		return (1);
62*57492Storek 	}
63*57492Storek 	if (emitdefs(ofp) != 0)
64*57492Storek 		goto wrerror;
65*57492Storek 	lineno = 0;
66*57492Storek 	while (fgets(line, sizeof(line), ifp) != NULL) {
67*57492Storek 		lineno++;
68*57492Storek 		if (line[0] != '%') {
69*57492Storek 			if (fputs(line, ofp) < 0)
70*57492Storek 				goto wrerror;
71*57492Storek 			continue;
72*57492Storek 		}
73*57492Storek 		if (strcmp(line, "%OBJS\n") == 0)
74*57492Storek 			fn = emitobjs;
75*57492Storek 		else if (strcmp(line, "%CFILES\n") == 0)
76*57492Storek 			fn = emitcfiles;
77*57492Storek 		else if (strcmp(line, "%SFILES\n") == 0)
78*57492Storek 			fn = emitsfiles;
79*57492Storek 		else if (strcmp(line, "%RULES\n") == 0)
80*57492Storek 			fn = emitrules;
81*57492Storek 		else if (strcmp(line, "%LOAD\n") == 0)
82*57492Storek 			fn = emitload;
83*57492Storek 		else {
84*57492Storek 			xerror(ifname, lineno,
85*57492Storek 			    "unknown %% construct ignored: %s", line);
86*57492Storek 			continue;
87*57492Storek 		}
88*57492Storek 		if ((*fn)(ofp))
89*57492Storek 			goto wrerror;
90*57492Storek 	}
91*57492Storek 	if (ferror(ifp)) {
92*57492Storek 		(void)fprintf(stderr,
93*57492Storek 		    "config: error reading %s (at line %d): %s\n",
94*57492Storek 		    ifname, lineno, strerror(errno));
95*57492Storek 		goto bad;
96*57492Storek 		/* (void)unlink(ofname); */
97*57492Storek 		free(ofname);
98*57492Storek 		return (1);
99*57492Storek 	}
100*57492Storek 	if (fclose(ofp)) {
101*57492Storek 		ofp = NULL;
102*57492Storek 		goto wrerror;
103*57492Storek 	}
104*57492Storek 	(void)fclose(ifp);
105*57492Storek 	free(ofname);
106*57492Storek 	return (0);
107*57492Storek wrerror:
108*57492Storek 	(void)fprintf(stderr, "config: error writing %s: %s\n",
109*57492Storek 	    ofname, strerror(errno));
110*57492Storek bad:
111*57492Storek 	if (ofp != NULL)
112*57492Storek 		(void)fclose(ofp);
113*57492Storek 	/* (void)unlink(ofname); */
114*57492Storek 	free(ofname);
115*57492Storek 	return (1);
116*57492Storek }
117*57492Storek 
118*57492Storek static int
119*57492Storek emitdefs(fp)
120*57492Storek 	register FILE *fp;
121*57492Storek {
122*57492Storek 	register struct nvlist *nv;
123*57492Storek 	register char *sp;
124*57492Storek 
125*57492Storek 	if (fputs("IDENT=", fp) < 0)
126*57492Storek 		return (1);
127*57492Storek 	sp = "";
128*57492Storek 	for (nv = options; nv != NULL; nv = nv->nv_next) {
129*57492Storek 		if (fprintf(fp, "%s-D%s%s%s", sp, nv->nv_name,
130*57492Storek 		    nv->nv_str ? "=" : "", nv->nv_str ? nv->nv_str : "") < 0)
131*57492Storek 			return (1);
132*57492Storek 		sp = " ";
133*57492Storek 	}
134*57492Storek 	if (putc('\n', fp) < 0)
135*57492Storek 		return (1);
136*57492Storek 	if (fprintf(fp, "PARAM=-DMAXUSERS=%d\n", maxusers) < 0)
137*57492Storek 		return (1);
138*57492Storek 	for (nv = mkoptions; nv != NULL; nv = nv->nv_next)
139*57492Storek 		if (fprintf(fp, "%s=%s\n", nv->nv_name, nv->nv_str) < 0)
140*57492Storek 			return (1);
141*57492Storek 	return (0);
142*57492Storek }
143*57492Storek 
144*57492Storek static int
145*57492Storek emitobjs(fp)
146*57492Storek 	register FILE *fp;
147*57492Storek {
148*57492Storek 	register struct files *fi;
149*57492Storek 	register int lpos, len, sp;
150*57492Storek 
151*57492Storek 	if (fputs("OBJS=", fp) < 0)
152*57492Storek 		return (1);
153*57492Storek 	sp = '\t';
154*57492Storek 	lpos = 7;
155*57492Storek 	for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
156*57492Storek 		if ((fi->fi_flags & FI_SEL) == 0)
157*57492Storek 			continue;
158*57492Storek 		len = strlen(fi->fi_base) + 2;
159*57492Storek 		if (lpos + len > 72) {
160*57492Storek 			if (fputs(" \\\n", fp) < 0)
161*57492Storek 				return (1);
162*57492Storek 			sp = '\t';
163*57492Storek 			lpos = 7;
164*57492Storek 		}
165*57492Storek 		if (fprintf(fp, "%c%s.o", sp, fi->fi_base) < 0)
166*57492Storek 			return (1);
167*57492Storek 		lpos += len + 1;
168*57492Storek 		sp = ' ';
169*57492Storek 	}
170*57492Storek 	if (lpos != 7 && putc('\n', fp) < 0)
171*57492Storek 		return (1);
172*57492Storek 	return (0);
173*57492Storek }
174*57492Storek 
175*57492Storek static int
176*57492Storek emitcfiles(fp)
177*57492Storek 	FILE *fp;
178*57492Storek {
179*57492Storek 
180*57492Storek 	return (emitfiles(fp, 'c'));
181*57492Storek }
182*57492Storek 
183*57492Storek static int
184*57492Storek emitsfiles(fp)
185*57492Storek 	FILE *fp;
186*57492Storek {
187*57492Storek 
188*57492Storek 	return (emitfiles(fp, 's'));
189*57492Storek }
190*57492Storek 
191*57492Storek static int
192*57492Storek emitfiles(fp, suffix)
193*57492Storek 	register FILE *fp;
194*57492Storek 	int suffix;
195*57492Storek {
196*57492Storek 	register struct files *fi;
197*57492Storek 	register struct config *cf;
198*57492Storek 	register int lpos, len, sp;
199*57492Storek 	char swapname[100];
200*57492Storek 
201*57492Storek 	if (fprintf(fp, "%cFILES=", toupper(suffix)) < 0)
202*57492Storek 		return (1);
203*57492Storek 	sp = '\t';
204*57492Storek 	lpos = 7;
205*57492Storek 	for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
206*57492Storek 		if ((fi->fi_flags & FI_SEL) == 0)
207*57492Storek 			continue;
208*57492Storek 		len = strlen(fi->fi_path);
209*57492Storek 		if (fi->fi_path[len - 1] != suffix)
210*57492Storek 			continue;
211*57492Storek 		if (*fi->fi_path != '/')
212*57492Storek 			len += 3;	/* "$S/" */
213*57492Storek 		if (lpos + len > 72) {
214*57492Storek 			if (fputs(" \\\n", fp) < 0)
215*57492Storek 				return (1);
216*57492Storek 			sp = '\t';
217*57492Storek 			lpos = 7;
218*57492Storek 		}
219*57492Storek 		if (fprintf(fp, "%c%s%s", sp, *fi->fi_path != '/' ? "$S/" : "",
220*57492Storek 		    fi->fi_path) < 0)
221*57492Storek 			return (1);
222*57492Storek 		lpos += len + 1;
223*57492Storek 		sp = ' ';
224*57492Storek 	}
225*57492Storek 	for (cf = allcf; cf != NULL; cf = cf->cf_next) {
226*57492Storek 		if (cf->cf_root == NULL)
227*57492Storek 			(void)sprintf(swapname, "$S/%s/%s/swapgeneric.c",
228*57492Storek 			    machine, machine);
229*57492Storek 		else
230*57492Storek 			(void)sprintf(swapname, "swap%s.c", cf->cf_name);
231*57492Storek 		len = strlen(swapname);
232*57492Storek 		if (lpos + len > 72) {
233*57492Storek 			if (fputs(" \\\n", fp) < 0)
234*57492Storek 				return (1);
235*57492Storek 			sp = '\t';
236*57492Storek 			lpos = 7;
237*57492Storek 		}
238*57492Storek 		if (fprintf(fp, "%c%s", sp, swapname) < 0)
239*57492Storek 			return (1);
240*57492Storek 		lpos += len + 1;
241*57492Storek 		sp = ' ';
242*57492Storek 	}
243*57492Storek 	if (lpos != 7 && putc('\n', fp) < 0)
244*57492Storek 		return (1);
245*57492Storek 	return (0);
246*57492Storek }
247*57492Storek 
248*57492Storek /*
249*57492Storek  * Emit the make-rules.
250*57492Storek  */
251*57492Storek static int
252*57492Storek emitrules(fp)
253*57492Storek 	register FILE *fp;
254*57492Storek {
255*57492Storek 	register struct files *fi;
256*57492Storek 	register const char *cp;
257*57492Storek 	int ch;
258*57492Storek 	char buf[200];
259*57492Storek 
260*57492Storek 	for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
261*57492Storek 		if ((fi->fi_flags & FI_SEL) == 0)
262*57492Storek 			continue;
263*57492Storek 		if (fprintf(fp, "%s.o: %s%s\n", fi->fi_base,
264*57492Storek 		    *fi->fi_path != '/' ? "$S/" : "", fi->fi_path) < 0)
265*57492Storek 			return (1);
266*57492Storek 		if ((cp = fi->fi_mkrule) == NULL) {
267*57492Storek 			cp = fi->fi_flags & FI_DRIVER ? "DRIVER" : "NORMAL";
268*57492Storek 			ch = fi->fi_lastc;
269*57492Storek 			if (islower(ch))
270*57492Storek 				ch = toupper(ch);
271*57492Storek 			(void)sprintf(buf, "${%s_%c%s}", cp, ch,
272*57492Storek 			    fi->fi_flags & FI_CONFIGDEP ? "_C" : "");
273*57492Storek 			cp = buf;
274*57492Storek 		}
275*57492Storek 		if (fprintf(fp, "\t%s\n\n", cp) < 0)
276*57492Storek 			return (1);
277*57492Storek 	}
278*57492Storek 	return (0);
279*57492Storek }
280*57492Storek 
281*57492Storek /*
282*57492Storek  * Emit the load commands.
283*57492Storek  *
284*57492Storek  * This function is not to be called `spurt'.
285*57492Storek  */
286*57492Storek static int
287*57492Storek emitload(fp)
288*57492Storek 	register FILE *fp;
289*57492Storek {
290*57492Storek 	register struct config *cf;
291*57492Storek 	register const char *nm, *swname;
292*57492Storek 	int first;
293*57492Storek 
294*57492Storek 	if (fputs("all:", fp) < 0)
295*57492Storek 		return (1);
296*57492Storek 	for (cf = allcf; cf != NULL; cf = cf->cf_next) {
297*57492Storek 		if (fprintf(fp, " %s", cf->cf_name) < 0)
298*57492Storek 			return (1);
299*57492Storek 	}
300*57492Storek 	if (fputs("\n\n", fp) < 0)
301*57492Storek 		return (1);
302*57492Storek 	for (first = 1, cf = allcf; cf != NULL; cf = cf->cf_next) {
303*57492Storek 		nm = cf->cf_name;
304*57492Storek 		swname = cf->cf_root != NULL ? cf->cf_name : "generic";
305*57492Storek 		if (fprintf(fp, "%s: ${SYSTEM_DEP} swap%s.o", nm, swname) < 0)
306*57492Storek 			return (1);
307*57492Storek 		if (first) {
308*57492Storek 			if (fputs(" newvers", fp) < 0)
309*57492Storek 				return (1);
310*57492Storek 			first = 0;
311*57492Storek 		}
312*57492Storek 		if (fprintf(fp, "\n\
313*57492Storek \t${SYSTEM_LD_HEAD}\n\
314*57492Storek \t${SYSTEM_LD} swap%s.o\n\
315*57492Storek \t${SYSTEM_LD_TAIL}\n\
316*57492Storek \n\
317*57492Storek swap%s.o: ", swname, swname) < 0)
318*57492Storek 			return (1);
319*57492Storek 		if (cf->cf_root != NULL) {
320*57492Storek 			if (fprintf(fp, "swap%s.c\n", nm) < 0)
321*57492Storek 				return (1);
322*57492Storek 		} else {
323*57492Storek 			if (fprintf(fp, "$S/%s/%s/swapgeneric.c\n",
324*57492Storek 			    machine, machine) < 0)
325*57492Storek 				return (1);
326*57492Storek 		}
327*57492Storek 		if (fputs("\t${NORMAL_C}\n\n", fp) < 0)
328*57492Storek 			return (1);
329*57492Storek 	}
330*57492Storek 	return (0);
331*57492Storek }
332