1*12966Smckusick static char sccsid[] = "@(#)pc.c 3.24 06/10/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) { 15512931Speter fprintf(stderr, "pc: -t but no directory\n"); 15612870Speter exit(1); 15712870Speter } 15812931Speter if (argp[2] != '\0') { 15912931Speter fprintf(stderr, "pc: bad -t option\n"); 16012931Speter exit(1); 16112931Speter } 16212870Speter tmpdir = argv[i]; 16312931Speter if (tmpdir[0] == '-') { 16412931Speter fprintf(stderr, "pc: bad -t option\n"); 16512931Speter exit(1); 16612931Speter } 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"; 286*12966Smckusick if (Jflag) 287*12966Smckusick pc0args[pc0argx++] = "-J"; 288621Sbill pc0args[pc0argx++] = argp; 289621Sbill pc0args[pc0argx] = 0; 290621Sbill if (dosys(pc0, pc0args, 0, 0)) 291621Sbill continue; 292621Sbill pc1args[1] = tfile[0]; 293654Sbill tfile[1] = tname[1]; 294621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 295621Sbill continue; 296621Sbill unlink(tfile[0]); 2972340Smckusic tfile[0] = tname[0]; 2982340Smckusic if (Oflag) { 2992340Smckusic if (dosys(c2, c2args, tfile[1], tfile[0])) 3002340Smckusic continue; 3012340Smckusic unlink(tfile[1]); 3022340Smckusic tfile[1] = tfile[0]; 3032340Smckusic tfile[0] = tname[1]; 3042340Smckusic } 3052340Smckusic if (Sflag) 306654Sbill tfile[0] = setsuf(argp, 's'); 307621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 308621Sbill continue; 309621Sbill unlink(tfile[1]); 310621Sbill tfile[1] = 0; 311654Sbill if (Sflag) { 312654Sbill tfile[0] = 0; 313621Sbill continue; 314654Sbill } 315908Sbill asargx = 1; 316908Sbill if (Jflag) 317908Sbill asargs[asargx++] = "-J"; 31812870Speter # ifdef vax 31912870Speter if (tflag) { 32012870Speter asargs[asargx++] = "-t"; 32112870Speter asargs[asargx++] = tmpdir; 32212870Speter } 32312870Speter # endif vax 324908Sbill asargs[asargx++] = tfile[0]; 325908Sbill asargs[asargx++] = "-o"; 326621Sbill tfile[1] = setsuf(argp, 'o'); 327908Sbill asargs[asargx++] = tfile[1]; 328908Sbill asargs[asargx] = 0; 329621Sbill if (dosys(as, asargs, 0, 0)) 330621Sbill continue; 331621Sbill tfile[1] = 0; 332621Sbill remove(); 333621Sbill } 334621Sbill if (errs || cflag || Sflag) 335621Sbill done(); 3367596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 337621Sbill pc3args[0] = "pc3"; 3387596Smckusick if (wflag) 3397596Smckusick pc3args[pc3argx++] = "-w"; 3407596Smckusick pc3args[pc3argx++] = "/usr/lib/pcexterns.o"; 341621Sbill for (i = 0; i < argc; i++) { 342621Sbill argp = argv[i]; 343621Sbill if (!strcmp(argp, "-o")) 344621Sbill i++; 345621Sbill if (argp[0] == '-') 346621Sbill continue; 347621Sbill switch (getsuf(argp)) { 348621Sbill 349621Sbill case 'o': 350621Sbill pc3args[pc3argx++] = argp; 351621Sbill nxo++; 352621Sbill continue; 3531211Speter case 's': 354621Sbill case 'p': 355621Sbill onepso = pc3args[pc3argx++] = 356621Sbill savestr(setsuf(argp, 'o')); 357621Sbill np++; 358621Sbill continue; 359621Sbill } 360621Sbill } 361621Sbill pc3args[pc3argx] = 0; 3627596Smckusick if (dosys(pc3, pc3args, 0, 0) > 1) 363621Sbill done(); 36410672Speter errs = 0; 365908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 366621Sbill ldargs[0] = "ld"; 367621Sbill ldargs[1] = "-X"; 368654Sbill ldargs[2] = crt0; 369621Sbill for (i = 0; i < argc; i++) { 370621Sbill argp = argv[i]; 371621Sbill if (argp[0] != '-') { 372621Sbill switch (getsuf(argp)) { 373621Sbill 374621Sbill case 'p': 3751211Speter case 's': 376621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 377621Sbill break; 378621Sbill default: 379621Sbill ldargs[ldargx] = argp; 380621Sbill break; 381621Sbill } 382621Sbill if (getsuf(ldargs[ldargx]) == 'o') 383621Sbill for (j = 0; j < ldargx; j++) 384621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 385621Sbill goto duplicate; 386621Sbill ldargx++; 387621Sbill duplicate: 388621Sbill continue; 389621Sbill } 390621Sbill switch (argp[1]) { 391621Sbill 392621Sbill case 'i': 393621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 394621Sbill getsuf(argv[i+1]) != 'p') 395621Sbill i++; 396621Sbill continue; 397621Sbill case 'd': 398621Sbill if (argp[2] == 0) 399621Sbill continue; 400621Sbill ldargs[ldargx++] = argp; 401621Sbill continue; 402621Sbill case 'o': 403621Sbill ldargs[ldargx++] = argp; 404621Sbill i++; 405621Sbill ldargs[ldargx++] = argv[i]; 406621Sbill continue; 407621Sbill case 'l': 408621Sbill if (argp[2]) 409621Sbill ldargs[ldargx++] = argp; 410621Sbill continue; 41112870Speter case 't': 41212870Speter i++; 41312870Speter continue; 414621Sbill case 'c': 415621Sbill case 'g': 416621Sbill case 'w': 417621Sbill case 'p': 418621Sbill case 'S': 419908Sbill case 'J': 420621Sbill case 'T': 421621Sbill case 'O': 422621Sbill case 'C': 423621Sbill case 'b': 424621Sbill case 's': 425621Sbill case 'z': 426621Sbill continue; 427621Sbill default: 428621Sbill ldargs[ldargx++] = argp; 429621Sbill continue; 430621Sbill } 431621Sbill } 432621Sbill ldargs[ldargx++] = lpc; 433621Sbill if (gflag) 434621Sbill ldargs[ldargx++] = "-lg"; 4355054Smckusic if (pflag) { 4365054Smckusic ldargs[ldargx++] = "-lm_p"; 4375054Smckusic ldargs[ldargx++] = "-lc_p"; 4385054Smckusic } else { 4395054Smckusic ldargs[ldargx++] = "-lm"; 4405054Smckusic ldargs[ldargx++] = "-lc"; 4415054Smckusic } 442621Sbill ldargs[ldargx] = 0; 443621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 444621Sbill unlink(onepso); 445621Sbill done(); 446621Sbill } 447621Sbill 448621Sbill dosys(cmd, argv, in, out) 449621Sbill char *cmd, **argv, *in, *out; 450621Sbill { 451621Sbill union wait status; 452621Sbill int pid; 453621Sbill 454621Sbill if (debug) { 455621Sbill int i; 456621Sbill printf("%s:", cmd); 457621Sbill for (i = 0; argv[i]; i++) 458621Sbill printf(" %s", argv[i]); 459621Sbill if (in) 460621Sbill printf(" <%s", in); 461621Sbill if (out) 462621Sbill printf(" >%s", out); 463621Sbill printf("\n"); 464621Sbill } 465621Sbill pid = vfork(); 466621Sbill if (pid < 0) { 467621Sbill fprintf(stderr, "pc: No more processes\n"); 468621Sbill done(); 469621Sbill } 470621Sbill if (pid == 0) { 471621Sbill if (in) { 472621Sbill close(0); 473621Sbill if (open(in, 0) != 0) { 474621Sbill perror(in); 475621Sbill exit(1); 476621Sbill } 477621Sbill } 478621Sbill if (out) { 479621Sbill close(1); 480621Sbill unlink(out); 481621Sbill if (creat(out, 0666) != 1) { 482621Sbill perror(out); 483621Sbill exit(1); 484621Sbill } 485621Sbill } 486621Sbill signal(SIGINT, SIG_DFL); 487621Sbill execv(cmd, argv); 488621Sbill perror(cmd); 489621Sbill exit(1); 490621Sbill } 491621Sbill while (wait(&status) != pid) 492621Sbill ; 493621Sbill if (WIFSIGNALED(status)) { 4947766Smckusick if (status.w_termsig != SIGINT) { 4957766Smckusick fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 4967766Smckusick if (status.w_coredump) 4977766Smckusick fprintf(stderr, " (core dumped)"); 4987766Smckusick fprintf(stderr, "\n"); 4997766Smckusick } 500621Sbill errs = 100; 501621Sbill done(); 502621Sbill /*NOTREACHED*/ 503621Sbill } 504621Sbill if (status.w_retcode) { 505621Sbill errs = 1; 506621Sbill remove(); 507621Sbill } 508621Sbill return (status.w_retcode); 509621Sbill } 510621Sbill 511621Sbill done() 512621Sbill { 513621Sbill 514621Sbill remove(); 515621Sbill exit(errs); 516621Sbill } 517621Sbill 518621Sbill remove() 519621Sbill { 520621Sbill 521621Sbill if (tfile[0]) 522621Sbill unlink(tfile[0]); 523621Sbill if (tfile[1]) 524621Sbill unlink(tfile[1]); 525621Sbill } 526621Sbill 527621Sbill onintr() 528621Sbill { 529621Sbill 530621Sbill errs = 1; 531621Sbill done(); 532621Sbill } 533621Sbill 534621Sbill getsuf(cp) 535621Sbill char *cp; 536621Sbill { 537621Sbill 538621Sbill if (*cp == 0) 539621Sbill return; 540621Sbill while (cp[1]) 541621Sbill cp++; 542621Sbill if (cp[-1] != '.') 543621Sbill return (0); 544621Sbill return (*cp); 545621Sbill } 546621Sbill 547621Sbill char * 548654Sbill setsuf(as, ch) 549654Sbill char *as; 550621Sbill { 551654Sbill register char *s, *s1; 552621Sbill 553654Sbill s = s1 = savestr(as); 554654Sbill while (*s) 555654Sbill if (*s++ == '/') 556654Sbill s1 = s; 557654Sbill s[-1] = ch; 558654Sbill return (s1); 559621Sbill } 560621Sbill 561621Sbill #define NSAVETAB 512 562621Sbill char *savetab; 563621Sbill int saveleft; 564621Sbill 565621Sbill char * 566621Sbill savestr(cp) 567621Sbill register char *cp; 568621Sbill { 569621Sbill register int len; 570621Sbill 571621Sbill len = strlen(cp) + 1; 572621Sbill if (len > saveleft) { 573621Sbill saveleft = NSAVETAB; 574621Sbill if (len > saveleft) 575621Sbill saveleft = len; 576621Sbill savetab = (char *)malloc(saveleft); 577621Sbill if (savetab == 0) { 578621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 579621Sbill exit(1); 580621Sbill } 581621Sbill } 582621Sbill strncpy(savetab, cp, len); 583621Sbill cp = savetab; 584621Sbill savetab += len; 585621Sbill return (cp); 586621Sbill } 587621Sbill 588621Sbill suffix(cp) 589621Sbill char *cp; 590621Sbill { 591621Sbill 592621Sbill if (cp[0] == 0 || cp[1] == 0) 593621Sbill return (0); 594621Sbill while (cp[1]) 595621Sbill cp++; 596621Sbill if (cp[-1] == '.') 597621Sbill return (*cp); 598621Sbill return (0); 599621Sbill } 600