xref: /csrg-svn/usr.bin/pascal/pc/pc.c (revision 9140)
1*9140Smckusick static	char sccsid[] = "@(#)pc.c 3.17 11/12/82";
25054Smckusic 
3621Sbill #include <stdio.h>
4621Sbill #include <signal.h>
5621Sbill #include <wait.h>
6621Sbill 
7621Sbill /*
8654Sbill  * Pc - front end for Pascal compiler.
9621Sbill  */
10908Sbill char	*pc0 = "/usr/lib/pc0";
11908Sbill char	*pc1 = "/lib/f1";
12908Sbill char	*pc2 = "/usr/lib/pc2";
13908Sbill char	*c2 = "/lib/c2";
14908Sbill char	*pc3 = "/usr/lib/pc3";
15908Sbill char	*ld = "/bin/ld";
16908Sbill char	*as = "/bin/as";
17621Sbill char	*lpc = "-lpc";
18908Sbill char	*crt0 = "/lib/crt0.o";
19908Sbill char	*mcrt0 = "/lib/mcrt0.o";
205054Smckusic char	*gcrt0 = "/usr/lib/gcrt0.o";
21621Sbill 
22621Sbill char	*mktemp();
23621Sbill char	*tname[2];
24621Sbill char	*tfile[2];
25621Sbill 
26621Sbill char	*setsuf(), *savestr();
27621Sbill 
287596Smckusick int	Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag, wflag;
29621Sbill int	debug;
30621Sbill 
31621Sbill #define	NARGS	512
32621Sbill int	ldargx = 3;
33621Sbill int	pc0argx = 3;
34621Sbill char	*pc0args[NARGS] =	{ "pc0", "-o", "XXX" };
35621Sbill char	*pc1args[3] =		{ "pc1", 0, };
36621Sbill char	*pc2args[2] =		{ "pc2", 0 };
37621Sbill char	*c2args[4] =		{ "c2", 0, 0, 0 };
387596Smckusick int	pc3argx = 1;
39621Sbill #define	pc3args	pc0args
40621Sbill #define	ldargs	pc0args
417596Smckusick /* char	*pc3args[NARGS] =	{ "pc3", 0 }; */
42908Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/lib/crt0.o", 0, }; */
43908Sbill int	asargx;
44908Sbill char	*asargs[6] =		{ "as", 0, };
45621Sbill 
467766Smckusick char *mesg[] = {
477766Smckusick 	0,
487766Smckusick 	"Hangup",
497766Smckusick 	"Interrupt",
507766Smckusick 	"Quit",
517766Smckusick 	"Illegal instruction",
527766Smckusick 	"Trace/BPT trap",
537766Smckusick 	"IOT trap",
547766Smckusick 	"EMT trap",
557766Smckusick 	"Floating exception",
567766Smckusick 	"Killed",
577766Smckusick 	"Bus error",
587766Smckusick 	"Segmentation fault",
597766Smckusick 	"Bad system call",
607766Smckusick 	"Broken pipe",
617766Smckusick 	"Alarm clock",
627766Smckusick 	"Terminated",
637766Smckusick 	"Signal 16",
647766Smckusick 	"Stopped (signal)",
657766Smckusick 	"Stopped",
667766Smckusick 	"Continued",
677766Smckusick 	"Child exited",
687766Smckusick 	"Stopped (tty input)",
697766Smckusick 	"Stopped (tty output)",
707766Smckusick 	"Tty input interrupt",
717766Smckusick 	"Cputime limit exceeded",
727766Smckusick 	"Filesize limit exceeded",
737766Smckusick 	"Signal 26",
747766Smckusick 	"Signal 27",
757766Smckusick 	"Signal 28",
767766Smckusick 	"Signal 29",
777766Smckusick 	"Signal 30",
787766Smckusick 	"Signal 31",
797766Smckusick 	"Signal 32"
807766Smckusick };
817766Smckusick 
82621Sbill /*
83621Sbill  * If the number of .p arguments (np) is 1, and the number of .o arguments
84621Sbill  * (nxo) is 0, and we successfully create an ``a.out'', then we remove
85621Sbill  * the one .ps .o file (onepso).
86621Sbill  */
87621Sbill int	np, nxo;
88621Sbill char	*onepso;
89621Sbill int	errs;
90621Sbill 
91621Sbill int	onintr();
92621Sbill 
93621Sbill main(argc, argv)
94621Sbill 	int argc;
95621Sbill 	char **argv;
96621Sbill {
97621Sbill 	register char *argp;
98621Sbill 	register int i;
99621Sbill 	int savargx;
100621Sbill 	char *t, c;
101621Sbill 	int j;
102621Sbill 
103621Sbill 	argc--, argv++;
104621Sbill 	if (argc == 0) {
105621Sbill 		execl("/bin/cat", "cat", "/usr/lib/how_pc");
106621Sbill 		exit(1);
107621Sbill 	}
108621Sbill 	if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
109621Sbill 		signal(SIGINT, onintr);
110621Sbill 		signal(SIGTERM, onintr);
111621Sbill 	}
112621Sbill 	for (i = 0; i < argc; i++) {
113621Sbill 		argp = argv[i];
114621Sbill 		if (argp[0] != '-')
115621Sbill 			continue;
116621Sbill 		switch (argp[1]) {
117621Sbill 
118621Sbill 		case 'd':
119621Sbill 			if (argp[2] == 0)
120621Sbill 				debug++;
121621Sbill 			continue;
122621Sbill 		case 'i':
123621Sbill 			pc0args[pc0argx++] = "-i";
124621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
125621Sbill 			    getsuf(argv[i+1]) != 'p') {
126621Sbill 				pc0args[pc0argx++] = argv[i+1];
127621Sbill 				i++;
128621Sbill 			}
129621Sbill 			if (i+1 == argc) {
130621Sbill 				fprintf(stderr, "pc: bad -i construction\n");
131621Sbill 				exit(1);
132621Sbill 			}
133621Sbill 			continue;
134621Sbill 		case 'o':
135621Sbill 			i++;
136621Sbill 			if (i == argc) {
137621Sbill 				fprintf(stderr, "pc: -o must specify file\n");
138621Sbill 				exit(1);
139621Sbill 			}
140621Sbill 			c = getsuf(argv[i]);
141621Sbill 			if (c == 'o' || c == 'p' || c == 'c') {
142621Sbill 				fprintf(stderr, "pc: -o would overwrite %s\n",
143621Sbill 				    argv[i]);
144621Sbill 				exit(1);
145621Sbill 			}
146621Sbill 			continue;
147621Sbill 		case 'O':
148621Sbill 			Oflag = 1;
149621Sbill 			continue;
150621Sbill 		case 'S':
151621Sbill 			Sflag = 1;
152621Sbill 			continue;
153908Sbill 		case 'J':
154908Sbill 			Jflag = 1;
155908Sbill 			continue;
156621Sbill 		case 'T':
157621Sbill 			switch (argp[2]) {
158621Sbill 
159621Sbill 			case '0':
160*9140Smckusick 				pc0 = "/usr/src/ucb/pc0/a.out";
1613862Smckusic 				if (argp[3] != '\0') {
1623862Smckusic 					pc0 = &argp[3];
1633862Smckusic 				}
164621Sbill 				continue;
165621Sbill 			case '1':
166*9140Smckusick 				pc1 = "/usr/src/lib/pcc/fort";
1673862Smckusic 				if (argp[3] != '\0') {
1683862Smckusic 					pc1 = &argp[3];
1693862Smckusic 				}
170621Sbill 				continue;
171621Sbill 			case '2':
172*9140Smckusick 				pc2 = "/usr/src/ucb/pascal/pc2";
1733862Smckusic 				if (argp[3] != '\0') {
1743862Smckusic 					pc2 = &argp[3];
1753862Smckusic 				}
176621Sbill 				continue;
177621Sbill 			case '3':
178*9140Smckusick 				pc3 = "/usr/src/ucb/pascal/pc3";
1793862Smckusic 				if (argp[3] != '\0') {
1803862Smckusic 					pc3 = &argp[3];
1813862Smckusic 				}
182621Sbill 				continue;
183621Sbill 			case 'l':
1845054Smckusic 				Tlflag = 1;
185*9140Smckusick 				lpc = "/usr/src/usr.lib/libpc/libpc";
1863862Smckusic 				if (argp[3] != '\0') {
1873862Smckusic 					lpc = &argp[3];
1883862Smckusic 				}
189621Sbill 				continue;
190621Sbill 			}
191621Sbill 			continue;
192621Sbill 		case 'c':
193621Sbill 			cflag = 1;
194621Sbill 			continue;
195621Sbill 		case 'l':
196621Sbill 			if (argp[2])
197621Sbill 				continue;
198621Sbill 			/* fall into ... */
199621Sbill 		case 'b':
200621Sbill 		case 's':
201621Sbill 		case 'z':
202621Sbill 		case 'C':
203621Sbill 			pc0args[pc0argx++] = argp;
204621Sbill 			continue;
2057596Smckusick 		case 'w':
2067596Smckusick 			wflag = 1;
2077596Smckusick 			pc0args[pc0argx++] = argp;
2087596Smckusick 			continue;
2097596Smckusick 		case 'g':
2107596Smckusick 			gflag = 1;
2117596Smckusick 			pc0args[pc0argx++] = argp;
2127596Smckusick 			continue;
213621Sbill 		case 't':
214621Sbill 			fprintf(stderr, "pc: -t is default; -C for checking\n");
215621Sbill 			continue;
216621Sbill 		case 'p':
2175054Smckusic 			if (argp[2] == 'g')
2185054Smckusic 				crt0 = gcrt0;
2195054Smckusic 			else
2205054Smckusic 				crt0 = mcrt0;
2215054Smckusic 			if (!Tlflag)
2225054Smckusic 				lpc = "-lpc_p";
2235054Smckusic 			pflag = 1;
224654Sbill 			continue;
225621Sbill 		}
226621Sbill 	}
227621Sbill 	if (gflag && Oflag) {
228621Sbill 		fprintf(stderr, "pc: warning: -g overrides -O\n");
229621Sbill 		Oflag = 0;
230621Sbill 	}
231621Sbill 	tname[0] = mktemp("/tmp/p0XXXXXX");
232621Sbill 	tname[1] = mktemp("/tmp/p1XXXXXX");
233621Sbill 	savargx = pc0argx;
234621Sbill 	for (i = 0; i < argc; i++) {
235621Sbill 		argp = argv[i];
236621Sbill 		if (argp[0] == '-')
237621Sbill 			continue;
2381211Speter 		if (suffix(argp) == 's') {
2391211Speter 			asargx = 1;
2401211Speter 			if (Jflag)
2411211Speter 				asargs[asargx++] = "-J";
2421211Speter 			asargs[asargx++] = argp;
2431211Speter 			asargs[asargx++] = "-o";
2441211Speter 			tfile[1] = setsuf(argp, 'o');
2451211Speter 			asargs[asargx++] = tfile[1];
2461211Speter 			asargs[asargx] = 0;
2471211Speter 			if (dosys(as, asargs, 0, 0))
2481211Speter 				continue;
2491211Speter 			tfile[1] = 0;
2501211Speter 			continue;
2511211Speter 		}
252621Sbill 		if (suffix(argp) != 'p')
253621Sbill 			continue;
254621Sbill 		tfile[0] = tname[0];
255621Sbill 		pc0args[2] = tfile[0];
256621Sbill 		pc0argx = savargx;
257654Sbill 		if (pflag)
258654Sbill 			pc0args[pc0argx++] = "-p";
259621Sbill 		pc0args[pc0argx++] = argp;
260621Sbill 		pc0args[pc0argx] = 0;
261621Sbill 		if (dosys(pc0, pc0args, 0, 0))
262621Sbill 			continue;
263621Sbill 		pc1args[1] = tfile[0];
264654Sbill 		tfile[1] = tname[1];
265621Sbill 		if (dosys(pc1, pc1args, 0, tfile[1]))
266621Sbill 			continue;
267621Sbill 		unlink(tfile[0]);
2682340Smckusic 		tfile[0] = tname[0];
2692340Smckusic 		if (Oflag) {
2702340Smckusic 			if (dosys(c2, c2args, tfile[1], tfile[0]))
2712340Smckusic 				continue;
2722340Smckusic 			unlink(tfile[1]);
2732340Smckusic 			tfile[1] = tfile[0];
2742340Smckusic 			tfile[0] = tname[1];
2752340Smckusic 		}
2762340Smckusic 		if (Sflag)
277654Sbill 			tfile[0] = setsuf(argp, 's');
278621Sbill 		if (dosys(pc2, pc2args, tfile[1], tfile[0]))
279621Sbill 			continue;
280621Sbill 		unlink(tfile[1]);
281621Sbill 		tfile[1] = 0;
282654Sbill 		if (Sflag) {
283654Sbill 			tfile[0] = 0;
284621Sbill 			continue;
285654Sbill 		}
286908Sbill 		asargx = 1;
287908Sbill 		if (Jflag)
288908Sbill 			asargs[asargx++] = "-J";
289908Sbill 		asargs[asargx++] = tfile[0];
290908Sbill 		asargs[asargx++] = "-o";
291621Sbill 		tfile[1] = setsuf(argp, 'o');
292908Sbill 		asargs[asargx++] = tfile[1];
293908Sbill 		asargs[asargx] = 0;
294621Sbill 		if (dosys(as, asargs, 0, 0))
295621Sbill 			continue;
296621Sbill 		tfile[1] = 0;
297621Sbill 		remove();
298621Sbill 	}
299621Sbill 	if (errs || cflag || Sflag)
300621Sbill 		done();
3017596Smckusick /* char	*pc3args[NARGS] =	{ "pc3", 0 }; */
302621Sbill 	pc3args[0] = "pc3";
3037596Smckusick 	if (wflag)
3047596Smckusick 		pc3args[pc3argx++] = "-w";
3057596Smckusick 	pc3args[pc3argx++] = "/usr/lib/pcexterns.o";
306621Sbill 	for (i = 0; i < argc; i++) {
307621Sbill 		argp = argv[i];
308621Sbill 		if (!strcmp(argp, "-o"))
309621Sbill 			i++;
310621Sbill 		if (argp[0] == '-')
311621Sbill 			continue;
312621Sbill 		switch (getsuf(argp)) {
313621Sbill 
314621Sbill 		case 'o':
315621Sbill 			pc3args[pc3argx++] = argp;
316621Sbill 			nxo++;
317621Sbill 			continue;
3181211Speter 		case 's':
319621Sbill 		case 'p':
320621Sbill 			onepso = pc3args[pc3argx++] =
321621Sbill 			    savestr(setsuf(argp, 'o'));
322621Sbill 			np++;
323621Sbill 			continue;
324621Sbill 		}
325621Sbill 	}
326621Sbill 	pc3args[pc3argx] = 0;
3277596Smckusick 	if (dosys(pc3, pc3args, 0, 0) > 1)
328621Sbill 		done();
329908Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/lib/crt0.o", 0, }; */
330621Sbill 	ldargs[0] = "ld";
331621Sbill 	ldargs[1] = "-X";
332654Sbill 	ldargs[2] = crt0;
333621Sbill 	for (i = 0; i < argc; i++) {
334621Sbill 		argp = argv[i];
335621Sbill 		if (argp[0] != '-') {
336621Sbill 			switch (getsuf(argp)) {
337621Sbill 
338621Sbill 			case 'p':
3391211Speter 			case 's':
340621Sbill 				ldargs[ldargx] = savestr(setsuf(argp, 'o'));
341621Sbill 				break;
342621Sbill 			default:
343621Sbill 				ldargs[ldargx] = argp;
344621Sbill 				break;
345621Sbill 			}
346621Sbill 			if (getsuf(ldargs[ldargx]) == 'o')
347621Sbill 			for (j = 0; j < ldargx; j++)
348621Sbill 				if (!strcmp(ldargs[j], ldargs[ldargx]))
349621Sbill 					goto duplicate;
350621Sbill 			ldargx++;
351621Sbill duplicate:
352621Sbill 			continue;
353621Sbill 		}
354621Sbill 		switch (argp[1]) {
355621Sbill 
356621Sbill 		case 'i':
357621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
358621Sbill 			    getsuf(argv[i+1]) != 'p')
359621Sbill 				i++;
360621Sbill 			continue;
361621Sbill 		case 'd':
362621Sbill 			if (argp[2] == 0)
363621Sbill 				continue;
364621Sbill 			ldargs[ldargx++] = argp;
365621Sbill 			continue;
366621Sbill 		case 'o':
367621Sbill 			ldargs[ldargx++] = argp;
368621Sbill 			i++;
369621Sbill 			ldargs[ldargx++] = argv[i];
370621Sbill 			continue;
371621Sbill 		case 'l':
372621Sbill 			if (argp[2])
373621Sbill 				ldargs[ldargx++] = argp;
374621Sbill 			continue;
375621Sbill 		case 'c':
376621Sbill 		case 'g':
377621Sbill 		case 'w':
378621Sbill 		case 'p':
379621Sbill 		case 'S':
380908Sbill 		case 'J':
381621Sbill 		case 'T':
382621Sbill 		case 'O':
383621Sbill 		case 'C':
384621Sbill 		case 'b':
385621Sbill 		case 's':
386621Sbill 		case 'z':
387621Sbill 			continue;
388621Sbill 		default:
389621Sbill 			ldargs[ldargx++] = argp;
390621Sbill 			continue;
391621Sbill 		}
392621Sbill 	}
393621Sbill 	ldargs[ldargx++] = lpc;
394621Sbill 	if (gflag)
395621Sbill 		ldargs[ldargx++] = "-lg";
3965054Smckusic 	if (pflag) {
3975054Smckusic 		ldargs[ldargx++] = "-lm_p";
3985054Smckusic 		ldargs[ldargx++] = "-lc_p";
3995054Smckusic 	} else {
4005054Smckusic 		ldargs[ldargx++] = "-lm";
4015054Smckusic 		ldargs[ldargx++] = "-lc";
4025054Smckusic 	}
403621Sbill 	ldargs[ldargx] = 0;
404621Sbill 	if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0)
405621Sbill 		unlink(onepso);
406621Sbill 	done();
407621Sbill }
408621Sbill 
409621Sbill dosys(cmd, argv, in, out)
410621Sbill 	char *cmd, **argv, *in, *out;
411621Sbill {
412621Sbill 	union wait status;
413621Sbill 	int pid;
414621Sbill 
415621Sbill 	if (debug) {
416621Sbill 		int i;
417621Sbill 		printf("%s:", cmd);
418621Sbill 		for (i = 0; argv[i]; i++)
419621Sbill 			printf(" %s", argv[i]);
420621Sbill 		if (in)
421621Sbill 			printf(" <%s", in);
422621Sbill 		if (out)
423621Sbill 			printf(" >%s", out);
424621Sbill 		printf("\n");
425621Sbill 	}
426621Sbill 	pid = vfork();
427621Sbill 	if (pid < 0) {
428621Sbill 		fprintf(stderr, "pc: No more processes\n");
429621Sbill 		done();
430621Sbill 	}
431621Sbill 	if (pid == 0) {
432621Sbill 		if (in) {
433621Sbill 			close(0);
434621Sbill 			if (open(in, 0) != 0) {
435621Sbill 				perror(in);
436621Sbill 				exit(1);
437621Sbill 			}
438621Sbill 		}
439621Sbill 		if (out) {
440621Sbill 			close(1);
441621Sbill 			unlink(out);
442621Sbill 			if (creat(out, 0666) != 1) {
443621Sbill 				perror(out);
444621Sbill 				exit(1);
445621Sbill 			}
446621Sbill 		}
447621Sbill 		signal(SIGINT, SIG_DFL);
448621Sbill 		execv(cmd, argv);
449621Sbill 		perror(cmd);
450621Sbill 		exit(1);
451621Sbill 	}
452621Sbill 	while (wait(&status) != pid)
453621Sbill 		;
454621Sbill 	if (WIFSIGNALED(status)) {
4557766Smckusick 		if (status.w_termsig != SIGINT) {
4567766Smckusick 			fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]);
4577766Smckusick 			if (status.w_coredump)
4587766Smckusick 				fprintf(stderr, " (core dumped)");
4597766Smckusick 			fprintf(stderr, "\n");
4607766Smckusick 		}
461621Sbill 		errs = 100;
462621Sbill 		done();
463621Sbill 		/*NOTREACHED*/
464621Sbill 	}
465621Sbill 	if (status.w_retcode) {
466621Sbill 		errs = 1;
467621Sbill 		remove();
468621Sbill 	}
469621Sbill 	return (status.w_retcode);
470621Sbill }
471621Sbill 
472621Sbill done()
473621Sbill {
474621Sbill 
475621Sbill 	remove();
476621Sbill 	exit(errs);
477621Sbill }
478621Sbill 
479621Sbill remove()
480621Sbill {
481621Sbill 
482621Sbill 	if (tfile[0])
483621Sbill 		unlink(tfile[0]);
484621Sbill 	if (tfile[1])
485621Sbill 		unlink(tfile[1]);
486621Sbill }
487621Sbill 
488621Sbill onintr()
489621Sbill {
490621Sbill 
491621Sbill 	errs = 1;
492621Sbill 	done();
493621Sbill }
494621Sbill 
495621Sbill getsuf(cp)
496621Sbill 	char *cp;
497621Sbill {
498621Sbill 
499621Sbill 	if (*cp == 0)
500621Sbill 		return;
501621Sbill 	while (cp[1])
502621Sbill 		cp++;
503621Sbill 	if (cp[-1] != '.')
504621Sbill 		return (0);
505621Sbill 	return (*cp);
506621Sbill }
507621Sbill 
508621Sbill char *
509654Sbill setsuf(as, ch)
510654Sbill 	char *as;
511621Sbill {
512654Sbill 	register char *s, *s1;
513621Sbill 
514654Sbill 	s = s1 = savestr(as);
515654Sbill 	while (*s)
516654Sbill 		if (*s++ == '/')
517654Sbill 			s1 = s;
518654Sbill 	s[-1] = ch;
519654Sbill 	return (s1);
520621Sbill }
521621Sbill 
522621Sbill #define	NSAVETAB	512
523621Sbill char	*savetab;
524621Sbill int	saveleft;
525621Sbill 
526621Sbill char *
527621Sbill savestr(cp)
528621Sbill 	register char *cp;
529621Sbill {
530621Sbill 	register int len;
531621Sbill 
532621Sbill 	len = strlen(cp) + 1;
533621Sbill 	if (len > saveleft) {
534621Sbill 		saveleft = NSAVETAB;
535621Sbill 		if (len > saveleft)
536621Sbill 			saveleft = len;
537621Sbill 		savetab = (char *)malloc(saveleft);
538621Sbill 		if (savetab == 0) {
539621Sbill 			fprintf(stderr, "ran out of memory (savestr)\n");
540621Sbill 			exit(1);
541621Sbill 		}
542621Sbill 	}
543621Sbill 	strncpy(savetab, cp, len);
544621Sbill 	cp = savetab;
545621Sbill 	savetab += len;
546621Sbill 	return (cp);
547621Sbill }
548621Sbill 
549621Sbill suffix(cp)
550621Sbill 	char *cp;
551621Sbill {
552621Sbill 
553621Sbill 	if (cp[0] == 0 || cp[1] == 0)
554621Sbill 		return (0);
555621Sbill 	while (cp[1])
556621Sbill 		cp++;
557621Sbill 	if (cp[-1] == '.')
558621Sbill 		return (*cp);
559621Sbill 	return (0);
560621Sbill }
561