xref: /csrg-svn/usr.bin/pascal/pc/pc.c (revision 7766)
1*7766Smckusick static	char sccsid[] = "@(#)pc.c 3.16 08/16/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 
46*7766Smckusick char *mesg[] = {
47*7766Smckusick 	0,
48*7766Smckusick 	"Hangup",
49*7766Smckusick 	"Interrupt",
50*7766Smckusick 	"Quit",
51*7766Smckusick 	"Illegal instruction",
52*7766Smckusick 	"Trace/BPT trap",
53*7766Smckusick 	"IOT trap",
54*7766Smckusick 	"EMT trap",
55*7766Smckusick 	"Floating exception",
56*7766Smckusick 	"Killed",
57*7766Smckusick 	"Bus error",
58*7766Smckusick 	"Segmentation fault",
59*7766Smckusick 	"Bad system call",
60*7766Smckusick 	"Broken pipe",
61*7766Smckusick 	"Alarm clock",
62*7766Smckusick 	"Terminated",
63*7766Smckusick 	"Signal 16",
64*7766Smckusick 	"Stopped (signal)",
65*7766Smckusick 	"Stopped",
66*7766Smckusick 	"Continued",
67*7766Smckusick 	"Child exited",
68*7766Smckusick 	"Stopped (tty input)",
69*7766Smckusick 	"Stopped (tty output)",
70*7766Smckusick 	"Tty input interrupt",
71*7766Smckusick 	"Cputime limit exceeded",
72*7766Smckusick 	"Filesize limit exceeded",
73*7766Smckusick 	"Signal 26",
74*7766Smckusick 	"Signal 27",
75*7766Smckusick 	"Signal 28",
76*7766Smckusick 	"Signal 29",
77*7766Smckusick 	"Signal 30",
78*7766Smckusick 	"Signal 31",
79*7766Smckusick 	"Signal 32"
80*7766Smckusick };
81*7766Smckusick 
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':
160908Sbill 				pc0 = "/usr/src/cmd/pc0/a.out";
1613862Smckusic 				if (argp[3] != '\0') {
1623862Smckusic 					pc0 = &argp[3];
1633862Smckusic 				}
164621Sbill 				continue;
165621Sbill 			case '1':
166908Sbill 				pc1 = "/usr/src/cmd/pcc/pc1";
1673862Smckusic 				if (argp[3] != '\0') {
1683862Smckusic 					pc1 = &argp[3];
1693862Smckusic 				}
170621Sbill 				continue;
171621Sbill 			case '2':
1722194Smckusic 				pc2 = "/usr/src/cmd/pascal/pc2";
1733862Smckusic 				if (argp[3] != '\0') {
1743862Smckusic 					pc2 = &argp[3];
1753862Smckusic 				}
176621Sbill 				continue;
177621Sbill 			case '3':
1782194Smckusic 				pc3 = "/usr/src/cmd/pascal/pc3";
1793862Smckusic 				if (argp[3] != '\0') {
1803862Smckusic 					pc3 = &argp[3];
1813862Smckusic 				}
182621Sbill 				continue;
183621Sbill 			case 'l':
1845054Smckusic 				Tlflag = 1;
1852127Smckusic 				lpc = "/usr/src/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)) {
455*7766Smckusick 		if (status.w_termsig != SIGINT) {
456*7766Smckusick 			fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]);
457*7766Smckusick 			if (status.w_coredump)
458*7766Smckusick 				fprintf(stderr, " (core dumped)");
459*7766Smckusick 			fprintf(stderr, "\n");
460*7766Smckusick 		}
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