xref: /csrg-svn/usr.bin/pascal/pc/pc.c (revision 10672)
1*10672Speter static	char sccsid[] = "@(#)pc.c 3.19 02/01/83";
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':
1609140Smckusick 				pc0 = "/usr/src/ucb/pc0/a.out";
1613862Smckusic 				if (argp[3] != '\0') {
1623862Smckusic 					pc0 = &argp[3];
1633862Smckusic 				}
164621Sbill 				continue;
165621Sbill 			case '1':
1669140Smckusick 				pc1 = "/usr/src/lib/pcc/fort";
1673862Smckusic 				if (argp[3] != '\0') {
1683862Smckusic 					pc1 = &argp[3];
1693862Smckusic 				}
170621Sbill 				continue;
171621Sbill 			case '2':
1729140Smckusick 				pc2 = "/usr/src/ucb/pascal/pc2";
1733862Smckusic 				if (argp[3] != '\0') {
1743862Smckusic 					pc2 = &argp[3];
1753862Smckusic 				}
176621Sbill 				continue;
177621Sbill 			case '3':
1789140Smckusick 				pc3 = "/usr/src/ucb/pascal/pc3";
1793862Smckusic 				if (argp[3] != '\0') {
1803862Smckusic 					pc3 = &argp[3];
1813862Smckusic 				}
182621Sbill 				continue;
183621Sbill 			case 'l':
1845054Smckusic 				Tlflag = 1;
1859140Smckusick 				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();
329*10672Speter 	errs = 0;
330908Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/lib/crt0.o", 0, }; */
331621Sbill 	ldargs[0] = "ld";
332621Sbill 	ldargs[1] = "-X";
333654Sbill 	ldargs[2] = crt0;
334621Sbill 	for (i = 0; i < argc; i++) {
335621Sbill 		argp = argv[i];
336621Sbill 		if (argp[0] != '-') {
337621Sbill 			switch (getsuf(argp)) {
338621Sbill 
339621Sbill 			case 'p':
3401211Speter 			case 's':
341621Sbill 				ldargs[ldargx] = savestr(setsuf(argp, 'o'));
342621Sbill 				break;
343621Sbill 			default:
344621Sbill 				ldargs[ldargx] = argp;
345621Sbill 				break;
346621Sbill 			}
347621Sbill 			if (getsuf(ldargs[ldargx]) == 'o')
348621Sbill 			for (j = 0; j < ldargx; j++)
349621Sbill 				if (!strcmp(ldargs[j], ldargs[ldargx]))
350621Sbill 					goto duplicate;
351621Sbill 			ldargx++;
352621Sbill duplicate:
353621Sbill 			continue;
354621Sbill 		}
355621Sbill 		switch (argp[1]) {
356621Sbill 
357621Sbill 		case 'i':
358621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
359621Sbill 			    getsuf(argv[i+1]) != 'p')
360621Sbill 				i++;
361621Sbill 			continue;
362621Sbill 		case 'd':
363621Sbill 			if (argp[2] == 0)
364621Sbill 				continue;
365621Sbill 			ldargs[ldargx++] = argp;
366621Sbill 			continue;
367621Sbill 		case 'o':
368621Sbill 			ldargs[ldargx++] = argp;
369621Sbill 			i++;
370621Sbill 			ldargs[ldargx++] = argv[i];
371621Sbill 			continue;
372621Sbill 		case 'l':
373621Sbill 			if (argp[2])
374621Sbill 				ldargs[ldargx++] = argp;
375621Sbill 			continue;
376621Sbill 		case 'c':
377621Sbill 		case 'g':
378621Sbill 		case 'w':
379621Sbill 		case 'p':
380621Sbill 		case 'S':
381908Sbill 		case 'J':
382621Sbill 		case 'T':
383621Sbill 		case 'O':
384621Sbill 		case 'C':
385621Sbill 		case 'b':
386621Sbill 		case 's':
387621Sbill 		case 'z':
388621Sbill 			continue;
389621Sbill 		default:
390621Sbill 			ldargs[ldargx++] = argp;
391621Sbill 			continue;
392621Sbill 		}
393621Sbill 	}
394621Sbill 	ldargs[ldargx++] = lpc;
395621Sbill 	if (gflag)
396621Sbill 		ldargs[ldargx++] = "-lg";
3975054Smckusic 	if (pflag) {
3985054Smckusic 		ldargs[ldargx++] = "-lm_p";
3995054Smckusic 		ldargs[ldargx++] = "-lc_p";
4005054Smckusic 	} else {
40110561Smckusick #ifndef sun
4025054Smckusic 		ldargs[ldargx++] = "-lm";
4035054Smckusic 		ldargs[ldargx++] = "-lc";
40410561Smckusick #else
40510561Smckusick 		ldargs[ldargx++] = "-lMm";
40610561Smckusick 		ldargs[ldargx++] = "-lMc";
40710561Smckusick #endif
4085054Smckusic 	}
409621Sbill 	ldargs[ldargx] = 0;
410621Sbill 	if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0)
411621Sbill 		unlink(onepso);
412621Sbill 	done();
413621Sbill }
414621Sbill 
415621Sbill dosys(cmd, argv, in, out)
416621Sbill 	char *cmd, **argv, *in, *out;
417621Sbill {
418621Sbill 	union wait status;
419621Sbill 	int pid;
420621Sbill 
421621Sbill 	if (debug) {
422621Sbill 		int i;
423621Sbill 		printf("%s:", cmd);
424621Sbill 		for (i = 0; argv[i]; i++)
425621Sbill 			printf(" %s", argv[i]);
426621Sbill 		if (in)
427621Sbill 			printf(" <%s", in);
428621Sbill 		if (out)
429621Sbill 			printf(" >%s", out);
430621Sbill 		printf("\n");
431621Sbill 	}
432621Sbill 	pid = vfork();
433621Sbill 	if (pid < 0) {
434621Sbill 		fprintf(stderr, "pc: No more processes\n");
435621Sbill 		done();
436621Sbill 	}
437621Sbill 	if (pid == 0) {
438621Sbill 		if (in) {
439621Sbill 			close(0);
440621Sbill 			if (open(in, 0) != 0) {
441621Sbill 				perror(in);
442621Sbill 				exit(1);
443621Sbill 			}
444621Sbill 		}
445621Sbill 		if (out) {
446621Sbill 			close(1);
447621Sbill 			unlink(out);
448621Sbill 			if (creat(out, 0666) != 1) {
449621Sbill 				perror(out);
450621Sbill 				exit(1);
451621Sbill 			}
452621Sbill 		}
453621Sbill 		signal(SIGINT, SIG_DFL);
454621Sbill 		execv(cmd, argv);
455621Sbill 		perror(cmd);
456621Sbill 		exit(1);
457621Sbill 	}
458621Sbill 	while (wait(&status) != pid)
459621Sbill 		;
460621Sbill 	if (WIFSIGNALED(status)) {
4617766Smckusick 		if (status.w_termsig != SIGINT) {
4627766Smckusick 			fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]);
4637766Smckusick 			if (status.w_coredump)
4647766Smckusick 				fprintf(stderr, " (core dumped)");
4657766Smckusick 			fprintf(stderr, "\n");
4667766Smckusick 		}
467621Sbill 		errs = 100;
468621Sbill 		done();
469621Sbill 		/*NOTREACHED*/
470621Sbill 	}
471621Sbill 	if (status.w_retcode) {
472621Sbill 		errs = 1;
473621Sbill 		remove();
474621Sbill 	}
475621Sbill 	return (status.w_retcode);
476621Sbill }
477621Sbill 
478621Sbill done()
479621Sbill {
480621Sbill 
481621Sbill 	remove();
482621Sbill 	exit(errs);
483621Sbill }
484621Sbill 
485621Sbill remove()
486621Sbill {
487621Sbill 
488621Sbill 	if (tfile[0])
489621Sbill 		unlink(tfile[0]);
490621Sbill 	if (tfile[1])
491621Sbill 		unlink(tfile[1]);
492621Sbill }
493621Sbill 
494621Sbill onintr()
495621Sbill {
496621Sbill 
497621Sbill 	errs = 1;
498621Sbill 	done();
499621Sbill }
500621Sbill 
501621Sbill getsuf(cp)
502621Sbill 	char *cp;
503621Sbill {
504621Sbill 
505621Sbill 	if (*cp == 0)
506621Sbill 		return;
507621Sbill 	while (cp[1])
508621Sbill 		cp++;
509621Sbill 	if (cp[-1] != '.')
510621Sbill 		return (0);
511621Sbill 	return (*cp);
512621Sbill }
513621Sbill 
514621Sbill char *
515654Sbill setsuf(as, ch)
516654Sbill 	char *as;
517621Sbill {
518654Sbill 	register char *s, *s1;
519621Sbill 
520654Sbill 	s = s1 = savestr(as);
521654Sbill 	while (*s)
522654Sbill 		if (*s++ == '/')
523654Sbill 			s1 = s;
524654Sbill 	s[-1] = ch;
525654Sbill 	return (s1);
526621Sbill }
527621Sbill 
528621Sbill #define	NSAVETAB	512
529621Sbill char	*savetab;
530621Sbill int	saveleft;
531621Sbill 
532621Sbill char *
533621Sbill savestr(cp)
534621Sbill 	register char *cp;
535621Sbill {
536621Sbill 	register int len;
537621Sbill 
538621Sbill 	len = strlen(cp) + 1;
539621Sbill 	if (len > saveleft) {
540621Sbill 		saveleft = NSAVETAB;
541621Sbill 		if (len > saveleft)
542621Sbill 			saveleft = len;
543621Sbill 		savetab = (char *)malloc(saveleft);
544621Sbill 		if (savetab == 0) {
545621Sbill 			fprintf(stderr, "ran out of memory (savestr)\n");
546621Sbill 			exit(1);
547621Sbill 		}
548621Sbill 	}
549621Sbill 	strncpy(savetab, cp, len);
550621Sbill 	cp = savetab;
551621Sbill 	savetab += len;
552621Sbill 	return (cp);
553621Sbill }
554621Sbill 
555621Sbill suffix(cp)
556621Sbill 	char *cp;
557621Sbill {
558621Sbill 
559621Sbill 	if (cp[0] == 0 || cp[1] == 0)
560621Sbill 		return (0);
561621Sbill 	while (cp[1])
562621Sbill 		cp++;
563621Sbill 	if (cp[-1] == '.')
564621Sbill 		return (*cp);
565621Sbill 	return (0);
566621Sbill }
567