xref: /csrg-svn/usr.bin/pascal/pc/pc.c (revision 3862)
1*3862Smckusic static	char sccsid[] = "@(#)pc.c 3.12 06/08/81";
2621Sbill #include <stdio.h>
3621Sbill #include <signal.h>
4621Sbill #include <wait.h>
5621Sbill 
6621Sbill /*
7654Sbill  * Pc - front end for Pascal compiler.
8621Sbill  */
9908Sbill char	*pc0 = "/usr/lib/pc0";
10908Sbill char	*pc1 = "/lib/f1";
11908Sbill char	*pc2 = "/usr/lib/pc2";
12908Sbill char	*c2 = "/lib/c2";
13908Sbill char	*pc3 = "/usr/lib/pc3";
14908Sbill char	*ld = "/bin/ld";
15908Sbill char	*as = "/bin/as";
16621Sbill char	*lpc = "-lpc";
17908Sbill char	*crt0 = "/lib/crt0.o";
18908Sbill char	*mcrt0 = "/lib/mcrt0.o";
19621Sbill 
20621Sbill char	*mktemp();
21621Sbill char	*tname[2];
22621Sbill char	*tfile[2];
23621Sbill 
24621Sbill char	*setsuf(), *savestr();
25621Sbill 
26908Sbill int	Jflag, 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 }; */
40908Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/lib/crt0.o", 0, }; */
41908Sbill int	asargx;
42908Sbill char	*asargs[6] =		{ "as", 0, };
43621Sbill 
44621Sbill /*
45621Sbill  * If the number of .p arguments (np) is 1, and the number of .o arguments
46621Sbill  * (nxo) is 0, and we successfully create an ``a.out'', then we remove
47621Sbill  * the one .ps .o file (onepso).
48621Sbill  */
49621Sbill int	np, nxo;
50621Sbill char	*onepso;
51621Sbill int	errs;
52621Sbill 
53621Sbill int	onintr();
54621Sbill 
55621Sbill main(argc, argv)
56621Sbill 	int argc;
57621Sbill 	char **argv;
58621Sbill {
59621Sbill 	register char *argp;
60621Sbill 	register int i;
61621Sbill 	int savargx;
62621Sbill 	char *t, c;
63621Sbill 	int j;
64621Sbill 
65621Sbill 	argc--, argv++;
66621Sbill 	if (argc == 0) {
67621Sbill 		execl("/bin/cat", "cat", "/usr/lib/how_pc");
68621Sbill 		exit(1);
69621Sbill 	}
70621Sbill 	if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
71621Sbill 		signal(SIGINT, onintr);
72621Sbill 		signal(SIGTERM, onintr);
73621Sbill 	}
74621Sbill 	for (i = 0; i < argc; i++) {
75621Sbill 		argp = argv[i];
76621Sbill 		if (argp[0] != '-')
77621Sbill 			continue;
78621Sbill 		switch (argp[1]) {
79621Sbill 
80621Sbill 		case 'd':
81621Sbill 			if (argp[2] == 0)
82621Sbill 				debug++;
83621Sbill 			continue;
84621Sbill 		case 'i':
85621Sbill 			pc0args[pc0argx++] = "-i";
86621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
87621Sbill 			    getsuf(argv[i+1]) != 'p') {
88621Sbill 				pc0args[pc0argx++] = argv[i+1];
89621Sbill 				i++;
90621Sbill 			}
91621Sbill 			if (i+1 == argc) {
92621Sbill 				fprintf(stderr, "pc: bad -i construction\n");
93621Sbill 				exit(1);
94621Sbill 			}
95621Sbill 			continue;
96621Sbill 		case 'o':
97621Sbill 			i++;
98621Sbill 			if (i == argc) {
99621Sbill 				fprintf(stderr, "pc: -o must specify file\n");
100621Sbill 				exit(1);
101621Sbill 			}
102621Sbill 			c = getsuf(argv[i]);
103621Sbill 			if (c == 'o' || c == 'p' || c == 'c') {
104621Sbill 				fprintf(stderr, "pc: -o would overwrite %s\n",
105621Sbill 				    argv[i]);
106621Sbill 				exit(1);
107621Sbill 			}
108621Sbill 			continue;
109621Sbill 		case 'O':
110621Sbill 			Oflag = 1;
111621Sbill 			continue;
112621Sbill 		case 'S':
113621Sbill 			Sflag = 1;
114621Sbill 			continue;
115908Sbill 		case 'J':
116908Sbill 			Jflag = 1;
117908Sbill 			continue;
118621Sbill 		case 'T':
119621Sbill 			switch (argp[2]) {
120621Sbill 
121621Sbill 			case '0':
122908Sbill 				pc0 = "/usr/src/cmd/pc0/a.out";
123*3862Smckusic 				if (argp[3] != '\0') {
124*3862Smckusic 					pc0 = &argp[3];
125*3862Smckusic 				}
126621Sbill 				continue;
127621Sbill 			case '1':
128908Sbill 				pc1 = "/usr/src/cmd/pcc/pc1";
129*3862Smckusic 				if (argp[3] != '\0') {
130*3862Smckusic 					pc1 = &argp[3];
131*3862Smckusic 				}
132621Sbill 				continue;
133621Sbill 			case '2':
1342194Smckusic 				pc2 = "/usr/src/cmd/pascal/pc2";
135*3862Smckusic 				if (argp[3] != '\0') {
136*3862Smckusic 					pc2 = &argp[3];
137*3862Smckusic 				}
138621Sbill 				continue;
139621Sbill 			case '3':
1402194Smckusic 				pc3 = "/usr/src/cmd/pascal/pc3";
141*3862Smckusic 				if (argp[3] != '\0') {
142*3862Smckusic 					pc3 = &argp[3];
143*3862Smckusic 				}
144621Sbill 				continue;
145621Sbill 			case 'l':
1462127Smckusic 				lpc = "/usr/src/lib/libpc/libpc";
147*3862Smckusic 				if (argp[3] != '\0') {
148*3862Smckusic 					lpc = &argp[3];
149*3862Smckusic 				}
150621Sbill 				continue;
151621Sbill 			}
152621Sbill 			continue;
153621Sbill 		case 'c':
154621Sbill 			cflag = 1;
155621Sbill 			continue;
156621Sbill 		case 'l':
157621Sbill 			if (argp[2])
158621Sbill 				continue;
159621Sbill 			/* fall into ... */
160621Sbill 		case 'b':
161621Sbill 		case 'g':
162621Sbill 		case 's':
163621Sbill 		case 'w':
164621Sbill 		case 'z':
165621Sbill 		case 'C':
166621Sbill 			pc0args[pc0argx++] = argp;
167621Sbill 			if (argp[1] == 'g')
168621Sbill 				gflag = 1;
169621Sbill 			continue;
170621Sbill 		case 't':
171621Sbill 			fprintf(stderr, "pc: -t is default; -C for checking\n");
172621Sbill 			continue;
173621Sbill 		case 'p':
174654Sbill 			crt0 = mcrt0;
175654Sbill 			pflag++;
176654Sbill 			continue;
177621Sbill 		}
178621Sbill 	}
179621Sbill 	if (gflag && Oflag) {
180621Sbill 		fprintf(stderr, "pc: warning: -g overrides -O\n");
181621Sbill 		Oflag = 0;
182621Sbill 	}
183621Sbill 	tname[0] = mktemp("/tmp/p0XXXXXX");
184621Sbill 	tname[1] = mktemp("/tmp/p1XXXXXX");
185621Sbill 	savargx = pc0argx;
186621Sbill 	for (i = 0; i < argc; i++) {
187621Sbill 		argp = argv[i];
188621Sbill 		if (argp[0] == '-')
189621Sbill 			continue;
1901211Speter 		if (suffix(argp) == 's') {
1911211Speter 			asargx = 1;
1921211Speter 			if (Jflag)
1931211Speter 				asargs[asargx++] = "-J";
1941211Speter 			asargs[asargx++] = argp;
1951211Speter 			asargs[asargx++] = "-o";
1961211Speter 			tfile[1] = setsuf(argp, 'o');
1971211Speter 			asargs[asargx++] = tfile[1];
1981211Speter 			asargs[asargx] = 0;
1991211Speter 			if (dosys(as, asargs, 0, 0))
2001211Speter 				continue;
2011211Speter 			tfile[1] = 0;
2021211Speter 			continue;
2031211Speter 		}
204621Sbill 		if (suffix(argp) != 'p')
205621Sbill 			continue;
206621Sbill 		tfile[0] = tname[0];
207621Sbill 		pc0args[2] = tfile[0];
208621Sbill 		pc0argx = savargx;
209654Sbill 		if (pflag)
210654Sbill 			pc0args[pc0argx++] = "-p";
211621Sbill 		pc0args[pc0argx++] = argp;
212621Sbill 		pc0args[pc0argx] = 0;
213621Sbill 		if (dosys(pc0, pc0args, 0, 0))
214621Sbill 			continue;
215621Sbill 		pc1args[1] = tfile[0];
216654Sbill 		tfile[1] = tname[1];
217621Sbill 		if (dosys(pc1, pc1args, 0, tfile[1]))
218621Sbill 			continue;
219621Sbill 		unlink(tfile[0]);
2202340Smckusic 		tfile[0] = tname[0];
2212340Smckusic 		if (Oflag) {
2222340Smckusic 			if (dosys(c2, c2args, tfile[1], tfile[0]))
2232340Smckusic 				continue;
2242340Smckusic 			unlink(tfile[1]);
2252340Smckusic 			tfile[1] = tfile[0];
2262340Smckusic 			tfile[0] = tname[1];
2272340Smckusic 		}
2282340Smckusic 		if (Sflag)
229654Sbill 			tfile[0] = setsuf(argp, 's');
230621Sbill 		if (dosys(pc2, pc2args, tfile[1], tfile[0]))
231621Sbill 			continue;
232621Sbill 		unlink(tfile[1]);
233621Sbill 		tfile[1] = 0;
234654Sbill 		if (Sflag) {
235654Sbill 			tfile[0] = 0;
236621Sbill 			continue;
237654Sbill 		}
238908Sbill 		asargx = 1;
239908Sbill 		if (Jflag)
240908Sbill 			asargs[asargx++] = "-J";
241908Sbill 		asargs[asargx++] = tfile[0];
242908Sbill 		asargs[asargx++] = "-o";
243621Sbill 		tfile[1] = setsuf(argp, 'o');
244908Sbill 		asargs[asargx++] = tfile[1];
245908Sbill 		asargs[asargx] = 0;
246621Sbill 		if (dosys(as, asargs, 0, 0))
247621Sbill 			continue;
248621Sbill 		tfile[1] = 0;
249621Sbill 		remove();
250621Sbill 	}
251621Sbill 	if (errs || cflag || Sflag)
252621Sbill 		done();
253621Sbill /* char	*pc3args[NARGS] =	{ "pc3", 0 }; */
254621Sbill 	pc3args[0] = "pc3";
255621Sbill 	for (i = 0; i < argc; i++) {
256621Sbill 		argp = argv[i];
257621Sbill 		if (!strcmp(argp, "-o"))
258621Sbill 			i++;
259621Sbill 		if (argp[0] == '-')
260621Sbill 			continue;
261621Sbill 		switch (getsuf(argp)) {
262621Sbill 
263621Sbill 		case 'o':
264621Sbill 			pc3args[pc3argx++] = argp;
265621Sbill 			nxo++;
266621Sbill 			continue;
2671211Speter 		case 's':
268621Sbill 		case 'p':
269621Sbill 			onepso = pc3args[pc3argx++] =
270621Sbill 			    savestr(setsuf(argp, 'o'));
271621Sbill 			np++;
272621Sbill 			continue;
273621Sbill 		}
274621Sbill 	}
275621Sbill 	pc3args[pc3argx] = 0;
276621Sbill 	if (dosys(pc3, pc3args, 0, 0))
277621Sbill 		done();
278908Sbill /* char	*ldargs[NARGS] =	{ "ld", "-X", "/lib/crt0.o", 0, }; */
279621Sbill 	ldargs[0] = "ld";
280621Sbill 	ldargs[1] = "-X";
281654Sbill 	ldargs[2] = crt0;
282621Sbill 	for (i = 0; i < argc; i++) {
283621Sbill 		argp = argv[i];
284621Sbill 		if (argp[0] != '-') {
285621Sbill 			switch (getsuf(argp)) {
286621Sbill 
287621Sbill 			case 'p':
2881211Speter 			case 's':
289621Sbill 				ldargs[ldargx] = savestr(setsuf(argp, 'o'));
290621Sbill 				break;
291621Sbill 			default:
292621Sbill 				ldargs[ldargx] = argp;
293621Sbill 				break;
294621Sbill 			}
295621Sbill 			if (getsuf(ldargs[ldargx]) == 'o')
296621Sbill 			for (j = 0; j < ldargx; j++)
297621Sbill 				if (!strcmp(ldargs[j], ldargs[ldargx]))
298621Sbill 					goto duplicate;
299621Sbill 			ldargx++;
300621Sbill duplicate:
301621Sbill 			continue;
302621Sbill 		}
303621Sbill 		switch (argp[1]) {
304621Sbill 
305621Sbill 		case 'i':
306621Sbill 			while (i+1 < argc && argv[i+1][0] != '-' &&
307621Sbill 			    getsuf(argv[i+1]) != 'p')
308621Sbill 				i++;
309621Sbill 			continue;
310621Sbill 		case 'd':
311621Sbill 			if (argp[2] == 0)
312621Sbill 				continue;
313621Sbill 			ldargs[ldargx++] = argp;
314621Sbill 			continue;
315621Sbill 		case 'o':
316621Sbill 			ldargs[ldargx++] = argp;
317621Sbill 			i++;
318621Sbill 			ldargs[ldargx++] = argv[i];
319621Sbill 			continue;
320621Sbill 		case 'l':
321621Sbill 			if (argp[2])
322621Sbill 				ldargs[ldargx++] = argp;
323621Sbill 			continue;
324621Sbill 		case 'c':
325621Sbill 		case 'g':
326621Sbill 		case 'w':
327621Sbill 		case 'p':
328621Sbill 		case 'S':
329908Sbill 		case 'J':
330621Sbill 		case 'T':
331621Sbill 		case 'O':
332621Sbill 		case 'C':
333621Sbill 		case 'b':
334621Sbill 		case 's':
335621Sbill 		case 'z':
336621Sbill 			continue;
337621Sbill 		default:
338621Sbill 			ldargs[ldargx++] = argp;
339621Sbill 			continue;
340621Sbill 		}
341621Sbill 	}
342621Sbill 	ldargs[ldargx++] = lpc;
343621Sbill 	if (gflag)
344621Sbill 		ldargs[ldargx++] = "-lg";
3452128Smckusic 	ldargs[ldargx++] = "-lnm";
346621Sbill 	ldargs[ldargx++] = "-lc";
347621Sbill 	ldargs[ldargx] = 0;
348621Sbill 	if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0)
349621Sbill 		unlink(onepso);
350621Sbill 	done();
351621Sbill }
352621Sbill 
353621Sbill dosys(cmd, argv, in, out)
354621Sbill 	char *cmd, **argv, *in, *out;
355621Sbill {
356621Sbill 	union wait status;
357621Sbill 	int pid;
358621Sbill 
359621Sbill 	if (debug) {
360621Sbill 		int i;
361621Sbill 		printf("%s:", cmd);
362621Sbill 		for (i = 0; argv[i]; i++)
363621Sbill 			printf(" %s", argv[i]);
364621Sbill 		if (in)
365621Sbill 			printf(" <%s", in);
366621Sbill 		if (out)
367621Sbill 			printf(" >%s", out);
368621Sbill 		printf("\n");
369621Sbill 	}
370621Sbill 	pid = vfork();
371621Sbill 	if (pid < 0) {
372621Sbill 		fprintf(stderr, "pc: No more processes\n");
373621Sbill 		done();
374621Sbill 	}
375621Sbill 	if (pid == 0) {
376621Sbill 		if (in) {
377621Sbill 			close(0);
378621Sbill 			if (open(in, 0) != 0) {
379621Sbill 				perror(in);
380621Sbill 				exit(1);
381621Sbill 			}
382621Sbill 		}
383621Sbill 		if (out) {
384621Sbill 			close(1);
385621Sbill 			unlink(out);
386621Sbill 			if (creat(out, 0666) != 1) {
387621Sbill 				perror(out);
388621Sbill 				exit(1);
389621Sbill 			}
390621Sbill 		}
391621Sbill 		signal(SIGINT, SIG_DFL);
392621Sbill 		execv(cmd, argv);
393621Sbill 		perror(cmd);
394621Sbill 		exit(1);
395621Sbill 	}
396621Sbill 	while (wait(&status) != pid)
397621Sbill 		;
398621Sbill 	if (WIFSIGNALED(status)) {
399621Sbill 		if (status.w_termsig != SIGINT)
400621Sbill 			fprintf(stderr, "Fatal error in %s\n", cmd);
401621Sbill 		errs = 100;
402621Sbill 		done();
403621Sbill 		/*NOTREACHED*/
404621Sbill 	}
405621Sbill 	if (status.w_retcode) {
406621Sbill 		errs = 1;
407621Sbill 		remove();
408621Sbill 	}
409621Sbill 	return (status.w_retcode);
410621Sbill }
411621Sbill 
412621Sbill done()
413621Sbill {
414621Sbill 
415621Sbill 	remove();
416621Sbill 	exit(errs);
417621Sbill }
418621Sbill 
419621Sbill remove()
420621Sbill {
421621Sbill 
422621Sbill 	if (tfile[0])
423621Sbill 		unlink(tfile[0]);
424621Sbill 	if (tfile[1])
425621Sbill 		unlink(tfile[1]);
426621Sbill }
427621Sbill 
428621Sbill onintr()
429621Sbill {
430621Sbill 
431621Sbill 	errs = 1;
432621Sbill 	done();
433621Sbill }
434621Sbill 
435621Sbill getsuf(cp)
436621Sbill 	char *cp;
437621Sbill {
438621Sbill 
439621Sbill 	if (*cp == 0)
440621Sbill 		return;
441621Sbill 	while (cp[1])
442621Sbill 		cp++;
443621Sbill 	if (cp[-1] != '.')
444621Sbill 		return (0);
445621Sbill 	return (*cp);
446621Sbill }
447621Sbill 
448621Sbill char *
449654Sbill setsuf(as, ch)
450654Sbill 	char *as;
451621Sbill {
452654Sbill 	register char *s, *s1;
453621Sbill 
454654Sbill 	s = s1 = savestr(as);
455654Sbill 	while (*s)
456654Sbill 		if (*s++ == '/')
457654Sbill 			s1 = s;
458654Sbill 	s[-1] = ch;
459654Sbill 	return (s1);
460621Sbill }
461621Sbill 
462621Sbill #define	NSAVETAB	512
463621Sbill char	*savetab;
464621Sbill int	saveleft;
465621Sbill 
466621Sbill char *
467621Sbill savestr(cp)
468621Sbill 	register char *cp;
469621Sbill {
470621Sbill 	register int len;
471621Sbill 
472621Sbill 	len = strlen(cp) + 1;
473621Sbill 	if (len > saveleft) {
474621Sbill 		saveleft = NSAVETAB;
475621Sbill 		if (len > saveleft)
476621Sbill 			saveleft = len;
477621Sbill 		savetab = (char *)malloc(saveleft);
478621Sbill 		if (savetab == 0) {
479621Sbill 			fprintf(stderr, "ran out of memory (savestr)\n");
480621Sbill 			exit(1);
481621Sbill 		}
482621Sbill 	}
483621Sbill 	strncpy(savetab, cp, len);
484621Sbill 	cp = savetab;
485621Sbill 	savetab += len;
486621Sbill 	return (cp);
487621Sbill }
488621Sbill 
489621Sbill suffix(cp)
490621Sbill 	char *cp;
491621Sbill {
492621Sbill 
493621Sbill 	if (cp[0] == 0 || cp[1] == 0)
494621Sbill 		return (0);
495621Sbill 	while (cp[1])
496621Sbill 		cp++;
497621Sbill 	if (cp[-1] == '.')
498621Sbill 		return (*cp);
499621Sbill 	return (0);
500621Sbill }
501