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