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