xref: /csrg-svn/usr.bin/pascal/pc/pc.c (revision 12966)
1*12966Smckusick static	char sccsid[] = "@(#)pc.c 3.24 06/10/83";
25054Smckusic 
3621Sbill #include <stdio.h>
4621Sbill #include <signal.h>
5621Sbill #include <wait.h>
612870Speter #include <sys/param.h>
7621Sbill 
8621Sbill /*
9654Sbill  * Pc - front end for Pascal compiler.
10621Sbill  */
11908Sbill char	*pc0 = "/usr/lib/pc0";
12908Sbill char	*pc1 = "/lib/f1";
13908Sbill char	*pc2 = "/usr/lib/pc2";
14908Sbill char	*c2 = "/lib/c2";
15908Sbill char	*pc3 = "/usr/lib/pc3";
16908Sbill char	*ld = "/bin/ld";
17908Sbill char	*as = "/bin/as";
18621Sbill char	*lpc = "-lpc";
19908Sbill char	*crt0 = "/lib/crt0.o";
20908Sbill char	*mcrt0 = "/lib/mcrt0.o";
215054Smckusic char	*gcrt0 = "/usr/lib/gcrt0.o";
22621Sbill 
23621Sbill char	*mktemp();
2412870Speter char	*tmpdir = "/tmp";
2512870Speter char	tmp0[MAXPATHLEN], tmp1[MAXPATHLEN];
26621Sbill char	*tname[2];
27621Sbill char	*tfile[2];
28621Sbill 
29621Sbill char	*setsuf(), *savestr();
30621Sbill 
3112870Speter int	Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag, wflag, tflag;
32621Sbill int	debug;
33621Sbill 
34621Sbill #define	NARGS	512
35621Sbill int	ldargx = 3;
36621Sbill int	pc0argx = 3;
37621Sbill char	*pc0args[NARGS] =	{ "pc0", "-o", "XXX" };
38621Sbill char	*pc1args[3] =		{ "pc1", 0, };
39621Sbill char	*pc2args[2] =		{ "pc2", 0 };
40621Sbill char	*c2args[4] =		{ "c2", 0, 0, 0 };
417596Smckusick int	pc3argx = 1;
42621Sbill #define	pc3args	pc0args
43621Sbill #define	ldargs	pc0args
447596Smckusick /* char	*pc3args[NARGS] =	{ "pc3", 0 }; */
45908Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/lib/crt0.o", 0, }; */
4612870Speter 
4712870Speter 				/* as -J -t tmpdir -o objfile srcfile \0 */
48908Sbill int	asargx;
4912870Speter char	*asargs[8] =		{ "as", 0, };
50621Sbill 
517766Smckusick char *mesg[] = {
527766Smckusick 	0,
537766Smckusick 	"Hangup",
547766Smckusick 	"Interrupt",
557766Smckusick 	"Quit",
567766Smckusick 	"Illegal instruction",
577766Smckusick 	"Trace/BPT trap",
587766Smckusick 	"IOT trap",
597766Smckusick 	"EMT trap",
607766Smckusick 	"Floating exception",
617766Smckusick 	"Killed",
627766Smckusick 	"Bus error",
637766Smckusick 	"Segmentation fault",
647766Smckusick 	"Bad system call",
657766Smckusick 	"Broken pipe",
667766Smckusick 	"Alarm clock",
677766Smckusick 	"Terminated",
687766Smckusick 	"Signal 16",
697766Smckusick 	"Stopped (signal)",
707766Smckusick 	"Stopped",
717766Smckusick 	"Continued",
727766Smckusick 	"Child exited",
737766Smckusick 	"Stopped (tty input)",
747766Smckusick 	"Stopped (tty output)",
757766Smckusick 	"Tty input interrupt",
767766Smckusick 	"Cputime limit exceeded",
777766Smckusick 	"Filesize limit exceeded",
787766Smckusick 	"Signal 26",
797766Smckusick 	"Signal 27",
807766Smckusick 	"Signal 28",
817766Smckusick 	"Signal 29",
827766Smckusick 	"Signal 30",
837766Smckusick 	"Signal 31",
847766Smckusick 	"Signal 32"
857766Smckusick };
867766Smckusick 
87621Sbill /*
88621Sbill  * If the number of .p arguments (np) is 1, and the number of .o arguments
89621Sbill  * (nxo) is 0, and we successfully create an ``a.out'', then we remove
90621Sbill  * the one .ps .o file (onepso).
91621Sbill  */
92621Sbill int	np, nxo;
93621Sbill char	*onepso;
94621Sbill int	errs;
95621Sbill 
96621Sbill int	onintr();
97621Sbill 
98621Sbill main(argc, argv)
99621Sbill 	int argc;
100621Sbill 	char **argv;
101621Sbill {
102621Sbill 	register char *argp;
103621Sbill 	register int i;
104621Sbill 	int savargx;
105621Sbill 	char *t, c;
106621Sbill 	int j;
107621Sbill 
108621Sbill 	argc--, argv++;
109621Sbill 	if (argc == 0) {
110621Sbill 		execl("/bin/cat", "cat", "/usr/lib/how_pc");
111621Sbill 		exit(1);
112621Sbill 	}
113621Sbill 	if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
114621Sbill 		signal(SIGINT, onintr);
115621Sbill 		signal(SIGTERM, onintr);
116621Sbill 	}
117621Sbill 	for (i = 0; i < argc; i++) {
118621Sbill 		argp = argv[i];
119621Sbill 		if (argp[0] != '-')
120621Sbill 			continue;
121621Sbill 		switch (argp[1]) {
122621Sbill 
123621Sbill 		case 'd':
124621Sbill 			if (argp[2] == 0)
125621Sbill 				debug++;
126621Sbill 			continue;
127621Sbill 		case 'i':
128621Sbill 			pc0args[pc0argx++] = "-i";
129621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
130621Sbill 			    getsuf(argv[i+1]) != 'p') {
131621Sbill 				pc0args[pc0argx++] = argv[i+1];
132621Sbill 				i++;
133621Sbill 			}
134621Sbill 			if (i+1 == argc) {
135621Sbill 				fprintf(stderr, "pc: bad -i construction\n");
136621Sbill 				exit(1);
137621Sbill 			}
138621Sbill 			continue;
139621Sbill 		case 'o':
140621Sbill 			i++;
141621Sbill 			if (i == argc) {
142621Sbill 				fprintf(stderr, "pc: -o must specify file\n");
143621Sbill 				exit(1);
144621Sbill 			}
145621Sbill 			c = getsuf(argv[i]);
146621Sbill 			if (c == 'o' || c == 'p' || c == 'c') {
147621Sbill 				fprintf(stderr, "pc: -o would overwrite %s\n",
148621Sbill 				    argv[i]);
149621Sbill 				exit(1);
150621Sbill 			}
151621Sbill 			continue;
15212870Speter 		case 't':
15312870Speter 			i++;
15412870Speter 			if (i == argc) {
15512931Speter 				fprintf(stderr, "pc: -t but no directory\n");
15612870Speter 				exit(1);
15712870Speter 			}
15812931Speter 			if (argp[2] != '\0') {
15912931Speter 				fprintf(stderr, "pc: bad -t option\n");
16012931Speter 				exit(1);
16112931Speter 			}
16212870Speter 			tmpdir = argv[i];
16312931Speter 			if (tmpdir[0] == '-') {
16412931Speter 				fprintf(stderr, "pc: bad -t option\n");
16512931Speter 				exit(1);
16612931Speter 			}
16712870Speter 			tflag = 1;
16812870Speter 			continue;
169621Sbill 		case 'O':
170621Sbill 			Oflag = 1;
171621Sbill 			continue;
172621Sbill 		case 'S':
173621Sbill 			Sflag = 1;
174621Sbill 			continue;
175908Sbill 		case 'J':
176908Sbill 			Jflag = 1;
177908Sbill 			continue;
178621Sbill 		case 'T':
179621Sbill 			switch (argp[2]) {
180621Sbill 
181621Sbill 			case '0':
18210721Smckusick 				pc0 = "/usr/src/ucb/pascal/pc0/a.out";
1833862Smckusic 				if (argp[3] != '\0') {
1843862Smckusic 					pc0 = &argp[3];
1853862Smckusic 				}
186621Sbill 				continue;
187621Sbill 			case '1':
1889140Smckusick 				pc1 = "/usr/src/lib/pcc/fort";
1893862Smckusic 				if (argp[3] != '\0') {
1903862Smckusic 					pc1 = &argp[3];
1913862Smckusic 				}
192621Sbill 				continue;
193621Sbill 			case '2':
19410721Smckusick 				pc2 = "/usr/src/ucb/pascal/utilities/pc2";
1953862Smckusic 				if (argp[3] != '\0') {
1963862Smckusic 					pc2 = &argp[3];
1973862Smckusic 				}
198621Sbill 				continue;
199621Sbill 			case '3':
20010721Smckusick 				pc3 = "/usr/src/ucb/pascal/utilities/pc3";
2013862Smckusic 				if (argp[3] != '\0') {
2023862Smckusic 					pc3 = &argp[3];
2033862Smckusic 				}
204621Sbill 				continue;
205621Sbill 			case 'l':
2065054Smckusic 				Tlflag = 1;
2079140Smckusick 				lpc = "/usr/src/usr.lib/libpc/libpc";
2083862Smckusic 				if (argp[3] != '\0') {
2093862Smckusic 					lpc = &argp[3];
2103862Smckusic 				}
211621Sbill 				continue;
212621Sbill 			}
213621Sbill 			continue;
214621Sbill 		case 'c':
215621Sbill 			cflag = 1;
216621Sbill 			continue;
217621Sbill 		case 'l':
218621Sbill 			if (argp[2])
219621Sbill 				continue;
220621Sbill 			/* fall into ... */
221621Sbill 		case 'b':
222621Sbill 		case 's':
223621Sbill 		case 'z':
224621Sbill 		case 'C':
225621Sbill 			pc0args[pc0argx++] = argp;
226621Sbill 			continue;
2277596Smckusick 		case 'w':
2287596Smckusick 			wflag = 1;
2297596Smckusick 			pc0args[pc0argx++] = argp;
2307596Smckusick 			continue;
2317596Smckusick 		case 'g':
2327596Smckusick 			gflag = 1;
2337596Smckusick 			pc0args[pc0argx++] = argp;
2347596Smckusick 			continue;
235621Sbill 		case 'p':
2365054Smckusic 			if (argp[2] == 'g')
2375054Smckusic 				crt0 = gcrt0;
2385054Smckusic 			else
2395054Smckusic 				crt0 = mcrt0;
2405054Smckusic 			if (!Tlflag)
2415054Smckusic 				lpc = "-lpc_p";
2425054Smckusic 			pflag = 1;
243654Sbill 			continue;
244621Sbill 		}
245621Sbill 	}
246621Sbill 	if (gflag && Oflag) {
247621Sbill 		fprintf(stderr, "pc: warning: -g overrides -O\n");
248621Sbill 		Oflag = 0;
249621Sbill 	}
25012870Speter 	sprintf(tmp0, "%s/%s", tmpdir, "p0XXXXXX");
25112870Speter 	tname[0] = mktemp(tmp0);
25212870Speter 	sprintf(tmp1, "%s/%s", tmpdir, "p1XXXXXX");
25312870Speter 	tname[1] = mktemp(tmp1);
254621Sbill 	savargx = pc0argx;
255621Sbill 	for (i = 0; i < argc; i++) {
256621Sbill 		argp = argv[i];
257621Sbill 		if (argp[0] == '-')
258621Sbill 			continue;
2591211Speter 		if (suffix(argp) == 's') {
2601211Speter 			asargx = 1;
2611211Speter 			if (Jflag)
2621211Speter 				asargs[asargx++] = "-J";
26312870Speter #			ifdef vax
26412870Speter 				if (tflag) {
26512870Speter 					asargs[asargx++] = "-t";
26612870Speter 					asargs[asargx++] = tmpdir;
26712870Speter 				}
26812870Speter #			endif vax
2691211Speter 			asargs[asargx++] = argp;
2701211Speter 			asargs[asargx++] = "-o";
2711211Speter 			tfile[1] = setsuf(argp, 'o');
2721211Speter 			asargs[asargx++] = tfile[1];
2731211Speter 			asargs[asargx] = 0;
2741211Speter 			if (dosys(as, asargs, 0, 0))
2751211Speter 				continue;
2761211Speter 			tfile[1] = 0;
2771211Speter 			continue;
2781211Speter 		}
279621Sbill 		if (suffix(argp) != 'p')
280621Sbill 			continue;
281621Sbill 		tfile[0] = tname[0];
282621Sbill 		pc0args[2] = tfile[0];
283621Sbill 		pc0argx = savargx;
284654Sbill 		if (pflag)
285654Sbill 			pc0args[pc0argx++] = "-p";
286*12966Smckusick 		if (Jflag)
287*12966Smckusick 			pc0args[pc0argx++] = "-J";
288621Sbill 		pc0args[pc0argx++] = argp;
289621Sbill 		pc0args[pc0argx] = 0;
290621Sbill 		if (dosys(pc0, pc0args, 0, 0))
291621Sbill 			continue;
292621Sbill 		pc1args[1] = tfile[0];
293654Sbill 		tfile[1] = tname[1];
294621Sbill 		if (dosys(pc1, pc1args, 0, tfile[1]))
295621Sbill 			continue;
296621Sbill 		unlink(tfile[0]);
2972340Smckusic 		tfile[0] = tname[0];
2982340Smckusic 		if (Oflag) {
2992340Smckusic 			if (dosys(c2, c2args, tfile[1], tfile[0]))
3002340Smckusic 				continue;
3012340Smckusic 			unlink(tfile[1]);
3022340Smckusic 			tfile[1] = tfile[0];
3032340Smckusic 			tfile[0] = tname[1];
3042340Smckusic 		}
3052340Smckusic 		if (Sflag)
306654Sbill 			tfile[0] = setsuf(argp, 's');
307621Sbill 		if (dosys(pc2, pc2args, tfile[1], tfile[0]))
308621Sbill 			continue;
309621Sbill 		unlink(tfile[1]);
310621Sbill 		tfile[1] = 0;
311654Sbill 		if (Sflag) {
312654Sbill 			tfile[0] = 0;
313621Sbill 			continue;
314654Sbill 		}
315908Sbill 		asargx = 1;
316908Sbill 		if (Jflag)
317908Sbill 			asargs[asargx++] = "-J";
31812870Speter #		ifdef vax
31912870Speter 			if (tflag) {
32012870Speter 				asargs[asargx++] = "-t";
32112870Speter 				asargs[asargx++] = tmpdir;
32212870Speter 			}
32312870Speter #		endif vax
324908Sbill 		asargs[asargx++] = tfile[0];
325908Sbill 		asargs[asargx++] = "-o";
326621Sbill 		tfile[1] = setsuf(argp, 'o');
327908Sbill 		asargs[asargx++] = tfile[1];
328908Sbill 		asargs[asargx] = 0;
329621Sbill 		if (dosys(as, asargs, 0, 0))
330621Sbill 			continue;
331621Sbill 		tfile[1] = 0;
332621Sbill 		remove();
333621Sbill 	}
334621Sbill 	if (errs || cflag || Sflag)
335621Sbill 		done();
3367596Smckusick /* char	*pc3args[NARGS] =	{ "pc3", 0 }; */
337621Sbill 	pc3args[0] = "pc3";
3387596Smckusick 	if (wflag)
3397596Smckusick 		pc3args[pc3argx++] = "-w";
3407596Smckusick 	pc3args[pc3argx++] = "/usr/lib/pcexterns.o";
341621Sbill 	for (i = 0; i < argc; i++) {
342621Sbill 		argp = argv[i];
343621Sbill 		if (!strcmp(argp, "-o"))
344621Sbill 			i++;
345621Sbill 		if (argp[0] == '-')
346621Sbill 			continue;
347621Sbill 		switch (getsuf(argp)) {
348621Sbill 
349621Sbill 		case 'o':
350621Sbill 			pc3args[pc3argx++] = argp;
351621Sbill 			nxo++;
352621Sbill 			continue;
3531211Speter 		case 's':
354621Sbill 		case 'p':
355621Sbill 			onepso = pc3args[pc3argx++] =
356621Sbill 			    savestr(setsuf(argp, 'o'));
357621Sbill 			np++;
358621Sbill 			continue;
359621Sbill 		}
360621Sbill 	}
361621Sbill 	pc3args[pc3argx] = 0;
3627596Smckusick 	if (dosys(pc3, pc3args, 0, 0) > 1)
363621Sbill 		done();
36410672Speter 	errs = 0;
365908Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/lib/crt0.o", 0, }; */
366621Sbill 	ldargs[0] = "ld";
367621Sbill 	ldargs[1] = "-X";
368654Sbill 	ldargs[2] = crt0;
369621Sbill 	for (i = 0; i < argc; i++) {
370621Sbill 		argp = argv[i];
371621Sbill 		if (argp[0] != '-') {
372621Sbill 			switch (getsuf(argp)) {
373621Sbill 
374621Sbill 			case 'p':
3751211Speter 			case 's':
376621Sbill 				ldargs[ldargx] = savestr(setsuf(argp, 'o'));
377621Sbill 				break;
378621Sbill 			default:
379621Sbill 				ldargs[ldargx] = argp;
380621Sbill 				break;
381621Sbill 			}
382621Sbill 			if (getsuf(ldargs[ldargx]) == 'o')
383621Sbill 			for (j = 0; j < ldargx; j++)
384621Sbill 				if (!strcmp(ldargs[j], ldargs[ldargx]))
385621Sbill 					goto duplicate;
386621Sbill 			ldargx++;
387621Sbill duplicate:
388621Sbill 			continue;
389621Sbill 		}
390621Sbill 		switch (argp[1]) {
391621Sbill 
392621Sbill 		case 'i':
393621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
394621Sbill 			    getsuf(argv[i+1]) != 'p')
395621Sbill 				i++;
396621Sbill 			continue;
397621Sbill 		case 'd':
398621Sbill 			if (argp[2] == 0)
399621Sbill 				continue;
400621Sbill 			ldargs[ldargx++] = argp;
401621Sbill 			continue;
402621Sbill 		case 'o':
403621Sbill 			ldargs[ldargx++] = argp;
404621Sbill 			i++;
405621Sbill 			ldargs[ldargx++] = argv[i];
406621Sbill 			continue;
407621Sbill 		case 'l':
408621Sbill 			if (argp[2])
409621Sbill 				ldargs[ldargx++] = argp;
410621Sbill 			continue;
41112870Speter 		case 't':
41212870Speter 			i++;
41312870Speter 			continue;
414621Sbill 		case 'c':
415621Sbill 		case 'g':
416621Sbill 		case 'w':
417621Sbill 		case 'p':
418621Sbill 		case 'S':
419908Sbill 		case 'J':
420621Sbill 		case 'T':
421621Sbill 		case 'O':
422621Sbill 		case 'C':
423621Sbill 		case 'b':
424621Sbill 		case 's':
425621Sbill 		case 'z':
426621Sbill 			continue;
427621Sbill 		default:
428621Sbill 			ldargs[ldargx++] = argp;
429621Sbill 			continue;
430621Sbill 		}
431621Sbill 	}
432621Sbill 	ldargs[ldargx++] = lpc;
433621Sbill 	if (gflag)
434621Sbill 		ldargs[ldargx++] = "-lg";
4355054Smckusic 	if (pflag) {
4365054Smckusic 		ldargs[ldargx++] = "-lm_p";
4375054Smckusic 		ldargs[ldargx++] = "-lc_p";
4385054Smckusic 	} else {
4395054Smckusic 		ldargs[ldargx++] = "-lm";
4405054Smckusic 		ldargs[ldargx++] = "-lc";
4415054Smckusic 	}
442621Sbill 	ldargs[ldargx] = 0;
443621Sbill 	if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0)
444621Sbill 		unlink(onepso);
445621Sbill 	done();
446621Sbill }
447621Sbill 
448621Sbill dosys(cmd, argv, in, out)
449621Sbill 	char *cmd, **argv, *in, *out;
450621Sbill {
451621Sbill 	union wait status;
452621Sbill 	int pid;
453621Sbill 
454621Sbill 	if (debug) {
455621Sbill 		int i;
456621Sbill 		printf("%s:", cmd);
457621Sbill 		for (i = 0; argv[i]; i++)
458621Sbill 			printf(" %s", argv[i]);
459621Sbill 		if (in)
460621Sbill 			printf(" <%s", in);
461621Sbill 		if (out)
462621Sbill 			printf(" >%s", out);
463621Sbill 		printf("\n");
464621Sbill 	}
465621Sbill 	pid = vfork();
466621Sbill 	if (pid < 0) {
467621Sbill 		fprintf(stderr, "pc: No more processes\n");
468621Sbill 		done();
469621Sbill 	}
470621Sbill 	if (pid == 0) {
471621Sbill 		if (in) {
472621Sbill 			close(0);
473621Sbill 			if (open(in, 0) != 0) {
474621Sbill 				perror(in);
475621Sbill 				exit(1);
476621Sbill 			}
477621Sbill 		}
478621Sbill 		if (out) {
479621Sbill 			close(1);
480621Sbill 			unlink(out);
481621Sbill 			if (creat(out, 0666) != 1) {
482621Sbill 				perror(out);
483621Sbill 				exit(1);
484621Sbill 			}
485621Sbill 		}
486621Sbill 		signal(SIGINT, SIG_DFL);
487621Sbill 		execv(cmd, argv);
488621Sbill 		perror(cmd);
489621Sbill 		exit(1);
490621Sbill 	}
491621Sbill 	while (wait(&status) != pid)
492621Sbill 		;
493621Sbill 	if (WIFSIGNALED(status)) {
4947766Smckusick 		if (status.w_termsig != SIGINT) {
4957766Smckusick 			fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]);
4967766Smckusick 			if (status.w_coredump)
4977766Smckusick 				fprintf(stderr, " (core dumped)");
4987766Smckusick 			fprintf(stderr, "\n");
4997766Smckusick 		}
500621Sbill 		errs = 100;
501621Sbill 		done();
502621Sbill 		/*NOTREACHED*/
503621Sbill 	}
504621Sbill 	if (status.w_retcode) {
505621Sbill 		errs = 1;
506621Sbill 		remove();
507621Sbill 	}
508621Sbill 	return (status.w_retcode);
509621Sbill }
510621Sbill 
511621Sbill done()
512621Sbill {
513621Sbill 
514621Sbill 	remove();
515621Sbill 	exit(errs);
516621Sbill }
517621Sbill 
518621Sbill remove()
519621Sbill {
520621Sbill 
521621Sbill 	if (tfile[0])
522621Sbill 		unlink(tfile[0]);
523621Sbill 	if (tfile[1])
524621Sbill 		unlink(tfile[1]);
525621Sbill }
526621Sbill 
527621Sbill onintr()
528621Sbill {
529621Sbill 
530621Sbill 	errs = 1;
531621Sbill 	done();
532621Sbill }
533621Sbill 
534621Sbill getsuf(cp)
535621Sbill 	char *cp;
536621Sbill {
537621Sbill 
538621Sbill 	if (*cp == 0)
539621Sbill 		return;
540621Sbill 	while (cp[1])
541621Sbill 		cp++;
542621Sbill 	if (cp[-1] != '.')
543621Sbill 		return (0);
544621Sbill 	return (*cp);
545621Sbill }
546621Sbill 
547621Sbill char *
548654Sbill setsuf(as, ch)
549654Sbill 	char *as;
550621Sbill {
551654Sbill 	register char *s, *s1;
552621Sbill 
553654Sbill 	s = s1 = savestr(as);
554654Sbill 	while (*s)
555654Sbill 		if (*s++ == '/')
556654Sbill 			s1 = s;
557654Sbill 	s[-1] = ch;
558654Sbill 	return (s1);
559621Sbill }
560621Sbill 
561621Sbill #define	NSAVETAB	512
562621Sbill char	*savetab;
563621Sbill int	saveleft;
564621Sbill 
565621Sbill char *
566621Sbill savestr(cp)
567621Sbill 	register char *cp;
568621Sbill {
569621Sbill 	register int len;
570621Sbill 
571621Sbill 	len = strlen(cp) + 1;
572621Sbill 	if (len > saveleft) {
573621Sbill 		saveleft = NSAVETAB;
574621Sbill 		if (len > saveleft)
575621Sbill 			saveleft = len;
576621Sbill 		savetab = (char *)malloc(saveleft);
577621Sbill 		if (savetab == 0) {
578621Sbill 			fprintf(stderr, "ran out of memory (savestr)\n");
579621Sbill 			exit(1);
580621Sbill 		}
581621Sbill 	}
582621Sbill 	strncpy(savetab, cp, len);
583621Sbill 	cp = savetab;
584621Sbill 	savetab += len;
585621Sbill 	return (cp);
586621Sbill }
587621Sbill 
588621Sbill suffix(cp)
589621Sbill 	char *cp;
590621Sbill {
591621Sbill 
592621Sbill 	if (cp[0] == 0 || cp[1] == 0)
593621Sbill 		return (0);
594621Sbill 	while (cp[1])
595621Sbill 		cp++;
596621Sbill 	if (cp[-1] == '.')
597621Sbill 		return (*cp);
598621Sbill 	return (0);
599621Sbill }
600