xref: /csrg-svn/usr.bin/pascal/pc/pc.c (revision 621)
1*621Sbill static	char sccsid[] = "@(#)pc.c 3.1 08/15/80";
2*621Sbill #include <stdio.h>
3*621Sbill #include <signal.h>
4*621Sbill #include <wait.h>
5*621Sbill 
6*621Sbill /*
7*621Sbill  * pc - front end for pascal compiler.
8*621Sbill  */
9*621Sbill char	*pc0 = "/usr/new/pc0";
10*621Sbill char	*pc1 = "/usr/new/pc1";
11*621Sbill char	*pc2 = "/usr/new/pc2";
12*621Sbill char	*c2 = "/usr/new/c2";
13*621Sbill char	*pc3 = "/usr/new/pc3";
14*621Sbill char	*ld = "/usr/new/ld";
15*621Sbill char	*as = "/usr/new/as";
16*621Sbill char	*lpc = "-lpc";
17*621Sbill 
18*621Sbill char	*mktemp();
19*621Sbill char	*tname[2];
20*621Sbill char	*tfile[2];
21*621Sbill 
22*621Sbill char	*setsuf(), *savestr();
23*621Sbill 
24*621Sbill int	Sflag, Oflag, cflag, gflag;
25*621Sbill int	debug;
26*621Sbill 
27*621Sbill #define	NARGS	512
28*621Sbill int	ldargx = 3;
29*621Sbill int	pc0argx = 3;
30*621Sbill char	*pc0args[NARGS] =	{ "pc0", "-o", "XXX" };
31*621Sbill char	*pc1args[3] =		{ "pc1", 0, };
32*621Sbill char	*pc2args[2] =		{ "pc2", 0 };
33*621Sbill char	*c2args[4] =		{ "c2", 0, 0, 0 };
34*621Sbill int	pc3argx = 1;
35*621Sbill #define	pc3args	pc0args
36*621Sbill #define	ldargs	pc0args
37*621Sbill /* char	*pc3args[NARGS] =	{ "pc3", 0 }; */
38*621Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/usr/new/crt0.o", 0, }; */
39*621Sbill char	*asargs[5] =		{ "as", 0, };
40*621Sbill 
41*621Sbill /*
42*621Sbill  * If the number of .p arguments (np) is 1, and the number of .o arguments
43*621Sbill  * (nxo) is 0, and we successfully create an ``a.out'', then we remove
44*621Sbill  * the one .ps .o file (onepso).
45*621Sbill  */
46*621Sbill int	np, nxo;
47*621Sbill char	*onepso;
48*621Sbill int	errs;
49*621Sbill 
50*621Sbill int	onintr();
51*621Sbill 
52*621Sbill main(argc, argv)
53*621Sbill 	int argc;
54*621Sbill 	char **argv;
55*621Sbill {
56*621Sbill 	register char *argp;
57*621Sbill 	register int i;
58*621Sbill 	int savargx;
59*621Sbill 	char *t, c;
60*621Sbill 	int j;
61*621Sbill 
62*621Sbill 	argc--, argv++;
63*621Sbill 	if (argc == 0) {
64*621Sbill 		execl("/bin/cat", "cat", "/usr/lib/how_pc");
65*621Sbill 		exit(1);
66*621Sbill 	}
67*621Sbill 	if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
68*621Sbill 		signal(SIGINT, onintr);
69*621Sbill 		signal(SIGTERM, onintr);
70*621Sbill 	}
71*621Sbill 	for (i = 0; i < argc; i++) {
72*621Sbill 		argp = argv[i];
73*621Sbill 		if (argp[0] != '-')
74*621Sbill 			continue;
75*621Sbill 		switch (argp[1]) {
76*621Sbill 
77*621Sbill 		case 'd':
78*621Sbill 			if (argp[2] == 0)
79*621Sbill 				debug++;
80*621Sbill 			continue;
81*621Sbill 		case 'i':
82*621Sbill 			pc0args[pc0argx++] = "-i";
83*621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
84*621Sbill 			    getsuf(argv[i+1]) != 'p') {
85*621Sbill 				pc0args[pc0argx++] = argv[i+1];
86*621Sbill 				i++;
87*621Sbill 			}
88*621Sbill 			if (i+1 == argc) {
89*621Sbill 				fprintf(stderr, "pc: bad -i construction\n");
90*621Sbill 				exit(1);
91*621Sbill 			}
92*621Sbill 			continue;
93*621Sbill 		case 'o':
94*621Sbill 			i++;
95*621Sbill 			if (i == argc) {
96*621Sbill 				fprintf(stderr, "pc: -o must specify file\n");
97*621Sbill 				exit(1);
98*621Sbill 			}
99*621Sbill 			c = getsuf(argv[i]);
100*621Sbill 			if (c == 'o' || c == 'p' || c == 'c') {
101*621Sbill 				fprintf(stderr, "pc: -o would overwrite %s\n",
102*621Sbill 				    argv[i]);
103*621Sbill 				exit(1);
104*621Sbill 			}
105*621Sbill 			continue;
106*621Sbill 		case 'O':
107*621Sbill 			Oflag = 1;
108*621Sbill 			continue;
109*621Sbill 		case 'S':
110*621Sbill 			Sflag = 1;
111*621Sbill 			continue;
112*621Sbill 		case 'T':
113*621Sbill 			switch (argp[2]) {
114*621Sbill 
115*621Sbill 			case '0':
116*621Sbill 				pc0 = "/vb/grad/peter/pc/npc0/src/a.pc";
117*621Sbill 				continue;
118*621Sbill 			case '1':
119*621Sbill 				pc1 = "/usr/src/new/pcc/pc1";
120*621Sbill 				continue;
121*621Sbill 			case '2':
122*621Sbill 				pc2 = "/usr/new/pc2";
123*621Sbill 				continue;
124*621Sbill 			case '3':
125*621Sbill 				pc3 = "/usr/new/pc3";
126*621Sbill 				continue;
127*621Sbill 			case 'l':
128*621Sbill 				lpc = "-lnpc";
129*621Sbill 				continue;
130*621Sbill 			}
131*621Sbill 			continue;
132*621Sbill 		case 'c':
133*621Sbill 			cflag = 1;
134*621Sbill 			continue;
135*621Sbill 		case 'l':
136*621Sbill 			if (argp[2])
137*621Sbill 				continue;
138*621Sbill 			/* fall into ... */
139*621Sbill 		case 'b':
140*621Sbill 		case 'g':
141*621Sbill 		case 's':
142*621Sbill 		case 'w':
143*621Sbill 		case 'z':
144*621Sbill 		case 'C':
145*621Sbill 			pc0args[pc0argx++] = argp;
146*621Sbill 			if (argp[1] == 'g')
147*621Sbill 				gflag = 1;
148*621Sbill 			continue;
149*621Sbill 		case 't':
150*621Sbill 			fprintf(stderr, "pc: -t is default; -C for checking\n");
151*621Sbill 			continue;
152*621Sbill 		case 'p':
153*621Sbill 			fprintf(stderr, "pc: -p (profiling) not implemented\n");
154*621Sbill 			exit(1);
155*621Sbill 		}
156*621Sbill 	}
157*621Sbill 	if (gflag && Oflag) {
158*621Sbill 		fprintf(stderr, "pc: warning: -g overrides -O\n");
159*621Sbill 		Oflag = 0;
160*621Sbill 	}
161*621Sbill 	tname[0] = mktemp("/tmp/p0XXXXXX");
162*621Sbill 	tname[1] = mktemp("/tmp/p1XXXXXX");
163*621Sbill 	savargx = pc0argx;
164*621Sbill 	for (i = 0; i < argc; i++) {
165*621Sbill 		argp = argv[i];
166*621Sbill 		if (argp[0] == '-')
167*621Sbill 			continue;
168*621Sbill 		if (suffix(argp) != 'p')
169*621Sbill 			continue;
170*621Sbill 		tfile[0] = tname[0];
171*621Sbill 		pc0args[2] = tfile[0];
172*621Sbill 		pc0argx = savargx;
173*621Sbill 		pc0args[pc0argx++] = argp;
174*621Sbill 		pc0args[pc0argx] = 0;
175*621Sbill 		if (dosys(pc0, pc0args, 0, 0))
176*621Sbill 			continue;
177*621Sbill 		pc1args[1] = tfile[0];
178*621Sbill 		if (Sflag && !Oflag)
179*621Sbill 			tfile[1] = setsuf(argp, 's');
180*621Sbill 		else
181*621Sbill 			tfile[1] = tname[1];
182*621Sbill 		if (dosys(pc1, pc1args, 0, tfile[1]))
183*621Sbill 			continue;
184*621Sbill 		unlink(tfile[0]);
185*621Sbill 		if (dosys(pc2, pc2args, tfile[1], tfile[0]))
186*621Sbill 			continue;
187*621Sbill 		unlink(tfile[1]);
188*621Sbill 		tfile[1] = 0;
189*621Sbill 		if (Oflag) {
190*621Sbill 			if (Sflag)
191*621Sbill 				tfile[1] = setsuf(argp, 's');
192*621Sbill 			else
193*621Sbill 				tfile[1] = tname[0];
194*621Sbill 			if (dosys(c2, c2args, tfile[0], tfile[1]))
195*621Sbill 				continue;
196*621Sbill 			unlink(tfile[0]);
197*621Sbill 			tfile[0] = tfile[1];
198*621Sbill 			tfile[1] = 0;
199*621Sbill 		}
200*621Sbill 		if (Sflag)
201*621Sbill 			continue;
202*621Sbill 		asargs[1] = tfile[0];
203*621Sbill 		asargs[2] = "-o";
204*621Sbill 		tfile[1] = setsuf(argp, 'o');
205*621Sbill 		asargs[3] = tfile[1];
206*621Sbill 		if (dosys(as, asargs, 0, 0))
207*621Sbill 			continue;
208*621Sbill 		tfile[1] = 0;
209*621Sbill 		remove();
210*621Sbill 	}
211*621Sbill 	if (errs || cflag || Sflag)
212*621Sbill 		done();
213*621Sbill /* char	*pc3args[NARGS] =	{ "pc3", 0 }; */
214*621Sbill 	pc3args[0] = "pc3";
215*621Sbill 	for (i = 0; i < argc; i++) {
216*621Sbill 		argp = argv[i];
217*621Sbill 		if (!strcmp(argp, "-o"))
218*621Sbill 			i++;
219*621Sbill 		if (argp[0] == '-')
220*621Sbill 			continue;
221*621Sbill 		switch (getsuf(argp)) {
222*621Sbill 
223*621Sbill 		case 'd':
224*621Sbill 			continue;
225*621Sbill 		case 'o':
226*621Sbill 			pc3args[pc3argx++] = argp;
227*621Sbill 			nxo++;
228*621Sbill 			continue;
229*621Sbill 		case 'p':
230*621Sbill 			onepso = pc3args[pc3argx++] =
231*621Sbill 			    savestr(setsuf(argp, 'o'));
232*621Sbill 			np++;
233*621Sbill 			continue;
234*621Sbill 		}
235*621Sbill 	}
236*621Sbill 	pc3args[pc3argx] = 0;
237*621Sbill 	if (dosys(pc3, pc3args, 0, 0))
238*621Sbill 		done();
239*621Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/usr/new/crt0.o", 0, }; */
240*621Sbill 	ldargs[0] = "ld";
241*621Sbill 	ldargs[1] = "-X";
242*621Sbill 	ldargs[2] = "/usr/new/crt0.o";
243*621Sbill 	for (i = 0; i < argc; i++) {
244*621Sbill 		argp = argv[i];
245*621Sbill 		if (argp[0] != '-') {
246*621Sbill 			switch (getsuf(argp)) {
247*621Sbill 
248*621Sbill 			case 'p':
249*621Sbill 				ldargs[ldargx] = savestr(setsuf(argp, 'o'));
250*621Sbill 				break;
251*621Sbill 			default:
252*621Sbill 				ldargs[ldargx] = argp;
253*621Sbill 				break;
254*621Sbill 			}
255*621Sbill 			if (getsuf(ldargs[ldargx]) == 'o')
256*621Sbill 			for (j = 0; j < ldargx; j++)
257*621Sbill 				if (!strcmp(ldargs[j], ldargs[ldargx]))
258*621Sbill 					goto duplicate;
259*621Sbill 			ldargx++;
260*621Sbill duplicate:
261*621Sbill 			continue;
262*621Sbill 		}
263*621Sbill 		switch (argp[1]) {
264*621Sbill 
265*621Sbill 		case 'i':
266*621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
267*621Sbill 			    getsuf(argv[i+1]) != 'p')
268*621Sbill 				i++;
269*621Sbill 			continue;
270*621Sbill 		case 'd':
271*621Sbill 			if (argp[2] == 0)
272*621Sbill 				continue;
273*621Sbill 			ldargs[ldargx++] = argp;
274*621Sbill 			continue;
275*621Sbill 		case 'o':
276*621Sbill 			ldargs[ldargx++] = argp;
277*621Sbill 			i++;
278*621Sbill 			ldargs[ldargx++] = argv[i];
279*621Sbill 			continue;
280*621Sbill 		case 'l':
281*621Sbill 			if (argp[2])
282*621Sbill 				ldargs[ldargx++] = argp;
283*621Sbill 			continue;
284*621Sbill 		case 'c':
285*621Sbill 		case 'g':
286*621Sbill 		case 'w':
287*621Sbill 		case 'p':
288*621Sbill 		case 'S':
289*621Sbill 		case 'T':
290*621Sbill 		case 'O':
291*621Sbill 		case 'C':
292*621Sbill 		case 'b':
293*621Sbill 		case 's':
294*621Sbill 		case 'z':
295*621Sbill 			continue;
296*621Sbill 		default:
297*621Sbill 			ldargs[ldargx++] = argp;
298*621Sbill 			continue;
299*621Sbill 		}
300*621Sbill 	}
301*621Sbill 	ldargs[ldargx++] = lpc;
302*621Sbill 	if (gflag)
303*621Sbill 		ldargs[ldargx++] = "-lg";
304*621Sbill 	ldargs[ldargx++] = "-lc";
305*621Sbill 	ldargs[ldargx] = 0;
306*621Sbill 	if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0)
307*621Sbill 		unlink(onepso);
308*621Sbill 	done();
309*621Sbill }
310*621Sbill 
311*621Sbill dosys(cmd, argv, in, out)
312*621Sbill 	char *cmd, **argv, *in, *out;
313*621Sbill {
314*621Sbill 	union wait status;
315*621Sbill 	int pid;
316*621Sbill 
317*621Sbill 	if (debug) {
318*621Sbill 		int i;
319*621Sbill 		printf("%s:", cmd);
320*621Sbill 		for (i = 0; argv[i]; i++)
321*621Sbill 			printf(" %s", argv[i]);
322*621Sbill 		if (in)
323*621Sbill 			printf(" <%s", in);
324*621Sbill 		if (out)
325*621Sbill 			printf(" >%s", out);
326*621Sbill 		printf("\n");
327*621Sbill 	}
328*621Sbill 	pid = vfork();
329*621Sbill 	if (pid < 0) {
330*621Sbill 		fprintf(stderr, "pc: No more processes\n");
331*621Sbill 		done();
332*621Sbill 	}
333*621Sbill 	if (pid == 0) {
334*621Sbill 		if (in) {
335*621Sbill 			close(0);
336*621Sbill 			if (open(in, 0) != 0) {
337*621Sbill 				perror(in);
338*621Sbill 				exit(1);
339*621Sbill 			}
340*621Sbill 		}
341*621Sbill 		if (out) {
342*621Sbill 			close(1);
343*621Sbill 			unlink(out);
344*621Sbill 			if (creat(out, 0666) != 1) {
345*621Sbill 				perror(out);
346*621Sbill 				exit(1);
347*621Sbill 			}
348*621Sbill 		}
349*621Sbill 		signal(SIGINT, SIG_DFL);
350*621Sbill 		execv(cmd, argv);
351*621Sbill 		perror(cmd);
352*621Sbill 		exit(1);
353*621Sbill 	}
354*621Sbill 	while (wait(&status) != pid)
355*621Sbill 		;
356*621Sbill 	if (WIFSIGNALED(status)) {
357*621Sbill 		if (status.w_termsig != SIGINT)
358*621Sbill 			fprintf(stderr, "Fatal error in %s\n", cmd);
359*621Sbill 		errs = 100;
360*621Sbill 		done();
361*621Sbill 		/*NOTREACHED*/
362*621Sbill 	}
363*621Sbill 	if (status.w_retcode) {
364*621Sbill 		errs = 1;
365*621Sbill 		remove();
366*621Sbill 	}
367*621Sbill 	return (status.w_retcode);
368*621Sbill }
369*621Sbill 
370*621Sbill done()
371*621Sbill {
372*621Sbill 
373*621Sbill 	remove();
374*621Sbill 	exit(errs);
375*621Sbill }
376*621Sbill 
377*621Sbill remove()
378*621Sbill {
379*621Sbill 
380*621Sbill 	if (tfile[0])
381*621Sbill 		unlink(tfile[0]);
382*621Sbill 	if (tfile[1])
383*621Sbill 		unlink(tfile[1]);
384*621Sbill }
385*621Sbill 
386*621Sbill onintr()
387*621Sbill {
388*621Sbill 
389*621Sbill 	errs = 1;
390*621Sbill 	done();
391*621Sbill }
392*621Sbill 
393*621Sbill getsuf(cp)
394*621Sbill 	char *cp;
395*621Sbill {
396*621Sbill 
397*621Sbill 	if (*cp == 0)
398*621Sbill 		return;
399*621Sbill 	while (cp[1])
400*621Sbill 		cp++;
401*621Sbill 	if (cp[-1] != '.')
402*621Sbill 		return (0);
403*621Sbill 	return (*cp);
404*621Sbill }
405*621Sbill 
406*621Sbill char	sufbuf[BUFSIZ];
407*621Sbill 
408*621Sbill char *
409*621Sbill setsuf(cp, c)
410*621Sbill 	char *cp;
411*621Sbill {
412*621Sbill 	register char *dp;
413*621Sbill 
414*621Sbill 	for (dp = sufbuf; *cp; *dp++ = *cp++)
415*621Sbill 		continue;
416*621Sbill 	*dp = 0;
417*621Sbill 	if (dp-sufbuf > 2 && dp[-2] == '.')
418*621Sbill 		dp[-1] = c;
419*621Sbill 	return (sufbuf);
420*621Sbill }
421*621Sbill 
422*621Sbill #define	NSAVETAB	512
423*621Sbill char	*savetab;
424*621Sbill int	saveleft;
425*621Sbill 
426*621Sbill char *
427*621Sbill savestr(cp)
428*621Sbill 	register char *cp;
429*621Sbill {
430*621Sbill 	register int len;
431*621Sbill 
432*621Sbill 	len = strlen(cp) + 1;
433*621Sbill 	if (len > saveleft) {
434*621Sbill 		saveleft = NSAVETAB;
435*621Sbill 		if (len > saveleft)
436*621Sbill 			saveleft = len;
437*621Sbill 		savetab = (char *)malloc(saveleft);
438*621Sbill 		if (savetab == 0) {
439*621Sbill 			fprintf(stderr, "ran out of memory (savestr)\n");
440*621Sbill 			exit(1);
441*621Sbill 		}
442*621Sbill 	}
443*621Sbill 	strncpy(savetab, cp, len);
444*621Sbill 	cp = savetab;
445*621Sbill 	savetab += len;
446*621Sbill 	return (cp);
447*621Sbill }
448*621Sbill 
449*621Sbill suffix(cp)
450*621Sbill 	char *cp;
451*621Sbill {
452*621Sbill 
453*621Sbill 	if (cp[0] == 0 || cp[1] == 0)
454*621Sbill 		return (0);
455*621Sbill 	while (cp[1])
456*621Sbill 		cp++;
457*621Sbill 	if (cp[-1] == '.')
458*621Sbill 		return (*cp);
459*621Sbill 	return (0);
460*621Sbill }
461