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