mkmakefile.c revision 1973
1130561Sobrien/*
2130561Sobrien * Copyright (c) 1993, 19801990
3218822Sdim *	The Regents of the University of California.  All rights reserved.
433965Sjdp *
5218822Sdim * Redistribution and use in source and binary forms, with or without
6130561Sobrien * modification, are permitted provided that the following conditions
7130561Sobrien * are met:
8218822Sdim * 1. Redistributions of source code must retain the above copyright
9218822Sdim *    notice, this list of conditions and the following disclaimer.
10218822Sdim * 2. Redistributions in binary form must reproduce the above copyright
1133965Sjdp *    notice, this list of conditions and the following disclaimer in the
12218822Sdim *    documentation and/or other materials provided with the distribution.
13218822Sdim * 3. All advertising materials mentioning features or use of this software
14218822Sdim *    must display the following acknowledgement:
15218822Sdim *	This product includes software developed by the University of
16218822Sdim *	California, Berkeley and its contributors.
17218822Sdim * 4. Neither the name of the University nor the names of its contributors
18218822Sdim *    may be used to endorse or promote products derived from this software
19218822Sdim *    without specific prior written permission.
20218822Sdim *
21218822Sdim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22218822Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23218822Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24218822Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25218822Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26218822Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27218822Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28218822Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29218822Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30218822Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31218822Sdim * SUCH DAMAGE.
32218822Sdim */
33218822Sdim
34218822Sdim#ifndef lint
35218822Sdimstatic char sccsid[] = "@(#)mkmakefile.c	8.1 (Berkeley) 6/6/93";
36218822Sdim#endif /* not lint */
37218822Sdim
38218822Sdim/*
39218822Sdim * Build the makefile for the system, from
40218822Sdim * the information in the files files and the
41218822Sdim * additional files for the machine being compiled to.
42218822Sdim */
43218822Sdim
44218822Sdim#include <stdio.h>
45218822Sdim#include <ctype.h>
46218822Sdim#include "y.tab.h"
47218822Sdim#include "config.h"
48218822Sdim
49218822Sdim#define next_word(fp, wd) \
50218822Sdim	{ register char *word = get_word(fp); \
51218822Sdim	  if (word == (char *)EOF) \
52218822Sdim		return; \
53218822Sdim	  else \
54218822Sdim		wd = word; \
55218822Sdim	}
56218822Sdim#define next_quoted_word(fp, wd) \
57218822Sdim	{ register char *word = get_quoted_word(fp); \
58218822Sdim	  if (word == (char *)EOF) \
59218822Sdim		return; \
60218822Sdim	  else \
61218822Sdim		wd = word; \
62218822Sdim	}
63218822Sdim
64218822Sdimstatic	struct file_list *fcur;
65218822Sdimchar *tail();
66218822Sdim
67218822Sdim/*
68218822Sdim * Lookup a file, by name.
69218822Sdim */
70218822Sdimstruct file_list *
71218822Sdimfl_lookup(file)
72218822Sdim	register char *file;
73218822Sdim{
74218822Sdim	register struct file_list *fp;
75218822Sdim
76218822Sdim	for (fp = ftab ; fp != 0; fp = fp->f_next) {
77218822Sdim		if (eq(fp->f_fn, file))
78218822Sdim			return (fp);
79218822Sdim	}
80218822Sdim	return (0);
81218822Sdim}
82218822Sdim
83218822Sdim/*
84218822Sdim * Lookup a file, by final component name.
85218822Sdim */
86218822Sdimstruct file_list *
87218822Sdimfltail_lookup(file)
88218822Sdim	register char *file;
89218822Sdim{
90218822Sdim	register struct file_list *fp;
91218822Sdim
92218822Sdim	for (fp = ftab ; fp != 0; fp = fp->f_next) {
93218822Sdim		if (eq(tail(fp->f_fn), tail(file)))
94218822Sdim			return (fp);
95218822Sdim	}
96218822Sdim	return (0);
97218822Sdim}
98218822Sdim
99218822Sdim/*
100218822Sdim * Make a new file list entry
101218822Sdim */
102218822Sdimstruct file_list *
103218822Sdimnew_fent()
104218822Sdim{
105218822Sdim	register struct file_list *fp;
106218822Sdim
107218822Sdim	fp = (struct file_list *) malloc(sizeof *fp);
108218822Sdim	bzero(fp, sizeof *fp);
109218822Sdim	if (fcur == 0)
110218822Sdim		fcur = ftab = fp;
111218822Sdim	else
112218822Sdim		fcur->f_next = fp;
113218822Sdim	fcur = fp;
114218822Sdim	return (fp);
115218822Sdim}
116218822Sdim
117218822Sdimstatic	struct users {
118218822Sdim	int	u_default;
119218822Sdim	int	u_min;
120218822Sdim	int	u_max;
121218822Sdim} users[] = {
122218822Sdim	{ 24, 8, 1024 },		/* MACHINE_VAX */
123218822Sdim	{ 4, 2, 128 },			/* MACHINE_TAHOE */
124218822Sdim	{ 8, 2, 64 },			/* MACHINE_HP300 */
125218822Sdim	{ 8, 2, 64 },			/* MACHINE_I386 */
126218822Sdim	{ 8, 2, 64 },			/* MACHINE_MIPS */
127218822Sdim	{ 8, 2, 64 },			/* MACHINE_PMAX */
128218822Sdim	{ 8, 2, 64 },			/* MACHINE_LUNA68K */
129218822Sdim	{ 8, 2, 64 },			/* MACHINE_NEWS3400 */
130218822Sdim};
131218822Sdim#define	NUSERS	(sizeof (users) / sizeof (users[0]))
132218822Sdim
133218822Sdim/*
134218822Sdim * Build the makefile from the skeleton
135218822Sdim */
136218822Sdimmakefile()
137218822Sdim{
138218822Sdim	FILE *ifp, *ofp;
139218822Sdim	char line[BUFSIZ];
140218822Sdim	struct opt *op;
141218822Sdim	struct users *up;
142218822Sdim
143218822Sdim	read_files();
144218822Sdim	strcpy(line, "Makefile.");
145218822Sdim	(void) strcat(line, machinename);
146218822Sdim	ifp = fopen(line, "r");
147218822Sdim	if (ifp == 0) {
148218822Sdim		perror(line);
149218822Sdim		exit(1);
150218822Sdim	}
151218822Sdim	ofp = fopen(path("Makefile"), "w");
152218822Sdim	if (ofp == 0) {
153218822Sdim		perror(path("Makefile"));
154218822Sdim		exit(1);
155218822Sdim	}
156218822Sdim	fprintf(ofp, "KERN_IDENT=%s\n", raise(ident));
157218822Sdim	fprintf(ofp, "IDENT=-D%s", raise(ident));
158218822Sdim	if (profiling)
159218822Sdim		fprintf(ofp, " -DGPROF");
160218822Sdim	if (cputype == 0) {
161218822Sdim		printf("cpu type must be specified\n");
162218822Sdim		exit(1);
163218822Sdim	}
164218822Sdim	{ struct cputype *cp;
165218822Sdim	  for (cp = cputype; cp; cp = cp->cpu_next)
166218822Sdim		fprintf(ofp, " -D%s", cp->cpu_name);
167218822Sdim	}
168218822Sdim	for (op = opt; op; op = op->op_next)
169218822Sdim		if (op->op_value)
170218822Sdim			fprintf(ofp, " -D%s=\"%s\"", op->op_name, op->op_value);
171218822Sdim		else
172218822Sdim			fprintf(ofp, " -D%s", op->op_name);
173218822Sdim	fprintf(ofp, "\n");
174218822Sdim	if ((unsigned)machine > NUSERS) {
175218822Sdim		printf("maxusers config info isn't present, using vax\n");
176218822Sdim		up = &users[MACHINE_VAX-1];
177218822Sdim	} else
178218822Sdim		up = &users[machine-1];
179218822Sdim	if (maxusers == 0) {
180218822Sdim		printf("maxusers not specified; %d assumed\n", up->u_default);
181218822Sdim		maxusers = up->u_default;
182218822Sdim	} else if (maxusers < up->u_min) {
183218822Sdim		printf("minimum of %d maxusers assumed\n", up->u_min);
184218822Sdim		maxusers = up->u_min;
185218822Sdim	} else if (maxusers > up->u_max)
186218822Sdim		printf("warning: maxusers > %d (%d)\n", up->u_max, maxusers);
187218822Sdim	fprintf(ofp, "PARAM=-DTIMEZONE=%d -DDST=%d -DMAXUSERS=%d\n",
188218822Sdim	    zone, dst, maxusers);
189218822Sdim	if (loadaddress != -1) {
190218822Sdim		fprintf(ofp, "LOAD_ADDRESS=%X\n", loadaddress);
191218822Sdim	}
192218822Sdim	for (op = mkopt; op; op = op->op_next)
193218822Sdim		fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
194218822Sdim	if (debugging)
195218822Sdim		fprintf(ofp, "DEBUG=-g\n");
196218822Sdim	if (profiling)
197218822Sdim		fprintf(ofp, "PROF=-pg\n");
198218822Sdim	while (fgets(line, BUFSIZ, ifp) != 0) {
199218822Sdim		if (*line != '%') {
200218822Sdim			fprintf(ofp, "%s", line);
201218822Sdim			continue;
202218822Sdim		}
203218822Sdim		if (eq(line, "%OBJS\n"))
204218822Sdim			do_objs(ofp);
205218822Sdim		else if (eq(line, "%CFILES\n"))
206218822Sdim			do_cfiles(ofp);
207218822Sdim		else if (eq(line, "%RULES\n"))
208218822Sdim			do_rules(ofp);
209218822Sdim		else if (eq(line, "%LOAD\n"))
210218822Sdim			do_load(ofp);
211218822Sdim		else
212218822Sdim			fprintf(stderr,
213218822Sdim			    "Unknown %% construct in generic makefile: %s",
214218822Sdim			    line);
215218822Sdim	}
216218822Sdim	(void) fclose(ifp);
217218822Sdim	(void) fclose(ofp);
218218822Sdim}
219218822Sdim
220218822Sdim/*
221218822Sdim * Read in the information about files used in making the system.
222218822Sdim * Store it in the ftab linked list.
223218822Sdim */
224218822Sdimread_files()
225218822Sdim{
226218822Sdim	FILE *fp;
227218822Sdim	register struct file_list *tp, *pf;
228218822Sdim	register struct device *dp;
229218822Sdim	struct device *save_dp;
230218822Sdim	register struct opt *op;
231218822Sdim	char *wd, *this, *needs, *special;
232218822Sdim	char fname[32];
233218822Sdim	int nreqs, first = 1, configdep, isdup, std, filetype;
234218822Sdim
235218822Sdim	ftab = 0;
236218822Sdim	(void) strcpy(fname, "../../conf/files");
237218822Sdimopenit:
238218822Sdim	fp = fopen(fname, "r");
239218822Sdim	if (fp == 0) {
240218822Sdim		perror(fname);
241218822Sdim		exit(1);
242218822Sdim	}
243218822Sdim	if(ident == NULL) {
244218822Sdim		printf("no ident line specified\n");
245218822Sdim		exit(1);
246218822Sdim	}
247218822Sdimnext:
248218822Sdim	/*
249218822Sdim	 * filename	[ standard | optional ] [ config-dependent ]
250218822Sdim	 *	[ dev* | profiling-routine ] [ device-driver]
251218822Sdim	 *	[ compile-with "compile rule" ]
252218822Sdim	 */
253218822Sdim	wd = get_word(fp);
254130561Sobrien	if (wd == (char *)EOF) {
255218822Sdim		(void) fclose(fp);
256218822Sdim		if (first == 1) {
257218822Sdim			(void) sprintf(fname, "files.%s", machinename);
258218822Sdim			first++;
259218822Sdim			goto openit;
260218822Sdim		}
26133965Sjdp		if (first == 2) {
262218822Sdim			(void) sprintf(fname, "files.%s", raise(ident));
263218822Sdim			first++;
264218822Sdim			fp = fopen(fname, "r");
265218822Sdim			if (fp != 0)
266218822Sdim				goto next;
267218822Sdim		}
268218822Sdim		return;
269218822Sdim	}
270218822Sdim	if (wd == 0)
271218822Sdim		goto next;
272218822Sdim	/*************************************************\
273218822Sdim	* If it's a comment ignore to the end of the line *
274218822Sdim	\*************************************************/
275218822Sdim	if(wd[0] == '#')
276218822Sdim	{
277218822Sdim		while( ((wd = get_word(fp)) != (char *)EOF) && wd)
278130561Sobrien		;
279218822Sdim		goto next;
280218822Sdim	}
281130561Sobrien	this = ns(wd);
282130561Sobrien	next_word(fp, wd);
283218822Sdim	if (wd == 0) {
284130561Sobrien		printf("%s: No type for %s.\n",
285130561Sobrien		    fname, this);
286130561Sobrien		exit(1);
287130561Sobrien	}
288130561Sobrien	if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags))
289130561Sobrien		isdup = 1;
290130561Sobrien	else
291130561Sobrien		isdup = 0;
29233965Sjdp	tp = 0;
29333965Sjdp	if (first == 3 && (tp = fltail_lookup(this)) != 0)
294130561Sobrien		printf("%s: Local file %s overrides %s.\n",
295130561Sobrien		    fname, this, tp->f_fn);
296130561Sobrien	nreqs = 0;
297218822Sdim	special = 0;
298218822Sdim	configdep = 0;
299218822Sdim	needs = 0;
300218822Sdim	std = 0;
301218822Sdim	filetype = NORMAL;
302218822Sdim	if (eq(wd, "standard"))
30338889Sjdp		std = 1;
30438889Sjdp	else if (!eq(wd, "optional")) {
30538889Sjdp		printf("%s: %s must be optional or standard\n", fname, this);
30638889Sjdp		exit(1);
30738889Sjdp	}
30838889Sjdpnextparam:
30938889Sjdp	next_word(fp, wd);
31038889Sjdp	if (wd == 0)
31138889Sjdp		goto doneparam;
31238889Sjdp	if (eq(wd, "config-dependent")) {
31338889Sjdp		configdep++;
31438889Sjdp		goto nextparam;
31533965Sjdp	}
316130561Sobrien	if (eq(wd, "compile-with")) {
317130561Sobrien		next_quoted_word(fp, wd);
318130561Sobrien		if (wd == 0) {
319130561Sobrien			printf("%s: %s missing compile command string.\n",
320130561Sobrien			       fname);
321130561Sobrien			exit(1);
322130561Sobrien		}
323130561Sobrien		special = ns(wd);
324130561Sobrien		goto nextparam;
325130561Sobrien	}
326218822Sdim	nreqs++;
327130561Sobrien	if (eq(wd, "device-driver")) {
328130561Sobrien		filetype = DRIVER;
329130561Sobrien		goto nextparam;
330218822Sdim	}
331130561Sobrien	if (eq(wd, "profiling-routine")) {
332130561Sobrien		filetype = PROFILING;
333130561Sobrien		goto nextparam;
334130561Sobrien	}
335218822Sdim	if (needs == 0 && nreqs == 1)
336130561Sobrien		needs = ns(wd);
337130561Sobrien	if (isdup)
338218822Sdim		goto invis;
339130561Sobrien	for (dp = dtab; dp != 0; save_dp = dp, dp = dp->d_next)
340218822Sdim		if (eq(dp->d_name, wd)) {
341130561Sobrien			if (std && dp->d_type == PSEUDO_DEVICE &&
342130561Sobrien			    dp->d_slave <= 0)
343130561Sobrien				dp->d_slave = 1;
344130561Sobrien			goto nextparam;
345130561Sobrien		}
346130561Sobrien	if (std) {
347218822Sdim		dp = (struct device *) malloc(sizeof *dp);
348130561Sobrien		init_dev(dp);
349218822Sdim		dp->d_name = ns(wd);
350218822Sdim		dp->d_type = PSEUDO_DEVICE;
351218822Sdim		dp->d_slave = 1;
352130561Sobrien		save_dp->d_next = dp;
353130561Sobrien		goto nextparam;
354130561Sobrien	}
355130561Sobrien	for (op = opt; op != 0; op = op->op_next)
356218822Sdim		if (op->op_value == 0 && opteq(op->op_name, wd)) {
357130561Sobrien			if (nreqs == 1) {
358130561Sobrien				free(needs);
359218822Sdim				needs = 0;
360130561Sobrien			}
361218822Sdim			goto nextparam;
362218822Sdim		}
363218822Sdiminvis:
364218822Sdim	while ((wd = get_word(fp)) != 0)
365218822Sdim		;
366130561Sobrien	if (tp == 0)
367130561Sobrien		tp = new_fent();
368218822Sdim	tp->f_fn = this;
369130561Sobrien	tp->f_type = INVISIBLE;
370218822Sdim	tp->f_needs = needs;
371218822Sdim	tp->f_flags = isdup;
372218822Sdim	tp->f_special = special;
373218822Sdim	goto next;
374218822Sdim
375218822Sdimdoneparam:
376130561Sobrien	if (std == 0 && nreqs == 0) {
377130561Sobrien		printf("%s: what is %s optional on?\n",
378218822Sdim		    fname, this);
379130561Sobrien		exit(1);
380130561Sobrien	}
381130561Sobrien
382130561Sobriensave:
383130561Sobrien	if (wd) {
384130561Sobrien		printf("%s: syntax error describing %s\n",
385130561Sobrien		    fname, this);
386130561Sobrien		exit(1);
387218822Sdim	}
388130561Sobrien	if (filetype == PROFILING && profiling == 0)
389130561Sobrien		goto next;
390130561Sobrien	if (tp == 0)
391130561Sobrien		tp = new_fent();
392130561Sobrien	tp->f_fn = this;
393218822Sdim	tp->f_type = filetype;
394218822Sdim	tp->f_flags = 0;
395218822Sdim	if (configdep)
396218822Sdim		tp->f_flags |= CONFIGDEP;
397218822Sdim	tp->f_needs = needs;
398218822Sdim	tp->f_special = special;
399130561Sobrien	if (pf && pf->f_type == INVISIBLE)
400130561Sobrien		pf->f_flags = 1;		/* mark as duplicate */
401218822Sdim	goto next;
402130561Sobrien}
403218822Sdim
404130561Sobrienopteq(cp, dp)
405130561Sobrien	char *cp, *dp;
406130561Sobrien{
407130561Sobrien	char c, d;
408130561Sobrien
409130561Sobrien	for (; ; cp++, dp++) {
410218822Sdim		if (*cp != *dp) {
411130561Sobrien			c = isupper(*cp) ? tolower(*cp) : *cp;
412130561Sobrien			d = isupper(*dp) ? tolower(*dp) : *dp;
413130561Sobrien			if (c != d)
414130561Sobrien				return (0);
415218822Sdim		}
416130561Sobrien		if (*cp == 0)
417130561Sobrien			return (1);
418130561Sobrien	}
419130561Sobrien}
420218822Sdim
421130561Sobriendo_objs(fp)
422130561Sobrien	FILE *fp;
423130561Sobrien{
424130561Sobrien	register struct file_list *tp, *fl;
425130561Sobrien	register int lpos, len;
426130561Sobrien	register char *cp, och, *sp;
427218822Sdim	char swapname[32];
428130561Sobrien
429130561Sobrien	fprintf(fp, "OBJS=");
430130561Sobrien	lpos = 6;
431130561Sobrien	for (tp = ftab; tp != 0; tp = tp->f_next) {
432130561Sobrien		if (tp->f_type == INVISIBLE)
433130561Sobrien			continue;
434130561Sobrien		sp = tail(tp->f_fn);
435130561Sobrien		for (fl = conf_list; fl; fl = fl->f_next) {
436218822Sdim			if (fl->f_type != SWAPSPEC)
437130561Sobrien				continue;
438130561Sobrien			(void) sprintf(swapname, "swap%s.c", fl->f_fn);
439130561Sobrien			if (eq(sp, swapname))
440130561Sobrien				goto cont;
441218822Sdim		}
442130561Sobrien		cp = sp + (len = strlen(sp)) - 1;
443130561Sobrien		och = *cp;
444130561Sobrien		*cp = 'o';
445130561Sobrien		if (len + lpos > 72) {
446130561Sobrien			lpos = 8;
447130561Sobrien			fprintf(fp, "\\\n\t");
448218822Sdim		}
449130561Sobrien		fprintf(fp, "%s ", sp);
450130561Sobrien		lpos += len + 1;
451130561Sobrien		*cp = och;
452130561Sobriencont:
453130561Sobrien		;
454130561Sobrien	}
455130561Sobrien	if (lpos != 8)
456130561Sobrien		putc('\n', fp);
457130561Sobrien}
458130561Sobrien
459130561Sobriendo_cfiles(fp)
460130561Sobrien	FILE *fp;
461130561Sobrien{
462218822Sdim	register struct file_list *tp, *fl;
463130561Sobrien	register int lpos, len;
464130561Sobrien	char swapname[32];
465130561Sobrien
466130561Sobrien	fputs("CFILES=", fp);
467218822Sdim	lpos = 8;
468130561Sobrien	for (tp = ftab; tp; tp = tp->f_next)
469130561Sobrien		if (tp->f_type != INVISIBLE) {
470130561Sobrien			len = strlen(tp->f_fn);
471130561Sobrien			if (tp->f_fn[len - 1] != 'c')
472130561Sobrien				continue;
473130561Sobrien			if ((len = 3 + len) + lpos > 72) {
474218822Sdim				lpos = 8;
475130561Sobrien				fputs("\\\n\t", fp);
476130561Sobrien			}
477130561Sobrien			fprintf(fp, "$S/%s ", tp->f_fn);
478130561Sobrien			lpos += len + 1;
479130561Sobrien		}
480130561Sobrien	for (fl = conf_list; fl; fl = fl->f_next)
481218822Sdim		if (fl->f_type == SYSTEMSPEC) {
482130561Sobrien			(void) sprintf(swapname, "swap%s.c", fl->f_fn);
483130561Sobrien			if ((len = 3 + strlen(swapname)) + lpos > 72) {
484130561Sobrien				lpos = 8;
485130561Sobrien				fputs("\\\n\t", fp);
486130561Sobrien			}
487130561Sobrien			if (eq(fl->f_fn, "generic"))
488130561Sobrien				fprintf(fp, "$S/%s/%s/%s ",
489130561Sobrien				    machinename, machinename, swapname);
490130561Sobrien			else
491130561Sobrien				fprintf(fp, "%s ", swapname);
492130561Sobrien			lpos += len + 1;
493130561Sobrien		}
494130561Sobrien	if (lpos != 8)
495130561Sobrien		putc('\n', fp);
496130561Sobrien}
497130561Sobrien
498218822Sdimchar *
499130561Sobrientail(fn)
500130561Sobrien	char *fn;
501130561Sobrien{
502130561Sobrien	register char *cp;
503130561Sobrien
504130561Sobrien	cp = rindex(fn, '/');
505130561Sobrien	if (cp == 0)
506130561Sobrien		return (fn);
507130561Sobrien	return (cp+1);
508218822Sdim}
509130561Sobrien
510130561Sobrien/*
511130561Sobrien * Create the makerules for each file
512130561Sobrien * which is part of the system.
513130561Sobrien * Devices are processed with the special c2 option -i
514130561Sobrien * which avoids any problem areas with i/o addressing
515130561Sobrien * (e.g. for the VAX); assembler files are processed by as.
516130561Sobrien */
517130561Sobriendo_rules(f)
518130561Sobrien	FILE *f;
519218822Sdim{
520130561Sobrien	register char *cp, *np, och, *tp;
521130561Sobrien	register struct file_list *ftp;
522130561Sobrien	char *special;
523130561Sobrien
524218822Sdim	for (ftp = ftab; ftp != 0; ftp = ftp->f_next) {
525130561Sobrien		if (ftp->f_type == INVISIBLE)
526130561Sobrien			continue;
527130561Sobrien		cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
528130561Sobrien		och = *cp;
529218822Sdim		*cp = '\0';
530130561Sobrien		if (och == 'o') {
531130561Sobrien			fprintf(f, "%so:\n\t-cp $S/%so .\n\n", tail(np), np);
532130561Sobrien			continue;
533130561Sobrien		}
534130561Sobrien		fprintf(f, "%so: $S/%s%c\n", tail(np), np, och);
535130561Sobrien		tp = tail(np);
536218822Sdim		special = ftp->f_special;
537130561Sobrien		if (special == 0) {
538130561Sobrien			char *ftype;
539218822Sdim			static char cmd[128];
540130561Sobrien
541218822Sdim			switch (ftp->f_type) {
542130561Sobrien
543130561Sobrien			case NORMAL:
544130561Sobrien				ftype = "NORMAL";
545130561Sobrien				break;
546218822Sdim
547218822Sdim			case DRIVER:
548130561Sobrien				ftype = "DRIVER";
549130561Sobrien				break;
550218822Sdim
551130561Sobrien			case PROFILING:
552218822Sdim				if (!profiling)
553218822Sdim					continue;
554218822Sdim				ftype = "PROFILE";
555130561Sobrien				break;
556218822Sdim
557218822Sdim			default:
558130561Sobrien				printf("config: don't know rules for %s\n", np);
559130561Sobrien				break;
560218822Sdim			}
561130561Sobrien			(void)sprintf(cmd, "${%s_%c%s}", ftype, toupper(och),
562130561Sobrien				      ftp->f_flags & CONFIGDEP? "_C" : "");
563218822Sdim			special = cmd;
564130561Sobrien		}
565218822Sdim		*cp = och;
566218822Sdim		fprintf(f, "\t%s\n\n", special);
567218822Sdim	}
568218822Sdim}
569218822Sdim
570130561Sobrien/*
571130561Sobrien * Create the load strings
572130561Sobrien */
573130561Sobriendo_load(f)
574130561Sobrien	register FILE *f;
575130561Sobrien{
576130561Sobrien	register struct file_list *fl;
577130561Sobrien	register int first;
578130561Sobrien	struct file_list *do_systemspec();
579130561Sobrien
580218822Sdim	for (first = 1, fl = conf_list; fl; first = 0)
581130561Sobrien		fl = fl->f_type == SYSTEMSPEC ?
582130561Sobrien			do_systemspec(f, fl, first) : fl->f_next;
583130561Sobrien	fputs("all:", f);
584130561Sobrien	for (fl = conf_list; fl; fl = fl->f_next)
585130561Sobrien		if (fl->f_type == SYSTEMSPEC)
586130561Sobrien			fprintf(f, " %s", fl->f_needs);
587218822Sdim	putc('\n', f);
588130561Sobrien}
589218822Sdim
590218822Sdimstruct file_list *
591218822Sdimdo_systemspec(f, fl, first)
592130561Sobrien	FILE *f;
593130561Sobrien	register struct file_list *fl;
594218822Sdim	int first;
595218822Sdim{
596218822Sdim
597218822Sdim	fprintf(f, "%s: ${SYSTEM_DEP} swap%s.o", fl->f_needs, fl->f_fn);
598218822Sdim	if (first)
599218822Sdim		fprintf(f, " vers.o");
600218822Sdim	fprintf(f, "\n\t${SYSTEM_LD_HEAD}\n");
601218822Sdim	fprintf(f, "\t${SYSTEM_LD} swap%s.o\n", fl->f_fn);
602218822Sdim	fprintf(f, "\t${SYSTEM_LD_TAIL}\n\n");
603218822Sdim	do_swapspec(f, fl->f_fn);
604130561Sobrien	for (fl = fl->f_next; fl; fl = fl->f_next)
605218822Sdim		if (fl->f_type != SWAPSPEC)
606218822Sdim			break;
607218822Sdim	return (fl);
608218822Sdim}
609218822Sdim
610130561Sobriendo_swapspec(f, name)
611130561Sobrien	FILE *f;
612130561Sobrien	register char *name;
613130561Sobrien{
614130561Sobrien
615130561Sobrien	if (!eq(name, "generic"))
616218822Sdim		fprintf(f, "swap%s.o: swap%s.c\n", name, name);
617218822Sdim	else
618218822Sdim		fprintf(f, "swapgeneric.o: $S/%s/%s/swapgeneric.c\n",
619130561Sobrien			machinename, machinename);
620130561Sobrien	fprintf(f, "\t${NORMAL_C}\n\n");
621218822Sdim}
622218822Sdim
623218822Sdimchar *
624218822Sdimraise(str)
625218822Sdim	register char *str;
626218822Sdim{
627218822Sdim	register char *cp = str;
628218822Sdim
629218822Sdim	while (*str) {
630218822Sdim		if (islower(*str))
631130561Sobrien			*str = toupper(*str);
632218822Sdim		str++;
633218822Sdim	}
634218822Sdim	return (cp);
635130561Sobrien}
636218822Sdim