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