|
|
1.1 root 1: /*-
2: * Copyright (c) 1990 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)pc.c 5.5 (Berkeley) 6/29/90";
28: #endif /* not lint */
29:
30: #include <sys/param.h>
31: #include <sys/signal.h>
32: #include <sys/wait.h>
33: #include <stdio.h>
34: #include "pathnames.h"
35:
36: /*
37: * Pc - front end for Pascal compiler.
38: */
39: char *pc0 = _PATH_PC0;
40: char *pc1 = _PATH_PC1;
41: char *pc2 = _PATH_PC2;
42: char *c2 = _PATH_C2;
43: char *pc3 = _PATH_PC3;
44: char *ld = _PATH_LD;
45: char *as = _PATH_AS;
46: char *lpc = "-lpc";
47: char *crt0 = _PATH_CRT0;
48: char *mcrt0 = _PATH_MCRT0;
49: char *gcrt0 = _PATH_GCRT0;
50:
51: char *mktemp();
52: char *tmpdir = _PATH_TMP;
53: char tmp0[MAXPATHLEN], tmp1[MAXPATHLEN];
54: char *tname[2];
55: char *tfile[2];
56:
57: char *setsuf(), *savestr();
58:
59: int Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag, wflag, tflag;
60: int debug;
61:
62: #define NARGS 512
63: int ldargx = 3;
64: int pc0argx = 3;
65: char *pc0args[NARGS] = { "pc0", "-o", "XXX" };
66: char *pc1args[3] = { "pc1", 0, };
67: char *pc2args[2] = { "pc2", 0 };
68: char *c2args[4] = { "c2", 0, 0, 0 };
69: int pc3argx = 1;
70: #define pc3args pc0args
71: #define ldargs pc0args
72: /* char *pc3args[NARGS] = { "pc3", 0 }; */
73: /* char *ldargs[NARGS] = { "ld", "-X", _PATH_CRT0, 0, }; */
74:
75: /* as -J -t tmpdir -o objfile srcfile \0 */
76: int asargx;
77: char *asargs[8] = { "as", 0, };
78:
79: char *mesg[] = {
80: 0,
81: "Hangup",
82: "Interrupt",
83: "Quit",
84: "Illegal instruction",
85: "Trace/BPT trap",
86: "IOT trap",
87: "EMT trap",
88: "Floating exception",
89: "Killed",
90: "Bus error",
91: "Segmentation fault",
92: "Bad system call",
93: "Broken pipe",
94: "Alarm clock",
95: "Terminated",
96: "Signal 16",
97: "Stopped (signal)",
98: "Stopped",
99: "Continued",
100: "Child exited",
101: "Stopped (tty input)",
102: "Stopped (tty output)",
103: "Tty input interrupt",
104: "Cputime limit exceeded",
105: "Filesize limit exceeded",
106: "Signal 26",
107: "Signal 27",
108: "Signal 28",
109: "Signal 29",
110: "Signal 30",
111: "Signal 31",
112: "Signal 32"
113: };
114:
115: /*
116: * If the number of .p arguments (np) is 1, and the number of .o arguments
117: * (nxo) is 0, and we successfully create an ``a.out'', then we remove
118: * the one .ps .o file (onepso).
119: */
120: int np, nxo;
121: char *onepso;
122: int errs;
123:
124: int onintr();
125:
126: main(argc, argv)
127: int argc;
128: char **argv;
129: {
130: register char *argp;
131: register int i;
132: int savargx;
133: char *t, c;
134: int j;
135:
136: argc--, argv++;
137: if (argc == 0) {
138: execl(_PATH_CAT, "cat", _PATH_HOWPC);
139: exit(1);
140: }
141: if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
142: signal(SIGINT, onintr);
143: signal(SIGTERM, onintr);
144: }
145: for (i = 0; i < argc; i++) {
146: argp = argv[i];
147: if (argp[0] != '-')
148: continue;
149: switch (argp[1]) {
150:
151: case 'd':
152: if (argp[2] == 0)
153: debug++;
154: continue;
155: case 'i':
156: pc0args[pc0argx++] = "-i";
157: while (i+1 < argc && argv[i+1][0] != '-' &&
158: getsuf(argv[i+1]) != 'p') {
159: pc0args[pc0argx++] = argv[i+1];
160: i++;
161: }
162: if (i+1 == argc) {
163: fprintf(stderr, "pc: bad -i construction\n");
164: exit(1);
165: }
166: continue;
167: case 'o':
168: i++;
169: if (i == argc) {
170: fprintf(stderr, "pc: -o must specify file\n");
171: exit(1);
172: }
173: c = getsuf(argv[i]);
174: if (c == 'o' || c == 'p' || c == 'c') {
175: fprintf(stderr, "pc: -o would overwrite %s\n",
176: argv[i]);
177: exit(1);
178: }
179: continue;
180: case 't':
181: i++;
182: if (i == argc) {
183: fprintf(stderr, "pc: -t but no directory\n");
184: exit(1);
185: }
186: if (argp[2] != '\0') {
187: fprintf(stderr, "pc: bad -t option\n");
188: exit(1);
189: }
190: tmpdir = argv[i];
191: if (tmpdir[0] == '-') {
192: fprintf(stderr, "pc: bad -t option\n");
193: exit(1);
194: }
195: tflag = 1;
196: continue;
197: case 'O':
198: Oflag = 1;
199: continue;
200: case 'S':
201: Sflag = 1;
202: continue;
203: case 'J':
204: Jflag = 1;
205: continue;
206: case 'T':
207: switch (argp[2]) {
208:
209: case '0':
210: pc0 = _PATH_DPC0;
211: if (argp[3] != '\0') {
212: pc0 = &argp[3];
213: }
214: continue;
215: case '1':
216: pc1 = _PATH_DPC1;
217: if (argp[3] != '\0') {
218: pc1 = &argp[3];
219: }
220: continue;
221: case '2':
222: pc2 = _PATH_DPC2;
223: if (argp[3] != '\0') {
224: pc2 = &argp[3];
225: }
226: continue;
227: case '3':
228: pc3 = _PATH_DPC3;
229: if (argp[3] != '\0') {
230: pc3 = &argp[3];
231: }
232: continue;
233: case 'l':
234: Tlflag = 1;
235: lpc = _PATH_DLPC;
236: if (argp[3] != '\0') {
237: lpc = &argp[3];
238: }
239: continue;
240: }
241: continue;
242: case 'c':
243: cflag = 1;
244: continue;
245: case 'l':
246: if (argp[2])
247: continue;
248: /* fall into ... */
249: case 'b':
250: case 's':
251: case 'z':
252: case 'C':
253: pc0args[pc0argx++] = argp;
254: continue;
255: case 'w':
256: wflag = 1;
257: pc0args[pc0argx++] = argp;
258: continue;
259: case 'g':
260: gflag = 1;
261: pc0args[pc0argx++] = argp;
262: continue;
263: case 'p':
264: if (argp[2] == 'g')
265: crt0 = gcrt0;
266: else
267: crt0 = mcrt0;
268: if (!Tlflag)
269: lpc = "-lpc_p";
270: pflag = 1;
271: continue;
272: }
273: }
274: if (gflag && Oflag) {
275: fprintf(stderr, "pc: warning: -g overrides -O\n");
276: Oflag = 0;
277: }
278: sprintf(tmp0, "%s/%s", tmpdir, "p0XXXXXX");
279: tname[0] = mktemp(tmp0);
280: sprintf(tmp1, "%s/%s", tmpdir, "p1XXXXXX");
281: tname[1] = mktemp(tmp1);
282: savargx = pc0argx;
283: for (i = 0; i < argc; i++) {
284: argp = argv[i];
285: if (argp[0] == '-')
286: continue;
287: if (suffix(argp) == 's') {
288: asargx = 1;
289: if (Jflag)
290: asargs[asargx++] = "-J";
291: # if defined(vax) || defined(tahoe)
292: if (tflag) {
293: asargs[asargx++] = "-t";
294: asargs[asargx++] = tmpdir;
295: }
296: # endif vax || tahoe
297: asargs[asargx++] = argp;
298: asargs[asargx++] = "-o";
299: tfile[1] = setsuf(argp, 'o');
300: asargs[asargx++] = tfile[1];
301: asargs[asargx] = 0;
302: if (dosys(as, asargs, 0, 0))
303: continue;
304: tfile[1] = 0;
305: continue;
306: }
307: if (suffix(argp) != 'p')
308: continue;
309: tfile[0] = tname[0];
310: pc0args[2] = tfile[0];
311: pc0argx = savargx;
312: if (pflag)
313: pc0args[pc0argx++] = "-p";
314: if (Jflag)
315: pc0args[pc0argx++] = "-J";
316: pc0args[pc0argx++] = argp;
317: pc0args[pc0argx] = 0;
318: if (dosys(pc0, pc0args, 0, 0))
319: continue;
320: pc1args[1] = tfile[0];
321: tfile[1] = tname[1];
322: if (dosys(pc1, pc1args, 0, tfile[1]))
323: continue;
324: unlink(tfile[0]);
325: tfile[0] = tname[0];
326: if (Oflag) {
327: if (dosys(c2, c2args, tfile[1], tfile[0]))
328: continue;
329: unlink(tfile[1]);
330: tfile[1] = tfile[0];
331: tfile[0] = tname[1];
332: }
333: if (Sflag)
334: tfile[0] = setsuf(argp, 's');
335: if (dosys(pc2, pc2args, tfile[1], tfile[0]))
336: continue;
337: unlink(tfile[1]);
338: tfile[1] = 0;
339: if (Sflag) {
340: tfile[0] = 0;
341: continue;
342: }
343: asargx = 1;
344: if (Jflag)
345: asargs[asargx++] = "-J";
346: # if defined(vax) || defined(tahoe)
347: if (tflag) {
348: asargs[asargx++] = "-t";
349: asargs[asargx++] = tmpdir;
350: }
351: # endif vax || tahoe
352: asargs[asargx++] = tfile[0];
353: asargs[asargx++] = "-o";
354: tfile[1] = setsuf(argp, 'o');
355: asargs[asargx++] = tfile[1];
356: asargs[asargx] = 0;
357: if (dosys(as, asargs, 0, 0))
358: continue;
359: tfile[1] = 0;
360: remove();
361: }
362: if (errs || cflag || Sflag)
363: done();
364: /* char *pc3args[NARGS] = { "pc3", 0 }; */
365: pc3args[0] = "pc3";
366: if (wflag)
367: pc3args[pc3argx++] = "-w";
368: pc3args[pc3argx++] = _PATH_PCEXTERN;
369: for (i = 0; i < argc; i++) {
370: argp = argv[i];
371: if (!strcmp(argp, "-o"))
372: i++;
373: if (argp[0] == '-')
374: continue;
375: switch (getsuf(argp)) {
376:
377: case 'o':
378: pc3args[pc3argx++] = argp;
379: nxo++;
380: continue;
381: case 's':
382: case 'p':
383: onepso = pc3args[pc3argx++] =
384: savestr(setsuf(argp, 'o'));
385: np++;
386: continue;
387: }
388: }
389: pc3args[pc3argx] = 0;
390: if (dosys(pc3, pc3args, 0, 0) > 1)
391: done();
392: errs = 0;
393: /* char *ldargs[NARGS] = { "ld", "-X", _PATH_CRT0, 0, }; */
394: ldargs[0] = "ld";
395: ldargs[1] = "-X";
396: ldargs[2] = crt0;
397: for (i = 0; i < argc; i++) {
398: argp = argv[i];
399: if (argp[0] != '-') {
400: switch (getsuf(argp)) {
401:
402: case 'p':
403: case 's':
404: ldargs[ldargx] = savestr(setsuf(argp, 'o'));
405: break;
406: default:
407: ldargs[ldargx] = argp;
408: break;
409: }
410: if (getsuf(ldargs[ldargx]) == 'o')
411: for (j = 0; j < ldargx; j++)
412: if (!strcmp(ldargs[j], ldargs[ldargx]))
413: goto duplicate;
414: ldargx++;
415: duplicate:
416: continue;
417: }
418: switch (argp[1]) {
419:
420: case 'i':
421: while (i+1 < argc && argv[i+1][0] != '-' &&
422: getsuf(argv[i+1]) != 'p')
423: i++;
424: continue;
425: case 'd':
426: if (argp[2] == 0)
427: continue;
428: ldargs[ldargx++] = argp;
429: continue;
430: case 'o':
431: ldargs[ldargx++] = argp;
432: i++;
433: ldargs[ldargx++] = argv[i];
434: continue;
435: case 'l':
436: if (argp[2])
437: ldargs[ldargx++] = argp;
438: continue;
439: case 't':
440: i++;
441: continue;
442: case 'c':
443: case 'g':
444: case 'w':
445: case 'p':
446: case 'S':
447: case 'J':
448: case 'T':
449: case 'O':
450: case 'C':
451: case 'b':
452: case 's':
453: case 'z':
454: continue;
455: default:
456: ldargs[ldargx++] = argp;
457: continue;
458: }
459: }
460: ldargs[ldargx++] = lpc;
461: if (gflag)
462: ldargs[ldargx++] = "-lg";
463: if (pflag) {
464: ldargs[ldargx++] = "-lm_p";
465: ldargs[ldargx++] = "-lc_p";
466: } else {
467: ldargs[ldargx++] = "-lm";
468: ldargs[ldargx++] = "-lc";
469: }
470: ldargs[ldargx] = 0;
471: if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0)
472: unlink(onepso);
473: done();
474: }
475:
476: dosys(cmd, argv, in, out)
477: char *cmd, **argv, *in, *out;
478: {
479: union wait status;
480: int pid;
481:
482: if (debug) {
483: int i;
484: printf("%s:", cmd);
485: for (i = 0; argv[i]; i++)
486: printf(" %s", argv[i]);
487: if (in)
488: printf(" <%s", in);
489: if (out)
490: printf(" >%s", out);
491: printf("\n");
492: }
493: /*
494: * warning: vfork doesn't work here, because the call to signal()
495: * done by the child process destroys the parent's SIGINT handler.
496: */
497: pid = fork();
498: if (pid < 0) {
499: fprintf(stderr, "pc: No more processes\n");
500: done();
501: }
502: if (pid == 0) {
503: if (in) {
504: close(0);
505: if (open(in, 0) != 0) {
506: perror(in);
507: exit(1);
508: }
509: }
510: if (out) {
511: close(1);
512: unlink(out);
513: if (creat(out, 0666) != 1) {
514: perror(out);
515: exit(1);
516: }
517: }
518: signal(SIGINT, SIG_DFL);
519: execv(cmd, argv);
520: perror(cmd);
521: exit(1);
522: }
523: while (wait(&status) != pid)
524: ;
525: if (WIFSIGNALED(status)) {
526: if (status.w_termsig != SIGINT) {
527: fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]);
528: if (status.w_coredump)
529: fprintf(stderr, " (core dumped)");
530: fprintf(stderr, "\n");
531: }
532: errs = 100;
533: done();
534: /*NOTREACHED*/
535: }
536: if (status.w_retcode) {
537: errs = 1;
538: remove();
539: }
540: return (status.w_retcode);
541: }
542:
543: done()
544: {
545:
546: remove();
547: exit(errs);
548: }
549:
550: remove()
551: {
552:
553: if (tfile[0])
554: unlink(tfile[0]);
555: if (tfile[1])
556: unlink(tfile[1]);
557: }
558:
559: onintr()
560: {
561:
562: errs = 1;
563: done();
564: }
565:
566: getsuf(cp)
567: char *cp;
568: {
569:
570: if (*cp == 0)
571: return;
572: while (cp[1])
573: cp++;
574: if (cp[-1] != '.')
575: return (0);
576: return (*cp);
577: }
578:
579: char *
580: setsuf(as, ch)
581: char *as;
582: {
583: register char *s, *s1;
584:
585: s = s1 = savestr(as);
586: while (*s)
587: if (*s++ == '/')
588: s1 = s;
589: s[-1] = ch;
590: return (s1);
591: }
592:
593: #define NSAVETAB 512
594: char *savetab;
595: int saveleft;
596:
597: char *
598: savestr(cp)
599: register char *cp;
600: {
601: register int len;
602:
603: len = strlen(cp) + 1;
604: if (len > saveleft) {
605: saveleft = NSAVETAB;
606: if (len > saveleft)
607: saveleft = len;
608: savetab = (char *)malloc(saveleft);
609: if (savetab == 0) {
610: fprintf(stderr, "ran out of memory (savestr)\n");
611: exit(1);
612: }
613: }
614: strncpy(savetab, cp, len);
615: cp = savetab;
616: savetab += len;
617: return (cp);
618: }
619:
620: suffix(cp)
621: char *cp;
622: {
623:
624: if (cp[0] == 0 || cp[1] == 0)
625: return (0);
626: while (cp[1])
627: cp++;
628: if (cp[-1] == '.')
629: return (*cp);
630: return (0);
631: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.