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