1*13724Ssam #ifndef lint 2*13724Ssam static char sccsid[] = "@(#)pc.c 3.25 (Berkeley) 07/02/83"; 3*13724Ssam #endif 45054Smckusic 5621Sbill #include <stdio.h> 6621Sbill #include <signal.h> 7*13724Ssam #include <sys/wait.h> 812870Speter #include <sys/param.h> 9621Sbill 10621Sbill /* 11654Sbill * Pc - front end for Pascal compiler. 12621Sbill */ 13908Sbill char *pc0 = "/usr/lib/pc0"; 14908Sbill char *pc1 = "/lib/f1"; 15908Sbill char *pc2 = "/usr/lib/pc2"; 16908Sbill char *c2 = "/lib/c2"; 17908Sbill char *pc3 = "/usr/lib/pc3"; 18908Sbill char *ld = "/bin/ld"; 19908Sbill char *as = "/bin/as"; 20621Sbill char *lpc = "-lpc"; 21908Sbill char *crt0 = "/lib/crt0.o"; 22908Sbill char *mcrt0 = "/lib/mcrt0.o"; 235054Smckusic char *gcrt0 = "/usr/lib/gcrt0.o"; 24621Sbill 25621Sbill char *mktemp(); 2612870Speter char *tmpdir = "/tmp"; 2712870Speter char tmp0[MAXPATHLEN], tmp1[MAXPATHLEN]; 28621Sbill char *tname[2]; 29621Sbill char *tfile[2]; 30621Sbill 31621Sbill char *setsuf(), *savestr(); 32621Sbill 3312870Speter int Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag, wflag, tflag; 34621Sbill int debug; 35621Sbill 36621Sbill #define NARGS 512 37621Sbill int ldargx = 3; 38621Sbill int pc0argx = 3; 39621Sbill char *pc0args[NARGS] = { "pc0", "-o", "XXX" }; 40621Sbill char *pc1args[3] = { "pc1", 0, }; 41621Sbill char *pc2args[2] = { "pc2", 0 }; 42621Sbill char *c2args[4] = { "c2", 0, 0, 0 }; 437596Smckusick int pc3argx = 1; 44621Sbill #define pc3args pc0args 45621Sbill #define ldargs pc0args 467596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 47908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 4812870Speter 4912870Speter /* as -J -t tmpdir -o objfile srcfile \0 */ 50908Sbill int asargx; 5112870Speter char *asargs[8] = { "as", 0, }; 52621Sbill 537766Smckusick char *mesg[] = { 547766Smckusick 0, 557766Smckusick "Hangup", 567766Smckusick "Interrupt", 577766Smckusick "Quit", 587766Smckusick "Illegal instruction", 597766Smckusick "Trace/BPT trap", 607766Smckusick "IOT trap", 617766Smckusick "EMT trap", 627766Smckusick "Floating exception", 637766Smckusick "Killed", 647766Smckusick "Bus error", 657766Smckusick "Segmentation fault", 667766Smckusick "Bad system call", 677766Smckusick "Broken pipe", 687766Smckusick "Alarm clock", 697766Smckusick "Terminated", 707766Smckusick "Signal 16", 717766Smckusick "Stopped (signal)", 727766Smckusick "Stopped", 737766Smckusick "Continued", 747766Smckusick "Child exited", 757766Smckusick "Stopped (tty input)", 767766Smckusick "Stopped (tty output)", 777766Smckusick "Tty input interrupt", 787766Smckusick "Cputime limit exceeded", 797766Smckusick "Filesize limit exceeded", 807766Smckusick "Signal 26", 817766Smckusick "Signal 27", 827766Smckusick "Signal 28", 837766Smckusick "Signal 29", 847766Smckusick "Signal 30", 857766Smckusick "Signal 31", 867766Smckusick "Signal 32" 877766Smckusick }; 887766Smckusick 89621Sbill /* 90621Sbill * If the number of .p arguments (np) is 1, and the number of .o arguments 91621Sbill * (nxo) is 0, and we successfully create an ``a.out'', then we remove 92621Sbill * the one .ps .o file (onepso). 93621Sbill */ 94621Sbill int np, nxo; 95621Sbill char *onepso; 96621Sbill int errs; 97621Sbill 98621Sbill int onintr(); 99621Sbill 100621Sbill main(argc, argv) 101621Sbill int argc; 102621Sbill char **argv; 103621Sbill { 104621Sbill register char *argp; 105621Sbill register int i; 106621Sbill int savargx; 107621Sbill char *t, c; 108621Sbill int j; 109621Sbill 110621Sbill argc--, argv++; 111621Sbill if (argc == 0) { 112621Sbill execl("/bin/cat", "cat", "/usr/lib/how_pc"); 113621Sbill exit(1); 114621Sbill } 115621Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 116621Sbill signal(SIGINT, onintr); 117621Sbill signal(SIGTERM, onintr); 118621Sbill } 119621Sbill for (i = 0; i < argc; i++) { 120621Sbill argp = argv[i]; 121621Sbill if (argp[0] != '-') 122621Sbill continue; 123621Sbill switch (argp[1]) { 124621Sbill 125621Sbill case 'd': 126621Sbill if (argp[2] == 0) 127621Sbill debug++; 128621Sbill continue; 129621Sbill case 'i': 130621Sbill pc0args[pc0argx++] = "-i"; 131621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 132621Sbill getsuf(argv[i+1]) != 'p') { 133621Sbill pc0args[pc0argx++] = argv[i+1]; 134621Sbill i++; 135621Sbill } 136621Sbill if (i+1 == argc) { 137621Sbill fprintf(stderr, "pc: bad -i construction\n"); 138621Sbill exit(1); 139621Sbill } 140621Sbill continue; 141621Sbill case 'o': 142621Sbill i++; 143621Sbill if (i == argc) { 144621Sbill fprintf(stderr, "pc: -o must specify file\n"); 145621Sbill exit(1); 146621Sbill } 147621Sbill c = getsuf(argv[i]); 148621Sbill if (c == 'o' || c == 'p' || c == 'c') { 149621Sbill fprintf(stderr, "pc: -o would overwrite %s\n", 150621Sbill argv[i]); 151621Sbill exit(1); 152621Sbill } 153621Sbill continue; 15412870Speter case 't': 15512870Speter i++; 15612870Speter if (i == argc) { 15712931Speter fprintf(stderr, "pc: -t but no directory\n"); 15812870Speter exit(1); 15912870Speter } 16012931Speter if (argp[2] != '\0') { 16112931Speter fprintf(stderr, "pc: bad -t option\n"); 16212931Speter exit(1); 16312931Speter } 16412870Speter tmpdir = argv[i]; 16512931Speter if (tmpdir[0] == '-') { 16612931Speter fprintf(stderr, "pc: bad -t option\n"); 16712931Speter exit(1); 16812931Speter } 16912870Speter tflag = 1; 17012870Speter continue; 171621Sbill case 'O': 172621Sbill Oflag = 1; 173621Sbill continue; 174621Sbill case 'S': 175621Sbill Sflag = 1; 176621Sbill continue; 177908Sbill case 'J': 178908Sbill Jflag = 1; 179908Sbill continue; 180621Sbill case 'T': 181621Sbill switch (argp[2]) { 182621Sbill 183621Sbill case '0': 18410721Smckusick pc0 = "/usr/src/ucb/pascal/pc0/a.out"; 1853862Smckusic if (argp[3] != '\0') { 1863862Smckusic pc0 = &argp[3]; 1873862Smckusic } 188621Sbill continue; 189621Sbill case '1': 1909140Smckusick pc1 = "/usr/src/lib/pcc/fort"; 1913862Smckusic if (argp[3] != '\0') { 1923862Smckusic pc1 = &argp[3]; 1933862Smckusic } 194621Sbill continue; 195621Sbill case '2': 19610721Smckusick pc2 = "/usr/src/ucb/pascal/utilities/pc2"; 1973862Smckusic if (argp[3] != '\0') { 1983862Smckusic pc2 = &argp[3]; 1993862Smckusic } 200621Sbill continue; 201621Sbill case '3': 20210721Smckusick pc3 = "/usr/src/ucb/pascal/utilities/pc3"; 2033862Smckusic if (argp[3] != '\0') { 2043862Smckusic pc3 = &argp[3]; 2053862Smckusic } 206621Sbill continue; 207621Sbill case 'l': 2085054Smckusic Tlflag = 1; 2099140Smckusick lpc = "/usr/src/usr.lib/libpc/libpc"; 2103862Smckusic if (argp[3] != '\0') { 2113862Smckusic lpc = &argp[3]; 2123862Smckusic } 213621Sbill continue; 214621Sbill } 215621Sbill continue; 216621Sbill case 'c': 217621Sbill cflag = 1; 218621Sbill continue; 219621Sbill case 'l': 220621Sbill if (argp[2]) 221621Sbill continue; 222621Sbill /* fall into ... */ 223621Sbill case 'b': 224621Sbill case 's': 225621Sbill case 'z': 226621Sbill case 'C': 227621Sbill pc0args[pc0argx++] = argp; 228621Sbill continue; 2297596Smckusick case 'w': 2307596Smckusick wflag = 1; 2317596Smckusick pc0args[pc0argx++] = argp; 2327596Smckusick continue; 2337596Smckusick case 'g': 2347596Smckusick gflag = 1; 2357596Smckusick pc0args[pc0argx++] = argp; 2367596Smckusick continue; 237621Sbill case 'p': 2385054Smckusic if (argp[2] == 'g') 2395054Smckusic crt0 = gcrt0; 2405054Smckusic else 2415054Smckusic crt0 = mcrt0; 2425054Smckusic if (!Tlflag) 2435054Smckusic lpc = "-lpc_p"; 2445054Smckusic pflag = 1; 245654Sbill continue; 246621Sbill } 247621Sbill } 248621Sbill if (gflag && Oflag) { 249621Sbill fprintf(stderr, "pc: warning: -g overrides -O\n"); 250621Sbill Oflag = 0; 251621Sbill } 25212870Speter sprintf(tmp0, "%s/%s", tmpdir, "p0XXXXXX"); 25312870Speter tname[0] = mktemp(tmp0); 25412870Speter sprintf(tmp1, "%s/%s", tmpdir, "p1XXXXXX"); 25512870Speter tname[1] = mktemp(tmp1); 256621Sbill savargx = pc0argx; 257621Sbill for (i = 0; i < argc; i++) { 258621Sbill argp = argv[i]; 259621Sbill if (argp[0] == '-') 260621Sbill continue; 2611211Speter if (suffix(argp) == 's') { 2621211Speter asargx = 1; 2631211Speter if (Jflag) 2641211Speter asargs[asargx++] = "-J"; 26512870Speter # ifdef vax 26612870Speter if (tflag) { 26712870Speter asargs[asargx++] = "-t"; 26812870Speter asargs[asargx++] = tmpdir; 26912870Speter } 27012870Speter # endif vax 2711211Speter asargs[asargx++] = argp; 2721211Speter asargs[asargx++] = "-o"; 2731211Speter tfile[1] = setsuf(argp, 'o'); 2741211Speter asargs[asargx++] = tfile[1]; 2751211Speter asargs[asargx] = 0; 2761211Speter if (dosys(as, asargs, 0, 0)) 2771211Speter continue; 2781211Speter tfile[1] = 0; 2791211Speter continue; 2801211Speter } 281621Sbill if (suffix(argp) != 'p') 282621Sbill continue; 283621Sbill tfile[0] = tname[0]; 284621Sbill pc0args[2] = tfile[0]; 285621Sbill pc0argx = savargx; 286654Sbill if (pflag) 287654Sbill pc0args[pc0argx++] = "-p"; 28812966Smckusick if (Jflag) 28912966Smckusick pc0args[pc0argx++] = "-J"; 290621Sbill pc0args[pc0argx++] = argp; 291621Sbill pc0args[pc0argx] = 0; 292621Sbill if (dosys(pc0, pc0args, 0, 0)) 293621Sbill continue; 294621Sbill pc1args[1] = tfile[0]; 295654Sbill tfile[1] = tname[1]; 296621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 297621Sbill continue; 298621Sbill unlink(tfile[0]); 2992340Smckusic tfile[0] = tname[0]; 3002340Smckusic if (Oflag) { 3012340Smckusic if (dosys(c2, c2args, tfile[1], tfile[0])) 3022340Smckusic continue; 3032340Smckusic unlink(tfile[1]); 3042340Smckusic tfile[1] = tfile[0]; 3052340Smckusic tfile[0] = tname[1]; 3062340Smckusic } 3072340Smckusic if (Sflag) 308654Sbill tfile[0] = setsuf(argp, 's'); 309621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 310621Sbill continue; 311621Sbill unlink(tfile[1]); 312621Sbill tfile[1] = 0; 313654Sbill if (Sflag) { 314654Sbill tfile[0] = 0; 315621Sbill continue; 316654Sbill } 317908Sbill asargx = 1; 318908Sbill if (Jflag) 319908Sbill asargs[asargx++] = "-J"; 32012870Speter # ifdef vax 32112870Speter if (tflag) { 32212870Speter asargs[asargx++] = "-t"; 32312870Speter asargs[asargx++] = tmpdir; 32412870Speter } 32512870Speter # endif vax 326908Sbill asargs[asargx++] = tfile[0]; 327908Sbill asargs[asargx++] = "-o"; 328621Sbill tfile[1] = setsuf(argp, 'o'); 329908Sbill asargs[asargx++] = tfile[1]; 330908Sbill asargs[asargx] = 0; 331621Sbill if (dosys(as, asargs, 0, 0)) 332621Sbill continue; 333621Sbill tfile[1] = 0; 334621Sbill remove(); 335621Sbill } 336621Sbill if (errs || cflag || Sflag) 337621Sbill done(); 3387596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 339621Sbill pc3args[0] = "pc3"; 3407596Smckusick if (wflag) 3417596Smckusick pc3args[pc3argx++] = "-w"; 3427596Smckusick pc3args[pc3argx++] = "/usr/lib/pcexterns.o"; 343621Sbill for (i = 0; i < argc; i++) { 344621Sbill argp = argv[i]; 345621Sbill if (!strcmp(argp, "-o")) 346621Sbill i++; 347621Sbill if (argp[0] == '-') 348621Sbill continue; 349621Sbill switch (getsuf(argp)) { 350621Sbill 351621Sbill case 'o': 352621Sbill pc3args[pc3argx++] = argp; 353621Sbill nxo++; 354621Sbill continue; 3551211Speter case 's': 356621Sbill case 'p': 357621Sbill onepso = pc3args[pc3argx++] = 358621Sbill savestr(setsuf(argp, 'o')); 359621Sbill np++; 360621Sbill continue; 361621Sbill } 362621Sbill } 363621Sbill pc3args[pc3argx] = 0; 3647596Smckusick if (dosys(pc3, pc3args, 0, 0) > 1) 365621Sbill done(); 36610672Speter errs = 0; 367908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 368621Sbill ldargs[0] = "ld"; 369621Sbill ldargs[1] = "-X"; 370654Sbill ldargs[2] = crt0; 371621Sbill for (i = 0; i < argc; i++) { 372621Sbill argp = argv[i]; 373621Sbill if (argp[0] != '-') { 374621Sbill switch (getsuf(argp)) { 375621Sbill 376621Sbill case 'p': 3771211Speter case 's': 378621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 379621Sbill break; 380621Sbill default: 381621Sbill ldargs[ldargx] = argp; 382621Sbill break; 383621Sbill } 384621Sbill if (getsuf(ldargs[ldargx]) == 'o') 385621Sbill for (j = 0; j < ldargx; j++) 386621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 387621Sbill goto duplicate; 388621Sbill ldargx++; 389621Sbill duplicate: 390621Sbill continue; 391621Sbill } 392621Sbill switch (argp[1]) { 393621Sbill 394621Sbill case 'i': 395621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 396621Sbill getsuf(argv[i+1]) != 'p') 397621Sbill i++; 398621Sbill continue; 399621Sbill case 'd': 400621Sbill if (argp[2] == 0) 401621Sbill continue; 402621Sbill ldargs[ldargx++] = argp; 403621Sbill continue; 404621Sbill case 'o': 405621Sbill ldargs[ldargx++] = argp; 406621Sbill i++; 407621Sbill ldargs[ldargx++] = argv[i]; 408621Sbill continue; 409621Sbill case 'l': 410621Sbill if (argp[2]) 411621Sbill ldargs[ldargx++] = argp; 412621Sbill continue; 41312870Speter case 't': 41412870Speter i++; 41512870Speter continue; 416621Sbill case 'c': 417621Sbill case 'g': 418621Sbill case 'w': 419621Sbill case 'p': 420621Sbill case 'S': 421908Sbill case 'J': 422621Sbill case 'T': 423621Sbill case 'O': 424621Sbill case 'C': 425621Sbill case 'b': 426621Sbill case 's': 427621Sbill case 'z': 428621Sbill continue; 429621Sbill default: 430621Sbill ldargs[ldargx++] = argp; 431621Sbill continue; 432621Sbill } 433621Sbill } 434621Sbill ldargs[ldargx++] = lpc; 435621Sbill if (gflag) 436621Sbill ldargs[ldargx++] = "-lg"; 4375054Smckusic if (pflag) { 4385054Smckusic ldargs[ldargx++] = "-lm_p"; 4395054Smckusic ldargs[ldargx++] = "-lc_p"; 4405054Smckusic } else { 4415054Smckusic ldargs[ldargx++] = "-lm"; 4425054Smckusic ldargs[ldargx++] = "-lc"; 4435054Smckusic } 444621Sbill ldargs[ldargx] = 0; 445621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 446621Sbill unlink(onepso); 447621Sbill done(); 448621Sbill } 449621Sbill 450621Sbill dosys(cmd, argv, in, out) 451621Sbill char *cmd, **argv, *in, *out; 452621Sbill { 453621Sbill union wait status; 454621Sbill int pid; 455621Sbill 456621Sbill if (debug) { 457621Sbill int i; 458621Sbill printf("%s:", cmd); 459621Sbill for (i = 0; argv[i]; i++) 460621Sbill printf(" %s", argv[i]); 461621Sbill if (in) 462621Sbill printf(" <%s", in); 463621Sbill if (out) 464621Sbill printf(" >%s", out); 465621Sbill printf("\n"); 466621Sbill } 467621Sbill pid = vfork(); 468621Sbill if (pid < 0) { 469621Sbill fprintf(stderr, "pc: No more processes\n"); 470621Sbill done(); 471621Sbill } 472621Sbill if (pid == 0) { 473621Sbill if (in) { 474621Sbill close(0); 475621Sbill if (open(in, 0) != 0) { 476621Sbill perror(in); 477621Sbill exit(1); 478621Sbill } 479621Sbill } 480621Sbill if (out) { 481621Sbill close(1); 482621Sbill unlink(out); 483621Sbill if (creat(out, 0666) != 1) { 484621Sbill perror(out); 485621Sbill exit(1); 486621Sbill } 487621Sbill } 488621Sbill signal(SIGINT, SIG_DFL); 489621Sbill execv(cmd, argv); 490621Sbill perror(cmd); 491621Sbill exit(1); 492621Sbill } 493621Sbill while (wait(&status) != pid) 494621Sbill ; 495621Sbill if (WIFSIGNALED(status)) { 4967766Smckusick if (status.w_termsig != SIGINT) { 4977766Smckusick fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 4987766Smckusick if (status.w_coredump) 4997766Smckusick fprintf(stderr, " (core dumped)"); 5007766Smckusick fprintf(stderr, "\n"); 5017766Smckusick } 502621Sbill errs = 100; 503621Sbill done(); 504621Sbill /*NOTREACHED*/ 505621Sbill } 506621Sbill if (status.w_retcode) { 507621Sbill errs = 1; 508621Sbill remove(); 509621Sbill } 510621Sbill return (status.w_retcode); 511621Sbill } 512621Sbill 513621Sbill done() 514621Sbill { 515621Sbill 516621Sbill remove(); 517621Sbill exit(errs); 518621Sbill } 519621Sbill 520621Sbill remove() 521621Sbill { 522621Sbill 523621Sbill if (tfile[0]) 524621Sbill unlink(tfile[0]); 525621Sbill if (tfile[1]) 526621Sbill unlink(tfile[1]); 527621Sbill } 528621Sbill 529621Sbill onintr() 530621Sbill { 531621Sbill 532621Sbill errs = 1; 533621Sbill done(); 534621Sbill } 535621Sbill 536621Sbill getsuf(cp) 537621Sbill char *cp; 538621Sbill { 539621Sbill 540621Sbill if (*cp == 0) 541621Sbill return; 542621Sbill while (cp[1]) 543621Sbill cp++; 544621Sbill if (cp[-1] != '.') 545621Sbill return (0); 546621Sbill return (*cp); 547621Sbill } 548621Sbill 549621Sbill char * 550654Sbill setsuf(as, ch) 551654Sbill char *as; 552621Sbill { 553654Sbill register char *s, *s1; 554621Sbill 555654Sbill s = s1 = savestr(as); 556654Sbill while (*s) 557654Sbill if (*s++ == '/') 558654Sbill s1 = s; 559654Sbill s[-1] = ch; 560654Sbill return (s1); 561621Sbill } 562621Sbill 563621Sbill #define NSAVETAB 512 564621Sbill char *savetab; 565621Sbill int saveleft; 566621Sbill 567621Sbill char * 568621Sbill savestr(cp) 569621Sbill register char *cp; 570621Sbill { 571621Sbill register int len; 572621Sbill 573621Sbill len = strlen(cp) + 1; 574621Sbill if (len > saveleft) { 575621Sbill saveleft = NSAVETAB; 576621Sbill if (len > saveleft) 577621Sbill saveleft = len; 578621Sbill savetab = (char *)malloc(saveleft); 579621Sbill if (savetab == 0) { 580621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 581621Sbill exit(1); 582621Sbill } 583621Sbill } 584621Sbill strncpy(savetab, cp, len); 585621Sbill cp = savetab; 586621Sbill savetab += len; 587621Sbill return (cp); 588621Sbill } 589621Sbill 590621Sbill suffix(cp) 591621Sbill char *cp; 592621Sbill { 593621Sbill 594621Sbill if (cp[0] == 0 || cp[1] == 0) 595621Sbill return (0); 596621Sbill while (cp[1]) 597621Sbill cp++; 598621Sbill if (cp[-1] == '.') 599621Sbill return (*cp); 600621Sbill return (0); 601621Sbill } 602