xref: /csrg-svn/usr.bin/pascal/pc/pc.c (revision 7596)
1*7596Smckusick static	char sccsid[] = "@(#)pc.c 3.15 07/29/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 
28*7596Smckusick 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 };
38*7596Smckusick int	pc3argx = 1;
39621Sbill #define	pc3args	pc0args
40621Sbill #define	ldargs	pc0args
41*7596Smckusick /* 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 
46621Sbill /*
47621Sbill  * If the number of .p arguments (np) is 1, and the number of .o arguments
48621Sbill  * (nxo) is 0, and we successfully create an ``a.out'', then we remove
49621Sbill  * the one .ps .o file (onepso).
50621Sbill  */
51621Sbill int	np, nxo;
52621Sbill char	*onepso;
53621Sbill int	errs;
54621Sbill 
55621Sbill int	onintr();
56621Sbill 
57621Sbill main(argc, argv)
58621Sbill 	int argc;
59621Sbill 	char **argv;
60621Sbill {
61621Sbill 	register char *argp;
62621Sbill 	register int i;
63621Sbill 	int savargx;
64621Sbill 	char *t, c;
65621Sbill 	int j;
66621Sbill 
67621Sbill 	argc--, argv++;
68621Sbill 	if (argc == 0) {
69621Sbill 		execl("/bin/cat", "cat", "/usr/lib/how_pc");
70621Sbill 		exit(1);
71621Sbill 	}
72621Sbill 	if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
73621Sbill 		signal(SIGINT, onintr);
74621Sbill 		signal(SIGTERM, onintr);
75621Sbill 	}
76621Sbill 	for (i = 0; i < argc; i++) {
77621Sbill 		argp = argv[i];
78621Sbill 		if (argp[0] != '-')
79621Sbill 			continue;
80621Sbill 		switch (argp[1]) {
81621Sbill 
82621Sbill 		case 'd':
83621Sbill 			if (argp[2] == 0)
84621Sbill 				debug++;
85621Sbill 			continue;
86621Sbill 		case 'i':
87621Sbill 			pc0args[pc0argx++] = "-i";
88621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
89621Sbill 			    getsuf(argv[i+1]) != 'p') {
90621Sbill 				pc0args[pc0argx++] = argv[i+1];
91621Sbill 				i++;
92621Sbill 			}
93621Sbill 			if (i+1 == argc) {
94621Sbill 				fprintf(stderr, "pc: bad -i construction\n");
95621Sbill 				exit(1);
96621Sbill 			}
97621Sbill 			continue;
98621Sbill 		case 'o':
99621Sbill 			i++;
100621Sbill 			if (i == argc) {
101621Sbill 				fprintf(stderr, "pc: -o must specify file\n");
102621Sbill 				exit(1);
103621Sbill 			}
104621Sbill 			c = getsuf(argv[i]);
105621Sbill 			if (c == 'o' || c == 'p' || c == 'c') {
106621Sbill 				fprintf(stderr, "pc: -o would overwrite %s\n",
107621Sbill 				    argv[i]);
108621Sbill 				exit(1);
109621Sbill 			}
110621Sbill 			continue;
111621Sbill 		case 'O':
112621Sbill 			Oflag = 1;
113621Sbill 			continue;
114621Sbill 		case 'S':
115621Sbill 			Sflag = 1;
116621Sbill 			continue;
117908Sbill 		case 'J':
118908Sbill 			Jflag = 1;
119908Sbill 			continue;
120621Sbill 		case 'T':
121621Sbill 			switch (argp[2]) {
122621Sbill 
123621Sbill 			case '0':
124908Sbill 				pc0 = "/usr/src/cmd/pc0/a.out";
1253862Smckusic 				if (argp[3] != '\0') {
1263862Smckusic 					pc0 = &argp[3];
1273862Smckusic 				}
128621Sbill 				continue;
129621Sbill 			case '1':
130908Sbill 				pc1 = "/usr/src/cmd/pcc/pc1";
1313862Smckusic 				if (argp[3] != '\0') {
1323862Smckusic 					pc1 = &argp[3];
1333862Smckusic 				}
134621Sbill 				continue;
135621Sbill 			case '2':
1362194Smckusic 				pc2 = "/usr/src/cmd/pascal/pc2";
1373862Smckusic 				if (argp[3] != '\0') {
1383862Smckusic 					pc2 = &argp[3];
1393862Smckusic 				}
140621Sbill 				continue;
141621Sbill 			case '3':
1422194Smckusic 				pc3 = "/usr/src/cmd/pascal/pc3";
1433862Smckusic 				if (argp[3] != '\0') {
1443862Smckusic 					pc3 = &argp[3];
1453862Smckusic 				}
146621Sbill 				continue;
147621Sbill 			case 'l':
1485054Smckusic 				Tlflag = 1;
1492127Smckusic 				lpc = "/usr/src/lib/libpc/libpc";
1503862Smckusic 				if (argp[3] != '\0') {
1513862Smckusic 					lpc = &argp[3];
1523862Smckusic 				}
153621Sbill 				continue;
154621Sbill 			}
155621Sbill 			continue;
156621Sbill 		case 'c':
157621Sbill 			cflag = 1;
158621Sbill 			continue;
159621Sbill 		case 'l':
160621Sbill 			if (argp[2])
161621Sbill 				continue;
162621Sbill 			/* fall into ... */
163621Sbill 		case 'b':
164621Sbill 		case 's':
165621Sbill 		case 'z':
166621Sbill 		case 'C':
167621Sbill 			pc0args[pc0argx++] = argp;
168621Sbill 			continue;
169*7596Smckusick 		case 'w':
170*7596Smckusick 			wflag = 1;
171*7596Smckusick 			pc0args[pc0argx++] = argp;
172*7596Smckusick 			continue;
173*7596Smckusick 		case 'g':
174*7596Smckusick 			gflag = 1;
175*7596Smckusick 			pc0args[pc0argx++] = argp;
176*7596Smckusick 			continue;
177621Sbill 		case 't':
178621Sbill 			fprintf(stderr, "pc: -t is default; -C for checking\n");
179621Sbill 			continue;
180621Sbill 		case 'p':
1815054Smckusic 			if (argp[2] == 'g')
1825054Smckusic 				crt0 = gcrt0;
1835054Smckusic 			else
1845054Smckusic 				crt0 = mcrt0;
1855054Smckusic 			if (!Tlflag)
1865054Smckusic 				lpc = "-lpc_p";
1875054Smckusic 			pflag = 1;
188654Sbill 			continue;
189621Sbill 		}
190621Sbill 	}
191621Sbill 	if (gflag && Oflag) {
192621Sbill 		fprintf(stderr, "pc: warning: -g overrides -O\n");
193621Sbill 		Oflag = 0;
194621Sbill 	}
195621Sbill 	tname[0] = mktemp("/tmp/p0XXXXXX");
196621Sbill 	tname[1] = mktemp("/tmp/p1XXXXXX");
197621Sbill 	savargx = pc0argx;
198621Sbill 	for (i = 0; i < argc; i++) {
199621Sbill 		argp = argv[i];
200621Sbill 		if (argp[0] == '-')
201621Sbill 			continue;
2021211Speter 		if (suffix(argp) == 's') {
2031211Speter 			asargx = 1;
2041211Speter 			if (Jflag)
2051211Speter 				asargs[asargx++] = "-J";
2061211Speter 			asargs[asargx++] = argp;
2071211Speter 			asargs[asargx++] = "-o";
2081211Speter 			tfile[1] = setsuf(argp, 'o');
2091211Speter 			asargs[asargx++] = tfile[1];
2101211Speter 			asargs[asargx] = 0;
2111211Speter 			if (dosys(as, asargs, 0, 0))
2121211Speter 				continue;
2131211Speter 			tfile[1] = 0;
2141211Speter 			continue;
2151211Speter 		}
216621Sbill 		if (suffix(argp) != 'p')
217621Sbill 			continue;
218621Sbill 		tfile[0] = tname[0];
219621Sbill 		pc0args[2] = tfile[0];
220621Sbill 		pc0argx = savargx;
221654Sbill 		if (pflag)
222654Sbill 			pc0args[pc0argx++] = "-p";
223621Sbill 		pc0args[pc0argx++] = argp;
224621Sbill 		pc0args[pc0argx] = 0;
225621Sbill 		if (dosys(pc0, pc0args, 0, 0))
226621Sbill 			continue;
227621Sbill 		pc1args[1] = tfile[0];
228654Sbill 		tfile[1] = tname[1];
229621Sbill 		if (dosys(pc1, pc1args, 0, tfile[1]))
230621Sbill 			continue;
231621Sbill 		unlink(tfile[0]);
2322340Smckusic 		tfile[0] = tname[0];
2332340Smckusic 		if (Oflag) {
2342340Smckusic 			if (dosys(c2, c2args, tfile[1], tfile[0]))
2352340Smckusic 				continue;
2362340Smckusic 			unlink(tfile[1]);
2372340Smckusic 			tfile[1] = tfile[0];
2382340Smckusic 			tfile[0] = tname[1];
2392340Smckusic 		}
2402340Smckusic 		if (Sflag)
241654Sbill 			tfile[0] = setsuf(argp, 's');
242621Sbill 		if (dosys(pc2, pc2args, tfile[1], tfile[0]))
243621Sbill 			continue;
244621Sbill 		unlink(tfile[1]);
245621Sbill 		tfile[1] = 0;
246654Sbill 		if (Sflag) {
247654Sbill 			tfile[0] = 0;
248621Sbill 			continue;
249654Sbill 		}
250908Sbill 		asargx = 1;
251908Sbill 		if (Jflag)
252908Sbill 			asargs[asargx++] = "-J";
253908Sbill 		asargs[asargx++] = tfile[0];
254908Sbill 		asargs[asargx++] = "-o";
255621Sbill 		tfile[1] = setsuf(argp, 'o');
256908Sbill 		asargs[asargx++] = tfile[1];
257908Sbill 		asargs[asargx] = 0;
258621Sbill 		if (dosys(as, asargs, 0, 0))
259621Sbill 			continue;
260621Sbill 		tfile[1] = 0;
261621Sbill 		remove();
262621Sbill 	}
263621Sbill 	if (errs || cflag || Sflag)
264621Sbill 		done();
265*7596Smckusick /* char	*pc3args[NARGS] =	{ "pc3", 0 }; */
266621Sbill 	pc3args[0] = "pc3";
267*7596Smckusick 	if (wflag)
268*7596Smckusick 		pc3args[pc3argx++] = "-w";
269*7596Smckusick 	pc3args[pc3argx++] = "/usr/lib/pcexterns.o";
270621Sbill 	for (i = 0; i < argc; i++) {
271621Sbill 		argp = argv[i];
272621Sbill 		if (!strcmp(argp, "-o"))
273621Sbill 			i++;
274621Sbill 		if (argp[0] == '-')
275621Sbill 			continue;
276621Sbill 		switch (getsuf(argp)) {
277621Sbill 
278621Sbill 		case 'o':
279621Sbill 			pc3args[pc3argx++] = argp;
280621Sbill 			nxo++;
281621Sbill 			continue;
2821211Speter 		case 's':
283621Sbill 		case 'p':
284621Sbill 			onepso = pc3args[pc3argx++] =
285621Sbill 			    savestr(setsuf(argp, 'o'));
286621Sbill 			np++;
287621Sbill 			continue;
288621Sbill 		}
289621Sbill 	}
290621Sbill 	pc3args[pc3argx] = 0;
291*7596Smckusick 	if (dosys(pc3, pc3args, 0, 0) > 1)
292621Sbill 		done();
293908Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/lib/crt0.o", 0, }; */
294621Sbill 	ldargs[0] = "ld";
295621Sbill 	ldargs[1] = "-X";
296654Sbill 	ldargs[2] = crt0;
297621Sbill 	for (i = 0; i < argc; i++) {
298621Sbill 		argp = argv[i];
299621Sbill 		if (argp[0] != '-') {
300621Sbill 			switch (getsuf(argp)) {
301621Sbill 
302621Sbill 			case 'p':
3031211Speter 			case 's':
304621Sbill 				ldargs[ldargx] = savestr(setsuf(argp, 'o'));
305621Sbill 				break;
306621Sbill 			default:
307621Sbill 				ldargs[ldargx] = argp;
308621Sbill 				break;
309621Sbill 			}
310621Sbill 			if (getsuf(ldargs[ldargx]) == 'o')
311621Sbill 			for (j = 0; j < ldargx; j++)
312621Sbill 				if (!strcmp(ldargs[j], ldargs[ldargx]))
313621Sbill 					goto duplicate;
314621Sbill 			ldargx++;
315621Sbill duplicate:
316621Sbill 			continue;
317621Sbill 		}
318621Sbill 		switch (argp[1]) {
319621Sbill 
320621Sbill 		case 'i':
321621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
322621Sbill 			    getsuf(argv[i+1]) != 'p')
323621Sbill 				i++;
324621Sbill 			continue;
325621Sbill 		case 'd':
326621Sbill 			if (argp[2] == 0)
327621Sbill 				continue;
328621Sbill 			ldargs[ldargx++] = argp;
329621Sbill 			continue;
330621Sbill 		case 'o':
331621Sbill 			ldargs[ldargx++] = argp;
332621Sbill 			i++;
333621Sbill 			ldargs[ldargx++] = argv[i];
334621Sbill 			continue;
335621Sbill 		case 'l':
336621Sbill 			if (argp[2])
337621Sbill 				ldargs[ldargx++] = argp;
338621Sbill 			continue;
339621Sbill 		case 'c':
340621Sbill 		case 'g':
341621Sbill 		case 'w':
342621Sbill 		case 'p':
343621Sbill 		case 'S':
344908Sbill 		case 'J':
345621Sbill 		case 'T':
346621Sbill 		case 'O':
347621Sbill 		case 'C':
348621Sbill 		case 'b':
349621Sbill 		case 's':
350621Sbill 		case 'z':
351621Sbill 			continue;
352621Sbill 		default:
353621Sbill 			ldargs[ldargx++] = argp;
354621Sbill 			continue;
355621Sbill 		}
356621Sbill 	}
357621Sbill 	ldargs[ldargx++] = lpc;
358621Sbill 	if (gflag)
359621Sbill 		ldargs[ldargx++] = "-lg";
3605054Smckusic 	if (pflag) {
3615054Smckusic 		ldargs[ldargx++] = "-lm_p";
3625054Smckusic 		ldargs[ldargx++] = "-lc_p";
3635054Smckusic 	} else {
3645054Smckusic 		ldargs[ldargx++] = "-lm";
3655054Smckusic 		ldargs[ldargx++] = "-lc";
3665054Smckusic 	}
367621Sbill 	ldargs[ldargx] = 0;
368621Sbill 	if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0)
369621Sbill 		unlink(onepso);
370621Sbill 	done();
371621Sbill }
372621Sbill 
373621Sbill dosys(cmd, argv, in, out)
374621Sbill 	char *cmd, **argv, *in, *out;
375621Sbill {
376621Sbill 	union wait status;
377621Sbill 	int pid;
378621Sbill 
379621Sbill 	if (debug) {
380621Sbill 		int i;
381621Sbill 		printf("%s:", cmd);
382621Sbill 		for (i = 0; argv[i]; i++)
383621Sbill 			printf(" %s", argv[i]);
384621Sbill 		if (in)
385621Sbill 			printf(" <%s", in);
386621Sbill 		if (out)
387621Sbill 			printf(" >%s", out);
388621Sbill 		printf("\n");
389621Sbill 	}
390621Sbill 	pid = vfork();
391621Sbill 	if (pid < 0) {
392621Sbill 		fprintf(stderr, "pc: No more processes\n");
393621Sbill 		done();
394621Sbill 	}
395621Sbill 	if (pid == 0) {
396621Sbill 		if (in) {
397621Sbill 			close(0);
398621Sbill 			if (open(in, 0) != 0) {
399621Sbill 				perror(in);
400621Sbill 				exit(1);
401621Sbill 			}
402621Sbill 		}
403621Sbill 		if (out) {
404621Sbill 			close(1);
405621Sbill 			unlink(out);
406621Sbill 			if (creat(out, 0666) != 1) {
407621Sbill 				perror(out);
408621Sbill 				exit(1);
409621Sbill 			}
410621Sbill 		}
411621Sbill 		signal(SIGINT, SIG_DFL);
412621Sbill 		execv(cmd, argv);
413621Sbill 		perror(cmd);
414621Sbill 		exit(1);
415621Sbill 	}
416621Sbill 	while (wait(&status) != pid)
417621Sbill 		;
418621Sbill 	if (WIFSIGNALED(status)) {
419621Sbill 		if (status.w_termsig != SIGINT)
420621Sbill 			fprintf(stderr, "Fatal error in %s\n", cmd);
421621Sbill 		errs = 100;
422621Sbill 		done();
423621Sbill 		/*NOTREACHED*/
424621Sbill 	}
425621Sbill 	if (status.w_retcode) {
426621Sbill 		errs = 1;
427621Sbill 		remove();
428621Sbill 	}
429621Sbill 	return (status.w_retcode);
430621Sbill }
431621Sbill 
432621Sbill done()
433621Sbill {
434621Sbill 
435621Sbill 	remove();
436621Sbill 	exit(errs);
437621Sbill }
438621Sbill 
439621Sbill remove()
440621Sbill {
441621Sbill 
442621Sbill 	if (tfile[0])
443621Sbill 		unlink(tfile[0]);
444621Sbill 	if (tfile[1])
445621Sbill 		unlink(tfile[1]);
446621Sbill }
447621Sbill 
448621Sbill onintr()
449621Sbill {
450621Sbill 
451621Sbill 	errs = 1;
452621Sbill 	done();
453621Sbill }
454621Sbill 
455621Sbill getsuf(cp)
456621Sbill 	char *cp;
457621Sbill {
458621Sbill 
459621Sbill 	if (*cp == 0)
460621Sbill 		return;
461621Sbill 	while (cp[1])
462621Sbill 		cp++;
463621Sbill 	if (cp[-1] != '.')
464621Sbill 		return (0);
465621Sbill 	return (*cp);
466621Sbill }
467621Sbill 
468621Sbill char *
469654Sbill setsuf(as, ch)
470654Sbill 	char *as;
471621Sbill {
472654Sbill 	register char *s, *s1;
473621Sbill 
474654Sbill 	s = s1 = savestr(as);
475654Sbill 	while (*s)
476654Sbill 		if (*s++ == '/')
477654Sbill 			s1 = s;
478654Sbill 	s[-1] = ch;
479654Sbill 	return (s1);
480621Sbill }
481621Sbill 
482621Sbill #define	NSAVETAB	512
483621Sbill char	*savetab;
484621Sbill int	saveleft;
485621Sbill 
486621Sbill char *
487621Sbill savestr(cp)
488621Sbill 	register char *cp;
489621Sbill {
490621Sbill 	register int len;
491621Sbill 
492621Sbill 	len = strlen(cp) + 1;
493621Sbill 	if (len > saveleft) {
494621Sbill 		saveleft = NSAVETAB;
495621Sbill 		if (len > saveleft)
496621Sbill 			saveleft = len;
497621Sbill 		savetab = (char *)malloc(saveleft);
498621Sbill 		if (savetab == 0) {
499621Sbill 			fprintf(stderr, "ran out of memory (savestr)\n");
500621Sbill 			exit(1);
501621Sbill 		}
502621Sbill 	}
503621Sbill 	strncpy(savetab, cp, len);
504621Sbill 	cp = savetab;
505621Sbill 	savetab += len;
506621Sbill 	return (cp);
507621Sbill }
508621Sbill 
509621Sbill suffix(cp)
510621Sbill 	char *cp;
511621Sbill {
512621Sbill 
513621Sbill 	if (cp[0] == 0 || cp[1] == 0)
514621Sbill 		return (0);
515621Sbill 	while (cp[1])
516621Sbill 		cp++;
517621Sbill 	if (cp[-1] == '.')
518621Sbill 		return (*cp);
519621Sbill 	return (0);
520621Sbill }
521