1*12931Speter static char sccsid[] = "@(#)pc.c 3.23 06/06/83"; 25054Smckusic 3621Sbill #include <stdio.h> 4621Sbill #include <signal.h> 5621Sbill #include <wait.h> 612870Speter #include <sys/param.h> 7621Sbill 8621Sbill /* 9654Sbill * Pc - front end for Pascal compiler. 10621Sbill */ 11908Sbill char *pc0 = "/usr/lib/pc0"; 12908Sbill char *pc1 = "/lib/f1"; 13908Sbill char *pc2 = "/usr/lib/pc2"; 14908Sbill char *c2 = "/lib/c2"; 15908Sbill char *pc3 = "/usr/lib/pc3"; 16908Sbill char *ld = "/bin/ld"; 17908Sbill char *as = "/bin/as"; 18621Sbill char *lpc = "-lpc"; 19908Sbill char *crt0 = "/lib/crt0.o"; 20908Sbill char *mcrt0 = "/lib/mcrt0.o"; 215054Smckusic char *gcrt0 = "/usr/lib/gcrt0.o"; 22621Sbill 23621Sbill char *mktemp(); 2412870Speter char *tmpdir = "/tmp"; 2512870Speter char tmp0[MAXPATHLEN], tmp1[MAXPATHLEN]; 26621Sbill char *tname[2]; 27621Sbill char *tfile[2]; 28621Sbill 29621Sbill char *setsuf(), *savestr(); 30621Sbill 3112870Speter int Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag, wflag, tflag; 32621Sbill int debug; 33621Sbill 34621Sbill #define NARGS 512 35621Sbill int ldargx = 3; 36621Sbill int pc0argx = 3; 37621Sbill char *pc0args[NARGS] = { "pc0", "-o", "XXX" }; 38621Sbill char *pc1args[3] = { "pc1", 0, }; 39621Sbill char *pc2args[2] = { "pc2", 0 }; 40621Sbill char *c2args[4] = { "c2", 0, 0, 0 }; 417596Smckusick int pc3argx = 1; 42621Sbill #define pc3args pc0args 43621Sbill #define ldargs pc0args 447596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 45908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 4612870Speter 4712870Speter /* as -J -t tmpdir -o objfile srcfile \0 */ 48908Sbill int asargx; 4912870Speter char *asargs[8] = { "as", 0, }; 50621Sbill 517766Smckusick char *mesg[] = { 527766Smckusick 0, 537766Smckusick "Hangup", 547766Smckusick "Interrupt", 557766Smckusick "Quit", 567766Smckusick "Illegal instruction", 577766Smckusick "Trace/BPT trap", 587766Smckusick "IOT trap", 597766Smckusick "EMT trap", 607766Smckusick "Floating exception", 617766Smckusick "Killed", 627766Smckusick "Bus error", 637766Smckusick "Segmentation fault", 647766Smckusick "Bad system call", 657766Smckusick "Broken pipe", 667766Smckusick "Alarm clock", 677766Smckusick "Terminated", 687766Smckusick "Signal 16", 697766Smckusick "Stopped (signal)", 707766Smckusick "Stopped", 717766Smckusick "Continued", 727766Smckusick "Child exited", 737766Smckusick "Stopped (tty input)", 747766Smckusick "Stopped (tty output)", 757766Smckusick "Tty input interrupt", 767766Smckusick "Cputime limit exceeded", 777766Smckusick "Filesize limit exceeded", 787766Smckusick "Signal 26", 797766Smckusick "Signal 27", 807766Smckusick "Signal 28", 817766Smckusick "Signal 29", 827766Smckusick "Signal 30", 837766Smckusick "Signal 31", 847766Smckusick "Signal 32" 857766Smckusick }; 867766Smckusick 87621Sbill /* 88621Sbill * If the number of .p arguments (np) is 1, and the number of .o arguments 89621Sbill * (nxo) is 0, and we successfully create an ``a.out'', then we remove 90621Sbill * the one .ps .o file (onepso). 91621Sbill */ 92621Sbill int np, nxo; 93621Sbill char *onepso; 94621Sbill int errs; 95621Sbill 96621Sbill int onintr(); 97621Sbill 98621Sbill main(argc, argv) 99621Sbill int argc; 100621Sbill char **argv; 101621Sbill { 102621Sbill register char *argp; 103621Sbill register int i; 104621Sbill int savargx; 105621Sbill char *t, c; 106621Sbill int j; 107621Sbill 108621Sbill argc--, argv++; 109621Sbill if (argc == 0) { 110621Sbill execl("/bin/cat", "cat", "/usr/lib/how_pc"); 111621Sbill exit(1); 112621Sbill } 113621Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 114621Sbill signal(SIGINT, onintr); 115621Sbill signal(SIGTERM, onintr); 116621Sbill } 117621Sbill for (i = 0; i < argc; i++) { 118621Sbill argp = argv[i]; 119621Sbill if (argp[0] != '-') 120621Sbill continue; 121621Sbill switch (argp[1]) { 122621Sbill 123621Sbill case 'd': 124621Sbill if (argp[2] == 0) 125621Sbill debug++; 126621Sbill continue; 127621Sbill case 'i': 128621Sbill pc0args[pc0argx++] = "-i"; 129621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 130621Sbill getsuf(argv[i+1]) != 'p') { 131621Sbill pc0args[pc0argx++] = argv[i+1]; 132621Sbill i++; 133621Sbill } 134621Sbill if (i+1 == argc) { 135621Sbill fprintf(stderr, "pc: bad -i construction\n"); 136621Sbill exit(1); 137621Sbill } 138621Sbill continue; 139621Sbill case 'o': 140621Sbill i++; 141621Sbill if (i == argc) { 142621Sbill fprintf(stderr, "pc: -o must specify file\n"); 143621Sbill exit(1); 144621Sbill } 145621Sbill c = getsuf(argv[i]); 146621Sbill if (c == 'o' || c == 'p' || c == 'c') { 147621Sbill fprintf(stderr, "pc: -o would overwrite %s\n", 148621Sbill argv[i]); 149621Sbill exit(1); 150621Sbill } 151621Sbill continue; 15212870Speter case 't': 15312870Speter i++; 15412870Speter if (i == argc) { 155*12931Speter fprintf(stderr, "pc: -t but no directory\n"); 15612870Speter exit(1); 15712870Speter } 158*12931Speter if (argp[2] != '\0') { 159*12931Speter fprintf(stderr, "pc: bad -t option\n"); 160*12931Speter exit(1); 161*12931Speter } 16212870Speter tmpdir = argv[i]; 163*12931Speter if (tmpdir[0] == '-') { 164*12931Speter fprintf(stderr, "pc: bad -t option\n"); 165*12931Speter exit(1); 166*12931Speter } 16712870Speter tflag = 1; 16812870Speter continue; 169621Sbill case 'O': 170621Sbill Oflag = 1; 171621Sbill continue; 172621Sbill case 'S': 173621Sbill Sflag = 1; 174621Sbill continue; 175908Sbill case 'J': 176908Sbill Jflag = 1; 177908Sbill continue; 178621Sbill case 'T': 179621Sbill switch (argp[2]) { 180621Sbill 181621Sbill case '0': 18210721Smckusick pc0 = "/usr/src/ucb/pascal/pc0/a.out"; 1833862Smckusic if (argp[3] != '\0') { 1843862Smckusic pc0 = &argp[3]; 1853862Smckusic } 186621Sbill continue; 187621Sbill case '1': 1889140Smckusick pc1 = "/usr/src/lib/pcc/fort"; 1893862Smckusic if (argp[3] != '\0') { 1903862Smckusic pc1 = &argp[3]; 1913862Smckusic } 192621Sbill continue; 193621Sbill case '2': 19410721Smckusick pc2 = "/usr/src/ucb/pascal/utilities/pc2"; 1953862Smckusic if (argp[3] != '\0') { 1963862Smckusic pc2 = &argp[3]; 1973862Smckusic } 198621Sbill continue; 199621Sbill case '3': 20010721Smckusick pc3 = "/usr/src/ucb/pascal/utilities/pc3"; 2013862Smckusic if (argp[3] != '\0') { 2023862Smckusic pc3 = &argp[3]; 2033862Smckusic } 204621Sbill continue; 205621Sbill case 'l': 2065054Smckusic Tlflag = 1; 2079140Smckusick lpc = "/usr/src/usr.lib/libpc/libpc"; 2083862Smckusic if (argp[3] != '\0') { 2093862Smckusic lpc = &argp[3]; 2103862Smckusic } 211621Sbill continue; 212621Sbill } 213621Sbill continue; 214621Sbill case 'c': 215621Sbill cflag = 1; 216621Sbill continue; 217621Sbill case 'l': 218621Sbill if (argp[2]) 219621Sbill continue; 220621Sbill /* fall into ... */ 221621Sbill case 'b': 222621Sbill case 's': 223621Sbill case 'z': 224621Sbill case 'C': 225621Sbill pc0args[pc0argx++] = argp; 226621Sbill continue; 2277596Smckusick case 'w': 2287596Smckusick wflag = 1; 2297596Smckusick pc0args[pc0argx++] = argp; 2307596Smckusick continue; 2317596Smckusick case 'g': 2327596Smckusick gflag = 1; 2337596Smckusick pc0args[pc0argx++] = argp; 2347596Smckusick continue; 235621Sbill case 'p': 2365054Smckusic if (argp[2] == 'g') 2375054Smckusic crt0 = gcrt0; 2385054Smckusic else 2395054Smckusic crt0 = mcrt0; 2405054Smckusic if (!Tlflag) 2415054Smckusic lpc = "-lpc_p"; 2425054Smckusic pflag = 1; 243654Sbill continue; 244621Sbill } 245621Sbill } 246621Sbill if (gflag && Oflag) { 247621Sbill fprintf(stderr, "pc: warning: -g overrides -O\n"); 248621Sbill Oflag = 0; 249621Sbill } 25012870Speter sprintf(tmp0, "%s/%s", tmpdir, "p0XXXXXX"); 25112870Speter tname[0] = mktemp(tmp0); 25212870Speter sprintf(tmp1, "%s/%s", tmpdir, "p1XXXXXX"); 25312870Speter tname[1] = mktemp(tmp1); 254621Sbill savargx = pc0argx; 255621Sbill for (i = 0; i < argc; i++) { 256621Sbill argp = argv[i]; 257621Sbill if (argp[0] == '-') 258621Sbill continue; 2591211Speter if (suffix(argp) == 's') { 2601211Speter asargx = 1; 2611211Speter if (Jflag) 2621211Speter asargs[asargx++] = "-J"; 26312870Speter # ifdef vax 26412870Speter if (tflag) { 26512870Speter asargs[asargx++] = "-t"; 26612870Speter asargs[asargx++] = tmpdir; 26712870Speter } 26812870Speter # endif vax 2691211Speter asargs[asargx++] = argp; 2701211Speter asargs[asargx++] = "-o"; 2711211Speter tfile[1] = setsuf(argp, 'o'); 2721211Speter asargs[asargx++] = tfile[1]; 2731211Speter asargs[asargx] = 0; 2741211Speter if (dosys(as, asargs, 0, 0)) 2751211Speter continue; 2761211Speter tfile[1] = 0; 2771211Speter continue; 2781211Speter } 279621Sbill if (suffix(argp) != 'p') 280621Sbill continue; 281621Sbill tfile[0] = tname[0]; 282621Sbill pc0args[2] = tfile[0]; 283621Sbill pc0argx = savargx; 284654Sbill if (pflag) 285654Sbill pc0args[pc0argx++] = "-p"; 286621Sbill pc0args[pc0argx++] = argp; 287621Sbill pc0args[pc0argx] = 0; 288621Sbill if (dosys(pc0, pc0args, 0, 0)) 289621Sbill continue; 290621Sbill pc1args[1] = tfile[0]; 291654Sbill tfile[1] = tname[1]; 292621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 293621Sbill continue; 294621Sbill unlink(tfile[0]); 2952340Smckusic tfile[0] = tname[0]; 2962340Smckusic if (Oflag) { 2972340Smckusic if (dosys(c2, c2args, tfile[1], tfile[0])) 2982340Smckusic continue; 2992340Smckusic unlink(tfile[1]); 3002340Smckusic tfile[1] = tfile[0]; 3012340Smckusic tfile[0] = tname[1]; 3022340Smckusic } 3032340Smckusic if (Sflag) 304654Sbill tfile[0] = setsuf(argp, 's'); 305621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 306621Sbill continue; 307621Sbill unlink(tfile[1]); 308621Sbill tfile[1] = 0; 309654Sbill if (Sflag) { 310654Sbill tfile[0] = 0; 311621Sbill continue; 312654Sbill } 313908Sbill asargx = 1; 314908Sbill if (Jflag) 315908Sbill asargs[asargx++] = "-J"; 31612870Speter # ifdef vax 31712870Speter if (tflag) { 31812870Speter asargs[asargx++] = "-t"; 31912870Speter asargs[asargx++] = tmpdir; 32012870Speter } 32112870Speter # endif vax 322908Sbill asargs[asargx++] = tfile[0]; 323908Sbill asargs[asargx++] = "-o"; 324621Sbill tfile[1] = setsuf(argp, 'o'); 325908Sbill asargs[asargx++] = tfile[1]; 326908Sbill asargs[asargx] = 0; 327621Sbill if (dosys(as, asargs, 0, 0)) 328621Sbill continue; 329621Sbill tfile[1] = 0; 330621Sbill remove(); 331621Sbill } 332621Sbill if (errs || cflag || Sflag) 333621Sbill done(); 3347596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 335621Sbill pc3args[0] = "pc3"; 3367596Smckusick if (wflag) 3377596Smckusick pc3args[pc3argx++] = "-w"; 3387596Smckusick pc3args[pc3argx++] = "/usr/lib/pcexterns.o"; 339621Sbill for (i = 0; i < argc; i++) { 340621Sbill argp = argv[i]; 341621Sbill if (!strcmp(argp, "-o")) 342621Sbill i++; 343621Sbill if (argp[0] == '-') 344621Sbill continue; 345621Sbill switch (getsuf(argp)) { 346621Sbill 347621Sbill case 'o': 348621Sbill pc3args[pc3argx++] = argp; 349621Sbill nxo++; 350621Sbill continue; 3511211Speter case 's': 352621Sbill case 'p': 353621Sbill onepso = pc3args[pc3argx++] = 354621Sbill savestr(setsuf(argp, 'o')); 355621Sbill np++; 356621Sbill continue; 357621Sbill } 358621Sbill } 359621Sbill pc3args[pc3argx] = 0; 3607596Smckusick if (dosys(pc3, pc3args, 0, 0) > 1) 361621Sbill done(); 36210672Speter errs = 0; 363908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 364621Sbill ldargs[0] = "ld"; 365621Sbill ldargs[1] = "-X"; 366654Sbill ldargs[2] = crt0; 367621Sbill for (i = 0; i < argc; i++) { 368621Sbill argp = argv[i]; 369621Sbill if (argp[0] != '-') { 370621Sbill switch (getsuf(argp)) { 371621Sbill 372621Sbill case 'p': 3731211Speter case 's': 374621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 375621Sbill break; 376621Sbill default: 377621Sbill ldargs[ldargx] = argp; 378621Sbill break; 379621Sbill } 380621Sbill if (getsuf(ldargs[ldargx]) == 'o') 381621Sbill for (j = 0; j < ldargx; j++) 382621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 383621Sbill goto duplicate; 384621Sbill ldargx++; 385621Sbill duplicate: 386621Sbill continue; 387621Sbill } 388621Sbill switch (argp[1]) { 389621Sbill 390621Sbill case 'i': 391621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 392621Sbill getsuf(argv[i+1]) != 'p') 393621Sbill i++; 394621Sbill continue; 395621Sbill case 'd': 396621Sbill if (argp[2] == 0) 397621Sbill continue; 398621Sbill ldargs[ldargx++] = argp; 399621Sbill continue; 400621Sbill case 'o': 401621Sbill ldargs[ldargx++] = argp; 402621Sbill i++; 403621Sbill ldargs[ldargx++] = argv[i]; 404621Sbill continue; 405621Sbill case 'l': 406621Sbill if (argp[2]) 407621Sbill ldargs[ldargx++] = argp; 408621Sbill continue; 40912870Speter case 't': 41012870Speter i++; 41112870Speter continue; 412621Sbill case 'c': 413621Sbill case 'g': 414621Sbill case 'w': 415621Sbill case 'p': 416621Sbill case 'S': 417908Sbill case 'J': 418621Sbill case 'T': 419621Sbill case 'O': 420621Sbill case 'C': 421621Sbill case 'b': 422621Sbill case 's': 423621Sbill case 'z': 424621Sbill continue; 425621Sbill default: 426621Sbill ldargs[ldargx++] = argp; 427621Sbill continue; 428621Sbill } 429621Sbill } 430621Sbill ldargs[ldargx++] = lpc; 431621Sbill if (gflag) 432621Sbill ldargs[ldargx++] = "-lg"; 4335054Smckusic if (pflag) { 4345054Smckusic ldargs[ldargx++] = "-lm_p"; 4355054Smckusic ldargs[ldargx++] = "-lc_p"; 4365054Smckusic } else { 4375054Smckusic ldargs[ldargx++] = "-lm"; 4385054Smckusic ldargs[ldargx++] = "-lc"; 4395054Smckusic } 440621Sbill ldargs[ldargx] = 0; 441621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 442621Sbill unlink(onepso); 443621Sbill done(); 444621Sbill } 445621Sbill 446621Sbill dosys(cmd, argv, in, out) 447621Sbill char *cmd, **argv, *in, *out; 448621Sbill { 449621Sbill union wait status; 450621Sbill int pid; 451621Sbill 452621Sbill if (debug) { 453621Sbill int i; 454621Sbill printf("%s:", cmd); 455621Sbill for (i = 0; argv[i]; i++) 456621Sbill printf(" %s", argv[i]); 457621Sbill if (in) 458621Sbill printf(" <%s", in); 459621Sbill if (out) 460621Sbill printf(" >%s", out); 461621Sbill printf("\n"); 462621Sbill } 463621Sbill pid = vfork(); 464621Sbill if (pid < 0) { 465621Sbill fprintf(stderr, "pc: No more processes\n"); 466621Sbill done(); 467621Sbill } 468621Sbill if (pid == 0) { 469621Sbill if (in) { 470621Sbill close(0); 471621Sbill if (open(in, 0) != 0) { 472621Sbill perror(in); 473621Sbill exit(1); 474621Sbill } 475621Sbill } 476621Sbill if (out) { 477621Sbill close(1); 478621Sbill unlink(out); 479621Sbill if (creat(out, 0666) != 1) { 480621Sbill perror(out); 481621Sbill exit(1); 482621Sbill } 483621Sbill } 484621Sbill signal(SIGINT, SIG_DFL); 485621Sbill execv(cmd, argv); 486621Sbill perror(cmd); 487621Sbill exit(1); 488621Sbill } 489621Sbill while (wait(&status) != pid) 490621Sbill ; 491621Sbill if (WIFSIGNALED(status)) { 4927766Smckusick if (status.w_termsig != SIGINT) { 4937766Smckusick fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 4947766Smckusick if (status.w_coredump) 4957766Smckusick fprintf(stderr, " (core dumped)"); 4967766Smckusick fprintf(stderr, "\n"); 4977766Smckusick } 498621Sbill errs = 100; 499621Sbill done(); 500621Sbill /*NOTREACHED*/ 501621Sbill } 502621Sbill if (status.w_retcode) { 503621Sbill errs = 1; 504621Sbill remove(); 505621Sbill } 506621Sbill return (status.w_retcode); 507621Sbill } 508621Sbill 509621Sbill done() 510621Sbill { 511621Sbill 512621Sbill remove(); 513621Sbill exit(errs); 514621Sbill } 515621Sbill 516621Sbill remove() 517621Sbill { 518621Sbill 519621Sbill if (tfile[0]) 520621Sbill unlink(tfile[0]); 521621Sbill if (tfile[1]) 522621Sbill unlink(tfile[1]); 523621Sbill } 524621Sbill 525621Sbill onintr() 526621Sbill { 527621Sbill 528621Sbill errs = 1; 529621Sbill done(); 530621Sbill } 531621Sbill 532621Sbill getsuf(cp) 533621Sbill char *cp; 534621Sbill { 535621Sbill 536621Sbill if (*cp == 0) 537621Sbill return; 538621Sbill while (cp[1]) 539621Sbill cp++; 540621Sbill if (cp[-1] != '.') 541621Sbill return (0); 542621Sbill return (*cp); 543621Sbill } 544621Sbill 545621Sbill char * 546654Sbill setsuf(as, ch) 547654Sbill char *as; 548621Sbill { 549654Sbill register char *s, *s1; 550621Sbill 551654Sbill s = s1 = savestr(as); 552654Sbill while (*s) 553654Sbill if (*s++ == '/') 554654Sbill s1 = s; 555654Sbill s[-1] = ch; 556654Sbill return (s1); 557621Sbill } 558621Sbill 559621Sbill #define NSAVETAB 512 560621Sbill char *savetab; 561621Sbill int saveleft; 562621Sbill 563621Sbill char * 564621Sbill savestr(cp) 565621Sbill register char *cp; 566621Sbill { 567621Sbill register int len; 568621Sbill 569621Sbill len = strlen(cp) + 1; 570621Sbill if (len > saveleft) { 571621Sbill saveleft = NSAVETAB; 572621Sbill if (len > saveleft) 573621Sbill saveleft = len; 574621Sbill savetab = (char *)malloc(saveleft); 575621Sbill if (savetab == 0) { 576621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 577621Sbill exit(1); 578621Sbill } 579621Sbill } 580621Sbill strncpy(savetab, cp, len); 581621Sbill cp = savetab; 582621Sbill savetab += len; 583621Sbill return (cp); 584621Sbill } 585621Sbill 586621Sbill suffix(cp) 587621Sbill char *cp; 588621Sbill { 589621Sbill 590621Sbill if (cp[0] == 0 || cp[1] == 0) 591621Sbill return (0); 592621Sbill while (cp[1]) 593621Sbill cp++; 594621Sbill if (cp[-1] == '.') 595621Sbill return (*cp); 596621Sbill return (0); 597621Sbill } 598