xref: /csrg-svn/usr.bin/pascal/pc/pc.c (revision 654)
1*654Sbill static	char sccsid[] = "@(#)pc.c 3.2 08/17/80";
2621Sbill #include <stdio.h>
3621Sbill #include <signal.h>
4621Sbill #include <wait.h>
5621Sbill 
6621Sbill /*
7*654Sbill  * Pc - front end for Pascal compiler.
8621Sbill  */
9621Sbill char	*pc0 = "/usr/new/pc0";
10621Sbill char	*pc1 = "/usr/new/pc1";
11621Sbill char	*pc2 = "/usr/new/pc2";
12621Sbill char	*c2 = "/usr/new/c2";
13621Sbill char	*pc3 = "/usr/new/pc3";
14621Sbill char	*ld = "/usr/new/ld";
15621Sbill char	*as = "/usr/new/as";
16621Sbill char	*lpc = "-lpc";
17*654Sbill char	*crt0 = "/usr/new/crt0.o";
18*654Sbill char	*mcrt0 = "/usr/new/mcrt0.o";
19621Sbill 
20621Sbill char	*mktemp();
21621Sbill char	*tname[2];
22621Sbill char	*tfile[2];
23621Sbill 
24621Sbill char	*setsuf(), *savestr();
25621Sbill 
26*654Sbill int	Sflag, Oflag, cflag, gflag, pflag;
27621Sbill int	debug;
28621Sbill 
29621Sbill #define	NARGS	512
30621Sbill int	ldargx = 3;
31621Sbill int	pc0argx = 3;
32621Sbill char	*pc0args[NARGS] =	{ "pc0", "-o", "XXX" };
33621Sbill char	*pc1args[3] =		{ "pc1", 0, };
34621Sbill char	*pc2args[2] =		{ "pc2", 0 };
35621Sbill char	*c2args[4] =		{ "c2", 0, 0, 0 };
36621Sbill int	pc3argx = 1;
37621Sbill #define	pc3args	pc0args
38621Sbill #define	ldargs	pc0args
39621Sbill /* char	*pc3args[NARGS] =	{ "pc3", 0 }; */
40621Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/usr/new/crt0.o", 0, }; */
41621Sbill char	*asargs[5] =		{ "as", 0, };
42621Sbill 
43621Sbill /*
44621Sbill  * If the number of .p arguments (np) is 1, and the number of .o arguments
45621Sbill  * (nxo) is 0, and we successfully create an ``a.out'', then we remove
46621Sbill  * the one .ps .o file (onepso).
47621Sbill  */
48621Sbill int	np, nxo;
49621Sbill char	*onepso;
50621Sbill int	errs;
51621Sbill 
52621Sbill int	onintr();
53621Sbill 
54621Sbill main(argc, argv)
55621Sbill 	int argc;
56621Sbill 	char **argv;
57621Sbill {
58621Sbill 	register char *argp;
59621Sbill 	register int i;
60621Sbill 	int savargx;
61621Sbill 	char *t, c;
62621Sbill 	int j;
63621Sbill 
64621Sbill 	argc--, argv++;
65621Sbill 	if (argc == 0) {
66621Sbill 		execl("/bin/cat", "cat", "/usr/lib/how_pc");
67621Sbill 		exit(1);
68621Sbill 	}
69621Sbill 	if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
70621Sbill 		signal(SIGINT, onintr);
71621Sbill 		signal(SIGTERM, onintr);
72621Sbill 	}
73621Sbill 	for (i = 0; i < argc; i++) {
74621Sbill 		argp = argv[i];
75621Sbill 		if (argp[0] != '-')
76621Sbill 			continue;
77621Sbill 		switch (argp[1]) {
78621Sbill 
79621Sbill 		case 'd':
80621Sbill 			if (argp[2] == 0)
81621Sbill 				debug++;
82621Sbill 			continue;
83621Sbill 		case 'i':
84621Sbill 			pc0args[pc0argx++] = "-i";
85621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
86621Sbill 			    getsuf(argv[i+1]) != 'p') {
87621Sbill 				pc0args[pc0argx++] = argv[i+1];
88621Sbill 				i++;
89621Sbill 			}
90621Sbill 			if (i+1 == argc) {
91621Sbill 				fprintf(stderr, "pc: bad -i construction\n");
92621Sbill 				exit(1);
93621Sbill 			}
94621Sbill 			continue;
95621Sbill 		case 'o':
96621Sbill 			i++;
97621Sbill 			if (i == argc) {
98621Sbill 				fprintf(stderr, "pc: -o must specify file\n");
99621Sbill 				exit(1);
100621Sbill 			}
101621Sbill 			c = getsuf(argv[i]);
102621Sbill 			if (c == 'o' || c == 'p' || c == 'c') {
103621Sbill 				fprintf(stderr, "pc: -o would overwrite %s\n",
104621Sbill 				    argv[i]);
105621Sbill 				exit(1);
106621Sbill 			}
107621Sbill 			continue;
108621Sbill 		case 'O':
109621Sbill 			Oflag = 1;
110621Sbill 			continue;
111621Sbill 		case 'S':
112621Sbill 			Sflag = 1;
113621Sbill 			continue;
114621Sbill 		case 'T':
115621Sbill 			switch (argp[2]) {
116621Sbill 
117621Sbill 			case '0':
118621Sbill 				pc0 = "/vb/grad/peter/pc/npc0/src/a.pc";
119621Sbill 				continue;
120621Sbill 			case '1':
121621Sbill 				pc1 = "/usr/src/new/pcc/pc1";
122621Sbill 				continue;
123621Sbill 			case '2':
124621Sbill 				pc2 = "/usr/new/pc2";
125621Sbill 				continue;
126621Sbill 			case '3':
127621Sbill 				pc3 = "/usr/new/pc3";
128621Sbill 				continue;
129621Sbill 			case 'l':
130621Sbill 				lpc = "-lnpc";
131621Sbill 				continue;
132621Sbill 			}
133621Sbill 			continue;
134621Sbill 		case 'c':
135621Sbill 			cflag = 1;
136621Sbill 			continue;
137621Sbill 		case 'l':
138621Sbill 			if (argp[2])
139621Sbill 				continue;
140621Sbill 			/* fall into ... */
141621Sbill 		case 'b':
142621Sbill 		case 'g':
143621Sbill 		case 's':
144621Sbill 		case 'w':
145621Sbill 		case 'z':
146621Sbill 		case 'C':
147621Sbill 			pc0args[pc0argx++] = argp;
148621Sbill 			if (argp[1] == 'g')
149621Sbill 				gflag = 1;
150621Sbill 			continue;
151621Sbill 		case 't':
152621Sbill 			fprintf(stderr, "pc: -t is default; -C for checking\n");
153621Sbill 			continue;
154621Sbill 		case 'p':
155*654Sbill 			crt0 = mcrt0;
156*654Sbill 			pflag++;
157*654Sbill 			continue;
158621Sbill 		}
159621Sbill 	}
160621Sbill 	if (gflag && Oflag) {
161621Sbill 		fprintf(stderr, "pc: warning: -g overrides -O\n");
162621Sbill 		Oflag = 0;
163621Sbill 	}
164621Sbill 	tname[0] = mktemp("/tmp/p0XXXXXX");
165621Sbill 	tname[1] = mktemp("/tmp/p1XXXXXX");
166621Sbill 	savargx = pc0argx;
167621Sbill 	for (i = 0; i < argc; i++) {
168621Sbill 		argp = argv[i];
169621Sbill 		if (argp[0] == '-')
170621Sbill 			continue;
171621Sbill 		if (suffix(argp) != 'p')
172621Sbill 			continue;
173621Sbill 		tfile[0] = tname[0];
174621Sbill 		pc0args[2] = tfile[0];
175621Sbill 		pc0argx = savargx;
176*654Sbill 		if (pflag)
177*654Sbill 			pc0args[pc0argx++] = "-p";
178621Sbill 		pc0args[pc0argx++] = argp;
179621Sbill 		pc0args[pc0argx] = 0;
180621Sbill 		if (dosys(pc0, pc0args, 0, 0))
181621Sbill 			continue;
182621Sbill 		pc1args[1] = tfile[0];
183*654Sbill 		tfile[1] = tname[1];
184621Sbill 		if (dosys(pc1, pc1args, 0, tfile[1]))
185621Sbill 			continue;
186621Sbill 		unlink(tfile[0]);
187*654Sbill 		if (Sflag && !Oflag)
188*654Sbill 			tfile[0] = setsuf(argp, 's');
189*654Sbill 		else
190*654Sbill 			tfile[0] = tname[0];
191621Sbill 		if (dosys(pc2, pc2args, tfile[1], tfile[0]))
192621Sbill 			continue;
193621Sbill 		unlink(tfile[1]);
194621Sbill 		tfile[1] = 0;
195621Sbill 		if (Oflag) {
196621Sbill 			if (Sflag)
197621Sbill 				tfile[1] = setsuf(argp, 's');
198621Sbill 			else
199*654Sbill 				tfile[1] = tname[1];
200621Sbill 			if (dosys(c2, c2args, tfile[0], tfile[1]))
201621Sbill 				continue;
202621Sbill 			unlink(tfile[0]);
203621Sbill 			tfile[0] = tfile[1];
204621Sbill 			tfile[1] = 0;
205621Sbill 		}
206*654Sbill 		if (Sflag) {
207*654Sbill 			tfile[0] = 0;
208621Sbill 			continue;
209*654Sbill 		}
210621Sbill 		asargs[1] = tfile[0];
211621Sbill 		asargs[2] = "-o";
212621Sbill 		tfile[1] = setsuf(argp, 'o');
213621Sbill 		asargs[3] = tfile[1];
214621Sbill 		if (dosys(as, asargs, 0, 0))
215621Sbill 			continue;
216621Sbill 		tfile[1] = 0;
217621Sbill 		remove();
218621Sbill 	}
219621Sbill 	if (errs || cflag || Sflag)
220621Sbill 		done();
221621Sbill /* char	*pc3args[NARGS] =	{ "pc3", 0 }; */
222621Sbill 	pc3args[0] = "pc3";
223621Sbill 	for (i = 0; i < argc; i++) {
224621Sbill 		argp = argv[i];
225621Sbill 		if (!strcmp(argp, "-o"))
226621Sbill 			i++;
227621Sbill 		if (argp[0] == '-')
228621Sbill 			continue;
229621Sbill 		switch (getsuf(argp)) {
230621Sbill 
231621Sbill 		case 'd':
232621Sbill 			continue;
233621Sbill 		case 'o':
234621Sbill 			pc3args[pc3argx++] = argp;
235621Sbill 			nxo++;
236621Sbill 			continue;
237621Sbill 		case 'p':
238621Sbill 			onepso = pc3args[pc3argx++] =
239621Sbill 			    savestr(setsuf(argp, 'o'));
240621Sbill 			np++;
241621Sbill 			continue;
242621Sbill 		}
243621Sbill 	}
244621Sbill 	pc3args[pc3argx] = 0;
245621Sbill 	if (dosys(pc3, pc3args, 0, 0))
246621Sbill 		done();
247621Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/usr/new/crt0.o", 0, }; */
248621Sbill 	ldargs[0] = "ld";
249621Sbill 	ldargs[1] = "-X";
250*654Sbill 	ldargs[2] = crt0;
251621Sbill 	for (i = 0; i < argc; i++) {
252621Sbill 		argp = argv[i];
253621Sbill 		if (argp[0] != '-') {
254621Sbill 			switch (getsuf(argp)) {
255621Sbill 
256621Sbill 			case 'p':
257621Sbill 				ldargs[ldargx] = savestr(setsuf(argp, 'o'));
258621Sbill 				break;
259621Sbill 			default:
260621Sbill 				ldargs[ldargx] = argp;
261621Sbill 				break;
262621Sbill 			}
263621Sbill 			if (getsuf(ldargs[ldargx]) == 'o')
264621Sbill 			for (j = 0; j < ldargx; j++)
265621Sbill 				if (!strcmp(ldargs[j], ldargs[ldargx]))
266621Sbill 					goto duplicate;
267621Sbill 			ldargx++;
268621Sbill duplicate:
269621Sbill 			continue;
270621Sbill 		}
271621Sbill 		switch (argp[1]) {
272621Sbill 
273621Sbill 		case 'i':
274621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
275621Sbill 			    getsuf(argv[i+1]) != 'p')
276621Sbill 				i++;
277621Sbill 			continue;
278621Sbill 		case 'd':
279621Sbill 			if (argp[2] == 0)
280621Sbill 				continue;
281621Sbill 			ldargs[ldargx++] = argp;
282621Sbill 			continue;
283621Sbill 		case 'o':
284621Sbill 			ldargs[ldargx++] = argp;
285621Sbill 			i++;
286621Sbill 			ldargs[ldargx++] = argv[i];
287621Sbill 			continue;
288621Sbill 		case 'l':
289621Sbill 			if (argp[2])
290621Sbill 				ldargs[ldargx++] = argp;
291621Sbill 			continue;
292621Sbill 		case 'c':
293621Sbill 		case 'g':
294621Sbill 		case 'w':
295621Sbill 		case 'p':
296621Sbill 		case 'S':
297621Sbill 		case 'T':
298621Sbill 		case 'O':
299621Sbill 		case 'C':
300621Sbill 		case 'b':
301621Sbill 		case 's':
302621Sbill 		case 'z':
303621Sbill 			continue;
304621Sbill 		default:
305621Sbill 			ldargs[ldargx++] = argp;
306621Sbill 			continue;
307621Sbill 		}
308621Sbill 	}
309621Sbill 	ldargs[ldargx++] = lpc;
310621Sbill 	if (gflag)
311621Sbill 		ldargs[ldargx++] = "-lg";
312621Sbill 	ldargs[ldargx++] = "-lc";
313621Sbill 	ldargs[ldargx] = 0;
314621Sbill 	if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0)
315621Sbill 		unlink(onepso);
316621Sbill 	done();
317621Sbill }
318621Sbill 
319621Sbill dosys(cmd, argv, in, out)
320621Sbill 	char *cmd, **argv, *in, *out;
321621Sbill {
322621Sbill 	union wait status;
323621Sbill 	int pid;
324621Sbill 
325621Sbill 	if (debug) {
326621Sbill 		int i;
327621Sbill 		printf("%s:", cmd);
328621Sbill 		for (i = 0; argv[i]; i++)
329621Sbill 			printf(" %s", argv[i]);
330621Sbill 		if (in)
331621Sbill 			printf(" <%s", in);
332621Sbill 		if (out)
333621Sbill 			printf(" >%s", out);
334621Sbill 		printf("\n");
335621Sbill 	}
336621Sbill 	pid = vfork();
337621Sbill 	if (pid < 0) {
338621Sbill 		fprintf(stderr, "pc: No more processes\n");
339621Sbill 		done();
340621Sbill 	}
341621Sbill 	if (pid == 0) {
342621Sbill 		if (in) {
343621Sbill 			close(0);
344621Sbill 			if (open(in, 0) != 0) {
345621Sbill 				perror(in);
346621Sbill 				exit(1);
347621Sbill 			}
348621Sbill 		}
349621Sbill 		if (out) {
350621Sbill 			close(1);
351621Sbill 			unlink(out);
352621Sbill 			if (creat(out, 0666) != 1) {
353621Sbill 				perror(out);
354621Sbill 				exit(1);
355621Sbill 			}
356621Sbill 		}
357621Sbill 		signal(SIGINT, SIG_DFL);
358621Sbill 		execv(cmd, argv);
359621Sbill 		perror(cmd);
360621Sbill 		exit(1);
361621Sbill 	}
362621Sbill 	while (wait(&status) != pid)
363621Sbill 		;
364621Sbill 	if (WIFSIGNALED(status)) {
365621Sbill 		if (status.w_termsig != SIGINT)
366621Sbill 			fprintf(stderr, "Fatal error in %s\n", cmd);
367621Sbill 		errs = 100;
368621Sbill 		done();
369621Sbill 		/*NOTREACHED*/
370621Sbill 	}
371621Sbill 	if (status.w_retcode) {
372621Sbill 		errs = 1;
373621Sbill 		remove();
374621Sbill 	}
375621Sbill 	return (status.w_retcode);
376621Sbill }
377621Sbill 
378621Sbill done()
379621Sbill {
380621Sbill 
381621Sbill 	remove();
382621Sbill 	exit(errs);
383621Sbill }
384621Sbill 
385621Sbill remove()
386621Sbill {
387621Sbill 
388621Sbill 	if (tfile[0])
389621Sbill 		unlink(tfile[0]);
390621Sbill 	if (tfile[1])
391621Sbill 		unlink(tfile[1]);
392621Sbill }
393621Sbill 
394621Sbill onintr()
395621Sbill {
396621Sbill 
397621Sbill 	errs = 1;
398621Sbill 	done();
399621Sbill }
400621Sbill 
401621Sbill getsuf(cp)
402621Sbill 	char *cp;
403621Sbill {
404621Sbill 
405621Sbill 	if (*cp == 0)
406621Sbill 		return;
407621Sbill 	while (cp[1])
408621Sbill 		cp++;
409621Sbill 	if (cp[-1] != '.')
410621Sbill 		return (0);
411621Sbill 	return (*cp);
412621Sbill }
413621Sbill 
414621Sbill char *
415*654Sbill setsuf(as, ch)
416*654Sbill 	char *as;
417621Sbill {
418*654Sbill 	register char *s, *s1;
419621Sbill 
420*654Sbill 	s = s1 = savestr(as);
421*654Sbill 	while (*s)
422*654Sbill 		if (*s++ == '/')
423*654Sbill 			s1 = s;
424*654Sbill 	s[-1] = ch;
425*654Sbill 	return (s1);
426621Sbill }
427621Sbill 
428621Sbill #define	NSAVETAB	512
429621Sbill char	*savetab;
430621Sbill int	saveleft;
431621Sbill 
432621Sbill char *
433621Sbill savestr(cp)
434621Sbill 	register char *cp;
435621Sbill {
436621Sbill 	register int len;
437621Sbill 
438621Sbill 	len = strlen(cp) + 1;
439621Sbill 	if (len > saveleft) {
440621Sbill 		saveleft = NSAVETAB;
441621Sbill 		if (len > saveleft)
442621Sbill 			saveleft = len;
443621Sbill 		savetab = (char *)malloc(saveleft);
444621Sbill 		if (savetab == 0) {
445621Sbill 			fprintf(stderr, "ran out of memory (savestr)\n");
446621Sbill 			exit(1);
447621Sbill 		}
448621Sbill 	}
449621Sbill 	strncpy(savetab, cp, len);
450621Sbill 	cp = savetab;
451621Sbill 	savetab += len;
452621Sbill 	return (cp);
453621Sbill }
454621Sbill 
455621Sbill suffix(cp)
456621Sbill 	char *cp;
457621Sbill {
458621Sbill 
459621Sbill 	if (cp[0] == 0 || cp[1] == 0)
460621Sbill 		return (0);
461621Sbill 	while (cp[1])
462621Sbill 		cp++;
463621Sbill 	if (cp[-1] == '.')
464621Sbill 		return (*cp);
465621Sbill 	return (0);
466621Sbill }
467