mkmakefile.c revision 20395
1179187Sjb/*
2179187Sjb * Copyright (c) 1993, 19801990
3179187Sjb *	The Regents of the University of California.  All rights reserved.
4179187Sjb *
5179187Sjb * Redistribution and use in source and binary forms, with or without
6179187Sjb * modification, are permitted provided that the following conditions
7179187Sjb * are met:
8179187Sjb * 1. Redistributions of source code must retain the above copyright
9179187Sjb *    notice, this list of conditions and the following disclaimer.
10179187Sjb * 2. Redistributions in binary form must reproduce the above copyright
11179187Sjb *    notice, this list of conditions and the following disclaimer in the
12179187Sjb *    documentation and/or other materials provided with the distribution.
13179187Sjb * 3. All advertising materials mentioning features or use of this software
14179187Sjb *    must display the following acknowledgement:
15179187Sjb *	This product includes software developed by the University of
16179187Sjb *	California, Berkeley and its contributors.
17179187Sjb * 4. Neither the name of the University nor the names of its contributors
18179187Sjb *    may be used to endorse or promote products derived from this software
19179187Sjb *    without specific prior written permission.
20179187Sjb *
21179187Sjb * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22179187Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23179187Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24179187Sjb * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25179187Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26179187Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27179187Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28179187Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29179187Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30179187Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31179187Sjb * SUCH DAMAGE.
32179187Sjb */
33179187Sjb
34179187Sjb#ifndef lint
35179187Sjbstatic char sccsid[] = "@(#)mkmakefile.c	8.1 (Berkeley) 6/6/93";
36179187Sjb#endif /* not lint */
37179187Sjb
38179187Sjb/*
39179187Sjb * Build the makefile for the system, from
40179187Sjb * the information in the files files and the
41179187Sjb * additional files for the machine being compiled to.
42179187Sjb */
43179187Sjb
44179187Sjb#include <stdio.h>
45179187Sjb#include <ctype.h>
46179187Sjb#include "y.tab.h"
47179187Sjb#include "config.h"
48
49#define next_word(fp, wd) \
50	{ register char *word = get_word(fp); \
51	  if (word == (char *)EOF) \
52		return; \
53	  else \
54		wd = word; \
55	}
56#define next_quoted_word(fp, wd) \
57	{ register char *word = get_quoted_word(fp); \
58	  if (word == (char *)EOF) \
59		return; \
60	  else \
61		wd = word; \
62	}
63
64static	struct file_list *fcur;
65char *tail();
66extern int old_config_present;
67
68/*
69 * Lookup a file, by name.
70 */
71struct file_list *
72fl_lookup(file)
73	register char *file;
74{
75	register struct file_list *fp;
76
77	for (fp = ftab ; fp != 0; fp = fp->f_next) {
78		if (eq(fp->f_fn, file))
79			return (fp);
80	}
81	return (0);
82}
83
84/*
85 * Lookup a file, by final component name.
86 */
87struct file_list *
88fltail_lookup(file)
89	register char *file;
90{
91	register struct file_list *fp;
92
93	for (fp = ftab ; fp != 0; fp = fp->f_next) {
94		if (eq(tail(fp->f_fn), tail(file)))
95			return (fp);
96	}
97	return (0);
98}
99
100/*
101 * Make a new file list entry
102 */
103struct file_list *
104new_fent()
105{
106	register struct file_list *fp;
107
108	fp = (struct file_list *) malloc(sizeof *fp);
109	bzero(fp, sizeof *fp);
110	if (fcur == 0)
111		fcur = ftab = fp;
112	else
113		fcur->f_next = fp;
114	fcur = fp;
115	return (fp);
116}
117
118static	struct users {
119	int	u_default;
120	int	u_min;
121	int	u_max;
122} users[] = {
123	{ 8, 2, 512 },			/* MACHINE_VAX */
124	{ 8, 2, 512 },			/* MACHINE_TAHOE */
125	{ 8, 2, 512 },			/* MACHINE_HP300 */
126	{ 8, 2, 512 },			/* MACHINE_I386 */
127	{ 8, 2, 512 },			/* MACHINE_MIPS */
128	{ 8, 2, 512 },			/* MACHINE_PMAX */
129	{ 8, 2, 512 },			/* MACHINE_LUNA68K */
130	{ 8, 2, 512 },			/* MACHINE_NEWS3400 */
131};
132#define	NUSERS	(sizeof (users) / sizeof (users[0]))
133
134/*
135 * Build the makefile from the skeleton
136 */
137makefile()
138{
139	FILE *ifp, *ofp;
140	char line[BUFSIZ];
141	struct opt *op;
142	struct users *up;
143	int warn_make_clean = 0;
144
145	read_files();
146	strcpy(line, "Makefile.");
147	(void) strcat(line, machinename);
148	ifp = fopen(line, "r");
149	if (ifp == 0) {
150		perror(line);
151		exit(1);
152	}
153	ofp = fopen(path("Makefile.new"), "w");
154	if (ofp == 0) {
155		perror(path("Makefile.new"));
156		exit(1);
157	}
158	fprintf(ofp, "KERN_IDENT=%s\n", raise(ident));
159	fprintf(ofp, "IDENT=");
160	if (profiling)
161		fprintf(ofp, " -DGPROF");
162
163	if (cputype == 0) {
164		printf("cpu type must be specified\n");
165		exit(1);
166	}
167#if 0
168	/* XXX: moved to cputype.h */
169	{ struct cputype *cp;
170	  for (cp = cputype; cp; cp = cp->cpu_next)
171		fprintf(ofp, " -D%s", cp->cpu_name);
172	}
173#endif
174	for (op = opt; op; op = op->op_next) {
175		if (!op->op_ownfile) {
176			warn_make_clean++;
177			if (op->op_value)
178				fprintf(ofp, " -D%s=%s", op->op_name, op->op_value);
179			else
180				fprintf(ofp, " -D%s", op->op_name);
181		}
182	}
183	fprintf(ofp, "\n");
184	if ((unsigned)machine > NUSERS) {
185		printf("maxusers config info isn't present, using vax\n");
186		up = &users[MACHINE_VAX-1];
187	} else
188		up = &users[machine-1];
189	if (maxusers == 0) {
190		printf("maxusers not specified; %d assumed\n", up->u_default);
191		maxusers = up->u_default;
192	} else if (maxusers < up->u_min) {
193		printf("minimum of %d maxusers assumed\n", up->u_min);
194		maxusers = up->u_min;
195	} else if (maxusers > up->u_max)
196		printf("warning: maxusers > %d (%d)\n", up->u_max, maxusers);
197	fprintf(ofp, "PARAM=-DMAXUSERS=%d\n", maxusers);
198	if (loadaddress != -1) {
199		fprintf(ofp, "LOAD_ADDRESS=%X\n", loadaddress);
200	}
201	for (op = mkopt; op; op = op->op_next)
202		fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
203	if (debugging)
204		fprintf(ofp, "DEBUG=-g\n");
205	if (profiling) {
206		fprintf(ofp, "PROF=-pg\n");
207		fprintf(ofp, "PROFLEVEL=%d\n", profiling);
208	}
209	while (fgets(line, BUFSIZ, ifp) != 0) {
210		if (*line != '%') {
211			fprintf(ofp, "%s", line);
212			continue;
213		}
214		if (eq(line, "%BEFORE_DEPEND\n"))
215			do_before_depend(ofp);
216		else if (eq(line, "%OBJS\n"))
217			do_objs(ofp);
218		else if (eq(line, "%CFILES\n"))
219			do_cfiles(ofp);
220		else if (eq(line, "%SFILES\n"))
221			do_sfiles(ofp);
222		else if (eq(line, "%RULES\n"))
223			do_rules(ofp);
224		else if (eq(line, "%LOAD\n"))
225			do_load(ofp);
226		else if (eq(line, "%CLEAN\n"))
227			do_clean(ofp);
228		else
229			fprintf(stderr,
230			    "Unknown %% construct in generic makefile: %s",
231			    line);
232	}
233	(void) fclose(ifp);
234	(void) fclose(ofp);
235	moveifchanged(path("Makefile.new"), path("Makefile"));
236#ifdef notyet
237	if (warn_make_clean) {
238		printf("WARNING: Unknown options used (not in ../../conf/options or ./options.%s).\n", machinename);
239	 	if (old_config_present) {
240			printf("It is VERY important that you do a ``make clean'' before recompiling!\n");
241		}
242	}
243	printf("Don't forget to do a ``make depend''\n");
244#endif
245}
246
247/*
248 * Read in the information about files used in making the system.
249 * Store it in the ftab linked list.
250 */
251read_files()
252{
253	FILE *fp;
254	register struct file_list *tp, *pf;
255	register struct device *dp;
256	struct device *save_dp;
257	register struct opt *op;
258	char *wd, *this, *needs, *special, *depends, *clean;
259	char fname[32];
260	int nreqs, first = 1, configdep, isdup, std, filetype,
261	    imp_rule, no_obj, before_depend;
262
263	ftab = 0;
264	(void) strcpy(fname, "../../conf/files");
265openit:
266	fp = fopen(fname, "r");
267	if (fp == 0) {
268		perror(fname);
269		exit(1);
270	}
271	if(ident == NULL) {
272		printf("no ident line specified\n");
273		exit(1);
274	}
275next:
276	/*
277	 * filename	[ standard | optional ] [ config-dependent ]
278	 *	[ dev* | profiling-routine ] [ device-driver] [ no-obj ]
279	 *	[ compile-with "compile rule" [no-implicit-rule] ]
280	 *      [ dependency "dependency-list"] [ before-depend ]
281	 *	[ clean "file-list"]
282	 */
283	wd = get_word(fp);
284	if (wd == (char *)EOF) {
285		(void) fclose(fp);
286		if (first == 1) {
287			(void) sprintf(fname, "files.%s", machinename);
288			first++;
289			goto openit;
290		}
291		if (first == 2) {
292			(void) sprintf(fname, "files.%s", raise(ident));
293			first++;
294			fp = fopen(fname, "r");
295			if (fp != 0)
296				goto next;
297		}
298		return;
299	}
300	if (wd == 0)
301		goto next;
302	/*************************************************\
303	* If it's a comment ignore to the end of the line *
304	\*************************************************/
305	if(wd[0] == '#')
306	{
307		while( ((wd = get_word(fp)) != (char *)EOF) && wd)
308		;
309		goto next;
310	}
311	this = ns(wd);
312	next_word(fp, wd);
313	if (wd == 0) {
314		printf("%s: No type for %s.\n",
315		    fname, this);
316		exit(1);
317	}
318	if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags))
319		isdup = 1;
320	else
321		isdup = 0;
322	tp = 0;
323	if (first == 3 && (tp = fltail_lookup(this)) != 0)
324		printf("%s: Local file %s overrides %s.\n",
325		    fname, this, tp->f_fn);
326	nreqs = 0;
327	special = 0;
328	depends = 0;
329	clean = 0;
330	configdep = 0;
331	needs = 0;
332	std = 0;
333	imp_rule = 0;
334	no_obj = 0;
335	before_depend = 0;
336	filetype = NORMAL;
337	if (eq(wd, "standard"))
338		std = 1;
339	else if (!eq(wd, "optional")) {
340		printf("%s: %s must be optional or standard\n", fname, this);
341		exit(1);
342	}
343nextparam:
344	next_word(fp, wd);
345	if (wd == 0)
346		goto doneparam;
347	if (eq(wd, "config-dependent")) {
348		configdep++;
349		goto nextparam;
350	}
351	if (eq(wd, "no-obj")) {
352		no_obj++;
353		goto nextparam;
354	}
355	if (eq(wd, "no-implicit-rule")) {
356		if (special == 0) {
357			printf("%s: alternate rule required when "
358			       "\"no-implicit-rule\" is specified.\n",
359			       fname);
360		}
361		imp_rule++;
362		goto nextparam;
363	}
364	if (eq(wd, "before-depend")) {
365		before_depend++;
366		goto nextparam;
367	}
368	if (eq(wd, "dependency")) {
369		next_quoted_word(fp, wd);
370		if (wd == 0) {
371			printf("%s: %s missing compile command string.\n",
372			       fname, this);
373			exit(1);
374		}
375		depends = ns(wd);
376		goto nextparam;
377	}
378	if (eq(wd, "clean")) {
379		next_quoted_word(fp, wd);
380		if (wd == 0) {
381			printf("%s: %s missing clean file list.\n",
382			       fname, this);
383			exit(1);
384		}
385		clean = ns(wd);
386		goto nextparam;
387	}
388	if (eq(wd, "compile-with")) {
389		next_quoted_word(fp, wd);
390		if (wd == 0) {
391			printf("%s: %s missing compile command string.\n",
392			       fname, this);
393			exit(1);
394		}
395		special = ns(wd);
396		goto nextparam;
397	}
398	nreqs++;
399	if (eq(wd, "device-driver")) {
400		filetype = DRIVER;
401		goto nextparam;
402	}
403	if (eq(wd, "profiling-routine")) {
404		filetype = PROFILING;
405		goto nextparam;
406	}
407	if (needs == 0 && nreqs == 1)
408		needs = ns(wd);
409	if (isdup)
410		goto invis;
411	for (dp = dtab; dp != 0; save_dp = dp, dp = dp->d_next)
412		if (eq(dp->d_name, wd)) {
413			if (std && dp->d_type == PSEUDO_DEVICE &&
414			    dp->d_slave <= 0)
415				dp->d_slave = 1;
416			goto nextparam;
417		}
418	if (std) {
419		dp = (struct device *) malloc(sizeof *dp);
420		bzero(dp, sizeof *dp);
421		init_dev(dp);
422		dp->d_name = ns(wd);
423		dp->d_type = PSEUDO_DEVICE;
424		dp->d_slave = 1;
425		save_dp->d_next = dp;
426		goto nextparam;
427	}
428	for (op = opt; op != 0; op = op->op_next)
429		if (op->op_value == 0 && opteq(op->op_name, wd)) {
430			if (nreqs == 1) {
431				free(needs);
432				needs = 0;
433			}
434			goto nextparam;
435		}
436invis:
437	while ((wd = get_word(fp)) != 0)
438		;
439	if (tp == 0)
440		tp = new_fent();
441	tp->f_fn = this;
442	tp->f_type = INVISIBLE;
443	tp->f_needs = needs;
444	tp->f_flags = isdup;
445	tp->f_special = special;
446	tp->f_depends = depends;
447	tp->f_clean = clean;
448	goto next;
449
450doneparam:
451	if (std == 0 && nreqs == 0) {
452		printf("%s: what is %s optional on?\n",
453		    fname, this);
454		exit(1);
455	}
456
457save:
458	if (wd) {
459		printf("%s: syntax error describing %s\n",
460		    fname, this);
461		exit(1);
462	}
463	if (filetype == PROFILING && profiling == 0)
464		goto next;
465	if (tp == 0)
466		tp = new_fent();
467	tp->f_fn = this;
468	tp->f_type = filetype;
469	tp->f_flags = 0;
470	if (configdep)
471		tp->f_flags |= CONFIGDEP;
472	if (imp_rule)
473		tp->f_flags |= NO_IMPLCT_RULE;
474	if (no_obj)
475		tp->f_flags |= NO_OBJ;
476	if (before_depend)
477		tp->f_flags |= BEFORE_DEPEND;
478	if (imp_rule)
479		tp->f_flags |= NO_IMPLCT_RULE;
480	if (no_obj)
481		tp->f_flags |= NO_OBJ;
482	tp->f_needs = needs;
483	tp->f_special = special;
484	tp->f_depends = depends;
485	tp->f_clean = clean;
486	if (pf && pf->f_type == INVISIBLE)
487		pf->f_flags = 1;		/* mark as duplicate */
488	goto next;
489}
490
491opteq(cp, dp)
492	char *cp, *dp;
493{
494	char c, d;
495
496	for (; ; cp++, dp++) {
497		if (*cp != *dp) {
498			c = isupper(*cp) ? tolower(*cp) : *cp;
499			d = isupper(*dp) ? tolower(*dp) : *dp;
500			if (c != d)
501				return (0);
502		}
503		if (*cp == 0)
504			return (1);
505	}
506}
507
508do_before_depend(fp)
509	FILE *fp;
510{
511	register struct file_list *tp, *fl;
512	register int lpos, len;
513	char swapname[32];
514
515	fputs("BEFORE_DEPEND=", fp);
516	lpos = 15;
517	for (tp = ftab; tp; tp = tp->f_next)
518		if (tp->f_flags & BEFORE_DEPEND) {
519			len = strlen(tp->f_fn);
520			if ((len = 3 + len) + lpos > 72) {
521				lpos = 8;
522				fputs("\\\n\t", fp);
523			}
524			if (tp->f_flags & NO_IMPLCT_RULE)
525				fprintf(fp, "%s ", tp->f_fn);
526			else
527				fprintf(fp, "$S/%s ", tp->f_fn);
528			lpos += len + 1;
529		}
530	if (lpos != 8)
531		putc('\n', fp);
532}
533
534do_objs(fp)
535	FILE *fp;
536{
537	register struct file_list *tp, *fl;
538	register int lpos, len;
539	register char *cp, och, *sp;
540	char swapname[32];
541
542	fprintf(fp, "OBJS=");
543	lpos = 6;
544	for (tp = ftab; tp != 0; tp = tp->f_next) {
545		if (tp->f_type == INVISIBLE || tp->f_flags & NO_OBJ)
546			continue;
547		sp = tail(tp->f_fn);
548		for (fl = conf_list; fl; fl = fl->f_next) {
549			if (fl->f_type != SWAPSPEC)
550				continue;
551			(void) sprintf(swapname, "swap%s.c", fl->f_fn);
552			if (eq(sp, swapname))
553				goto cont;
554		}
555		cp = sp + (len = strlen(sp)) - 1;
556		och = *cp;
557		*cp = 'o';
558		if (len + lpos > 72) {
559			lpos = 8;
560			fprintf(fp, "\\\n\t");
561		}
562		fprintf(fp, "%s ", sp);
563		lpos += len + 1;
564		*cp = och;
565cont:
566		;
567	}
568	if (lpos != 8)
569		putc('\n', fp);
570}
571
572do_cfiles(fp)
573	FILE *fp;
574{
575	register struct file_list *tp, *fl;
576	register int lpos, len;
577	char swapname[32];
578
579	fputs("CFILES=", fp);
580	lpos = 8;
581	for (tp = ftab; tp; tp = tp->f_next)
582		if (tp->f_type != INVISIBLE) {
583			len = strlen(tp->f_fn);
584			if (tp->f_fn[len - 1] != 'c')
585				continue;
586			if ((len = 3 + len) + lpos > 72) {
587				lpos = 8;
588				fputs("\\\n\t", fp);
589			}
590			fprintf(fp, "$S/%s ", tp->f_fn);
591			lpos += len + 1;
592		}
593	for (fl = conf_list; fl; fl = fl->f_next)
594		if (fl->f_type == SYSTEMSPEC) {
595			(void) sprintf(swapname, "swap%s.c", fl->f_fn);
596			if ((len = 3 + strlen(swapname)) + lpos > 72) {
597				lpos = 8;
598				fputs("\\\n\t", fp);
599			}
600			if (eq(fl->f_fn, "generic"))
601				fprintf(fp, "$S/%s/%s/%s ",
602				    machinename, machinename, swapname);
603			else
604				fprintf(fp, "%s ", swapname);
605			lpos += len + 1;
606		}
607	if (lpos != 8)
608		putc('\n', fp);
609}
610
611do_sfiles(fp)
612	FILE *fp;
613{
614	register struct file_list *tp;
615	register int lpos, len;
616
617	fputs("SFILES=", fp);
618	lpos = 8;
619	for (tp = ftab; tp; tp = tp->f_next)
620		if (tp->f_type != INVISIBLE) {
621			len = strlen(tp->f_fn);
622			if (tp->f_fn[len - 1] != 'S' && tp->f_fn[len - 1] != 's')
623				continue;
624			if ((len = 3 + len) + lpos > 72) {
625				lpos = 8;
626				fputs("\\\n\t", fp);
627			}
628			fprintf(fp, "$S/%s ", tp->f_fn);
629			lpos += len + 1;
630		}
631	if (lpos != 8)
632		putc('\n', fp);
633}
634
635
636char *
637tail(fn)
638	char *fn;
639{
640	register char *cp;
641
642	cp = rindex(fn, '/');
643	if (cp == 0)
644		return (fn);
645	return (cp+1);
646}
647
648/*
649 * Create the makerules for each file
650 * which is part of the system.
651 * Devices are processed with the special c2 option -i
652 * which avoids any problem areas with i/o addressing
653 * (e.g. for the VAX); assembler files are processed by as.
654 */
655do_rules(f)
656	FILE *f;
657{
658	register char *cp, *np, och, *tp;
659	register struct file_list *ftp;
660	char *special;
661
662	for (ftp = ftab; ftp != 0; ftp = ftp->f_next) {
663		if (ftp->f_type == INVISIBLE)
664			continue;
665		cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
666		och = *cp;
667		if (ftp->f_flags & NO_IMPLCT_RULE) {
668			if (ftp->f_depends)
669				fprintf(f, "%s: %s\n", np, ftp->f_depends );
670			else
671				fprintf(f, "%s: \n", np );
672		}
673		else {
674			*cp = '\0';
675			if (och == 'o') {
676				fprintf(f, "%so:\n\t-cp $S/%so .\n\n",
677					tail(np), np);
678				continue;
679			}
680			if (ftp->f_depends)
681				fprintf(f, "%so: $S/%s%c %s\n", tail(np),
682					np, och, ftp->f_depends);
683			else
684				fprintf(f, "%so: $S/%s%c\n", tail(np),
685					np, och);
686		}
687		tp = tail(np);
688		special = ftp->f_special;
689		if (special == 0) {
690			char *ftype;
691			static char cmd[128];
692
693			switch (ftp->f_type) {
694
695			case NORMAL:
696				ftype = "NORMAL";
697				break;
698
699			case DRIVER:
700				ftype = "DRIVER";
701				break;
702
703			case PROFILING:
704				if (!profiling)
705					continue;
706				ftype = "PROFILE";
707				break;
708
709			default:
710				printf("config: don't know rules for %s\n", np);
711				break;
712			}
713			(void)sprintf(cmd, "${%s_%c%s}", ftype, toupper(och),
714				      ftp->f_flags & CONFIGDEP? "_C" : "");
715			special = cmd;
716		}
717		*cp = och;
718		fprintf(f, "\t%s\n\n", special);
719	}
720}
721
722/*
723 * Create the load strings
724 */
725do_load(f)
726	register FILE *f;
727{
728	register struct file_list *fl;
729	register int first;
730	struct file_list *do_systemspec();
731
732	for (first = 1, fl = conf_list; fl; first = 0)
733		fl = fl->f_type == SYSTEMSPEC ?
734			do_systemspec(f, fl, first) : fl->f_next;
735	fputs("all:", f);
736	for (fl = conf_list; fl; fl = fl->f_next)
737		if (fl->f_type == SYSTEMSPEC)
738			fprintf(f, " %s", fl->f_needs);
739	putc('\n', f);
740}
741
742do_clean(fp)
743	FILE *fp;
744{
745	register struct file_list *tp, *fl;
746	register int lpos, len;
747	char swapname[32];
748
749	fputs("CLEAN=", fp);
750	lpos = 7;
751	for (tp = ftab; tp; tp = tp->f_next)
752		if (tp->f_clean) {
753			len = strlen(tp->f_clean);
754			if (len + lpos > 72) {
755				lpos = 8;
756				fputs("\\\n\t", fp);
757			}
758			fprintf(fp, "%s ", tp->f_clean);
759			lpos += len + 1;
760		}
761	if (lpos != 8)
762		putc('\n', fp);
763}
764
765struct file_list *
766do_systemspec(f, fl, first)
767	FILE *f;
768	register struct file_list *fl;
769	int first;
770{
771
772	fprintf(f, "%s: ${SYSTEM_DEP} swap%s.o", fl->f_needs, fl->f_fn);
773	if (first)
774		fprintf(f, " vers.o");
775	fprintf(f, "\n\t${SYSTEM_LD_HEAD}\n");
776	fprintf(f, "\t${SYSTEM_LD} swap%s.o\n", fl->f_fn);
777	fprintf(f, "\t${SYSTEM_LD_TAIL}\n\n");
778	do_swapspec(f, fl->f_fn);
779	for (fl = fl->f_next; fl; fl = fl->f_next)
780		if (fl->f_type != SWAPSPEC)
781			break;
782	return (fl);
783}
784
785do_swapspec(f, name)
786	FILE *f;
787	register char *name;
788{
789
790	if (!eq(name, "generic"))
791		fprintf(f, "swap%s.o: swap%s.c\n", name, name);
792	else
793		fprintf(f, "swapgeneric.o: $S/%s/%s/swapgeneric.c\n",
794			machinename, machinename);
795	fprintf(f, "\t${NORMAL_C}\n\n");
796}
797
798char *
799raise(str)
800	register char *str;
801{
802	register char *cp = str;
803
804	while (*str) {
805		if (islower(*str))
806			*str = toupper(*str);
807		str++;
808	}
809	return (cp);
810}
811
812