xref: /original-bsd/usr.bin/pascal/pc/pc.c (revision 5fb3de76)
1 static	char sccsid[] = "@(#)pc.c 3.11 02/04/81";
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/pascal/pc2";
129 				continue;
130 			case '3':
131 				pc3 = "/usr/src/cmd/pascal/pc3";
132 				continue;
133 			case 'l':
134 				lpc = "/usr/src/lib/libpc/libpc";
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 		tfile[0] = tname[0];
206 		if (Oflag) {
207 			if (dosys(c2, c2args, tfile[1], tfile[0]))
208 				continue;
209 			unlink(tfile[1]);
210 			tfile[1] = tfile[0];
211 			tfile[0] = tname[1];
212 		}
213 		if (Sflag)
214 			tfile[0] = setsuf(argp, 's');
215 		if (dosys(pc2, pc2args, tfile[1], tfile[0]))
216 			continue;
217 		unlink(tfile[1]);
218 		tfile[1] = 0;
219 		if (Sflag) {
220 			tfile[0] = 0;
221 			continue;
222 		}
223 		asargx = 1;
224 		if (Jflag)
225 			asargs[asargx++] = "-J";
226 		asargs[asargx++] = tfile[0];
227 		asargs[asargx++] = "-o";
228 		tfile[1] = setsuf(argp, 'o');
229 		asargs[asargx++] = tfile[1];
230 		asargs[asargx] = 0;
231 		if (dosys(as, asargs, 0, 0))
232 			continue;
233 		tfile[1] = 0;
234 		remove();
235 	}
236 	if (errs || cflag || Sflag)
237 		done();
238 /* char	*pc3args[NARGS] =	{ "pc3", 0 }; */
239 	pc3args[0] = "pc3";
240 	for (i = 0; i < argc; i++) {
241 		argp = argv[i];
242 		if (!strcmp(argp, "-o"))
243 			i++;
244 		if (argp[0] == '-')
245 			continue;
246 		switch (getsuf(argp)) {
247 
248 		case 'o':
249 			pc3args[pc3argx++] = argp;
250 			nxo++;
251 			continue;
252 		case 's':
253 		case 'p':
254 			onepso = pc3args[pc3argx++] =
255 			    savestr(setsuf(argp, 'o'));
256 			np++;
257 			continue;
258 		}
259 	}
260 	pc3args[pc3argx] = 0;
261 	if (dosys(pc3, pc3args, 0, 0))
262 		done();
263 /* char	*ldargs[NARGS] =	{ "ld", "-X", "/lib/crt0.o", 0, }; */
264 	ldargs[0] = "ld";
265 	ldargs[1] = "-X";
266 	ldargs[2] = crt0;
267 	for (i = 0; i < argc; i++) {
268 		argp = argv[i];
269 		if (argp[0] != '-') {
270 			switch (getsuf(argp)) {
271 
272 			case 'p':
273 			case 's':
274 				ldargs[ldargx] = savestr(setsuf(argp, 'o'));
275 				break;
276 			default:
277 				ldargs[ldargx] = argp;
278 				break;
279 			}
280 			if (getsuf(ldargs[ldargx]) == 'o')
281 			for (j = 0; j < ldargx; j++)
282 				if (!strcmp(ldargs[j], ldargs[ldargx]))
283 					goto duplicate;
284 			ldargx++;
285 duplicate:
286 			continue;
287 		}
288 		switch (argp[1]) {
289 
290 		case 'i':
291 			while (i+1 < argc && argv[i+1][0] != '-' &&
292 			    getsuf(argv[i+1]) != 'p')
293 				i++;
294 			continue;
295 		case 'd':
296 			if (argp[2] == 0)
297 				continue;
298 			ldargs[ldargx++] = argp;
299 			continue;
300 		case 'o':
301 			ldargs[ldargx++] = argp;
302 			i++;
303 			ldargs[ldargx++] = argv[i];
304 			continue;
305 		case 'l':
306 			if (argp[2])
307 				ldargs[ldargx++] = argp;
308 			continue;
309 		case 'c':
310 		case 'g':
311 		case 'w':
312 		case 'p':
313 		case 'S':
314 		case 'J':
315 		case 'T':
316 		case 'O':
317 		case 'C':
318 		case 'b':
319 		case 's':
320 		case 'z':
321 			continue;
322 		default:
323 			ldargs[ldargx++] = argp;
324 			continue;
325 		}
326 	}
327 	ldargs[ldargx++] = lpc;
328 	if (gflag)
329 		ldargs[ldargx++] = "-lg";
330 	ldargs[ldargx++] = "-lnm";
331 	ldargs[ldargx++] = "-lc";
332 	ldargs[ldargx] = 0;
333 	if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0)
334 		unlink(onepso);
335 	done();
336 }
337 
338 dosys(cmd, argv, in, out)
339 	char *cmd, **argv, *in, *out;
340 {
341 	union wait status;
342 	int pid;
343 
344 	if (debug) {
345 		int i;
346 		printf("%s:", cmd);
347 		for (i = 0; argv[i]; i++)
348 			printf(" %s", argv[i]);
349 		if (in)
350 			printf(" <%s", in);
351 		if (out)
352 			printf(" >%s", out);
353 		printf("\n");
354 	}
355 	pid = vfork();
356 	if (pid < 0) {
357 		fprintf(stderr, "pc: No more processes\n");
358 		done();
359 	}
360 	if (pid == 0) {
361 		if (in) {
362 			close(0);
363 			if (open(in, 0) != 0) {
364 				perror(in);
365 				exit(1);
366 			}
367 		}
368 		if (out) {
369 			close(1);
370 			unlink(out);
371 			if (creat(out, 0666) != 1) {
372 				perror(out);
373 				exit(1);
374 			}
375 		}
376 		signal(SIGINT, SIG_DFL);
377 		execv(cmd, argv);
378 		perror(cmd);
379 		exit(1);
380 	}
381 	while (wait(&status) != pid)
382 		;
383 	if (WIFSIGNALED(status)) {
384 		if (status.w_termsig != SIGINT)
385 			fprintf(stderr, "Fatal error in %s\n", cmd);
386 		errs = 100;
387 		done();
388 		/*NOTREACHED*/
389 	}
390 	if (status.w_retcode) {
391 		errs = 1;
392 		remove();
393 	}
394 	return (status.w_retcode);
395 }
396 
397 done()
398 {
399 
400 	remove();
401 	exit(errs);
402 }
403 
404 remove()
405 {
406 
407 	if (tfile[0])
408 		unlink(tfile[0]);
409 	if (tfile[1])
410 		unlink(tfile[1]);
411 }
412 
413 onintr()
414 {
415 
416 	errs = 1;
417 	done();
418 }
419 
420 getsuf(cp)
421 	char *cp;
422 {
423 
424 	if (*cp == 0)
425 		return;
426 	while (cp[1])
427 		cp++;
428 	if (cp[-1] != '.')
429 		return (0);
430 	return (*cp);
431 }
432 
433 char *
434 setsuf(as, ch)
435 	char *as;
436 {
437 	register char *s, *s1;
438 
439 	s = s1 = savestr(as);
440 	while (*s)
441 		if (*s++ == '/')
442 			s1 = s;
443 	s[-1] = ch;
444 	return (s1);
445 }
446 
447 #define	NSAVETAB	512
448 char	*savetab;
449 int	saveleft;
450 
451 char *
452 savestr(cp)
453 	register char *cp;
454 {
455 	register int len;
456 
457 	len = strlen(cp) + 1;
458 	if (len > saveleft) {
459 		saveleft = NSAVETAB;
460 		if (len > saveleft)
461 			saveleft = len;
462 		savetab = (char *)malloc(saveleft);
463 		if (savetab == 0) {
464 			fprintf(stderr, "ran out of memory (savestr)\n");
465 			exit(1);
466 		}
467 	}
468 	strncpy(savetab, cp, len);
469 	cp = savetab;
470 	savetab += len;
471 	return (cp);
472 }
473 
474 suffix(cp)
475 	char *cp;
476 {
477 
478 	if (cp[0] == 0 || cp[1] == 0)
479 		return (0);
480 	while (cp[1])
481 		cp++;
482 	if (cp[-1] == '.')
483 		return (*cp);
484 	return (0);
485 }
486