1*12870Speter static char sccsid[] = "@(#)pc.c 3.22 06/01/83"; 25054Smckusic 3621Sbill #include <stdio.h> 4621Sbill #include <signal.h> 5621Sbill #include <wait.h> 6*12870Speter #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(); 24*12870Speter char *tmpdir = "/tmp"; 25*12870Speter char tmp0[MAXPATHLEN], tmp1[MAXPATHLEN]; 26621Sbill char *tname[2]; 27621Sbill char *tfile[2]; 28621Sbill 29621Sbill char *setsuf(), *savestr(); 30621Sbill 31*12870Speter 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, }; */ 46*12870Speter 47*12870Speter /* as -J -t tmpdir -o objfile srcfile \0 */ 48908Sbill int asargx; 49*12870Speter 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; 152*12870Speter case 't': 153*12870Speter i++; 154*12870Speter if (i == argc) { 155*12870Speter fprintf(stderr, "pc: -T but no directory\n"); 156*12870Speter exit(1); 157*12870Speter } 158*12870Speter tmpdir = argv[i]; 159*12870Speter tflag = 1; 160*12870Speter continue; 161621Sbill case 'O': 162621Sbill Oflag = 1; 163621Sbill continue; 164621Sbill case 'S': 165621Sbill Sflag = 1; 166621Sbill continue; 167908Sbill case 'J': 168908Sbill Jflag = 1; 169908Sbill continue; 170621Sbill case 'T': 171621Sbill switch (argp[2]) { 172621Sbill 173621Sbill case '0': 17410721Smckusick pc0 = "/usr/src/ucb/pascal/pc0/a.out"; 1753862Smckusic if (argp[3] != '\0') { 1763862Smckusic pc0 = &argp[3]; 1773862Smckusic } 178621Sbill continue; 179621Sbill case '1': 1809140Smckusick pc1 = "/usr/src/lib/pcc/fort"; 1813862Smckusic if (argp[3] != '\0') { 1823862Smckusic pc1 = &argp[3]; 1833862Smckusic } 184621Sbill continue; 185621Sbill case '2': 18610721Smckusick pc2 = "/usr/src/ucb/pascal/utilities/pc2"; 1873862Smckusic if (argp[3] != '\0') { 1883862Smckusic pc2 = &argp[3]; 1893862Smckusic } 190621Sbill continue; 191621Sbill case '3': 19210721Smckusick pc3 = "/usr/src/ucb/pascal/utilities/pc3"; 1933862Smckusic if (argp[3] != '\0') { 1943862Smckusic pc3 = &argp[3]; 1953862Smckusic } 196621Sbill continue; 197621Sbill case 'l': 1985054Smckusic Tlflag = 1; 1999140Smckusick lpc = "/usr/src/usr.lib/libpc/libpc"; 2003862Smckusic if (argp[3] != '\0') { 2013862Smckusic lpc = &argp[3]; 2023862Smckusic } 203621Sbill continue; 204621Sbill } 205621Sbill continue; 206621Sbill case 'c': 207621Sbill cflag = 1; 208621Sbill continue; 209621Sbill case 'l': 210621Sbill if (argp[2]) 211621Sbill continue; 212621Sbill /* fall into ... */ 213621Sbill case 'b': 214621Sbill case 's': 215621Sbill case 'z': 216621Sbill case 'C': 217621Sbill pc0args[pc0argx++] = argp; 218621Sbill continue; 2197596Smckusick case 'w': 2207596Smckusick wflag = 1; 2217596Smckusick pc0args[pc0argx++] = argp; 2227596Smckusick continue; 2237596Smckusick case 'g': 2247596Smckusick gflag = 1; 2257596Smckusick pc0args[pc0argx++] = argp; 2267596Smckusick continue; 227621Sbill case 'p': 2285054Smckusic if (argp[2] == 'g') 2295054Smckusic crt0 = gcrt0; 2305054Smckusic else 2315054Smckusic crt0 = mcrt0; 2325054Smckusic if (!Tlflag) 2335054Smckusic lpc = "-lpc_p"; 2345054Smckusic pflag = 1; 235654Sbill continue; 236621Sbill } 237621Sbill } 238621Sbill if (gflag && Oflag) { 239621Sbill fprintf(stderr, "pc: warning: -g overrides -O\n"); 240621Sbill Oflag = 0; 241621Sbill } 242*12870Speter sprintf(tmp0, "%s/%s", tmpdir, "p0XXXXXX"); 243*12870Speter tname[0] = mktemp(tmp0); 244*12870Speter sprintf(tmp1, "%s/%s", tmpdir, "p1XXXXXX"); 245*12870Speter tname[1] = mktemp(tmp1); 246621Sbill savargx = pc0argx; 247621Sbill for (i = 0; i < argc; i++) { 248621Sbill argp = argv[i]; 249621Sbill if (argp[0] == '-') 250621Sbill continue; 2511211Speter if (suffix(argp) == 's') { 2521211Speter asargx = 1; 2531211Speter if (Jflag) 2541211Speter asargs[asargx++] = "-J"; 255*12870Speter # ifdef vax 256*12870Speter if (tflag) { 257*12870Speter asargs[asargx++] = "-t"; 258*12870Speter asargs[asargx++] = tmpdir; 259*12870Speter } 260*12870Speter # endif vax 2611211Speter asargs[asargx++] = argp; 2621211Speter asargs[asargx++] = "-o"; 2631211Speter tfile[1] = setsuf(argp, 'o'); 2641211Speter asargs[asargx++] = tfile[1]; 2651211Speter asargs[asargx] = 0; 2661211Speter if (dosys(as, asargs, 0, 0)) 2671211Speter continue; 2681211Speter tfile[1] = 0; 2691211Speter continue; 2701211Speter } 271621Sbill if (suffix(argp) != 'p') 272621Sbill continue; 273621Sbill tfile[0] = tname[0]; 274621Sbill pc0args[2] = tfile[0]; 275621Sbill pc0argx = savargx; 276654Sbill if (pflag) 277654Sbill pc0args[pc0argx++] = "-p"; 278621Sbill pc0args[pc0argx++] = argp; 279621Sbill pc0args[pc0argx] = 0; 280621Sbill if (dosys(pc0, pc0args, 0, 0)) 281621Sbill continue; 282621Sbill pc1args[1] = tfile[0]; 283654Sbill tfile[1] = tname[1]; 284621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 285621Sbill continue; 286621Sbill unlink(tfile[0]); 2872340Smckusic tfile[0] = tname[0]; 2882340Smckusic if (Oflag) { 2892340Smckusic if (dosys(c2, c2args, tfile[1], tfile[0])) 2902340Smckusic continue; 2912340Smckusic unlink(tfile[1]); 2922340Smckusic tfile[1] = tfile[0]; 2932340Smckusic tfile[0] = tname[1]; 2942340Smckusic } 2952340Smckusic if (Sflag) 296654Sbill tfile[0] = setsuf(argp, 's'); 297621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 298621Sbill continue; 299621Sbill unlink(tfile[1]); 300621Sbill tfile[1] = 0; 301654Sbill if (Sflag) { 302654Sbill tfile[0] = 0; 303621Sbill continue; 304654Sbill } 305908Sbill asargx = 1; 306908Sbill if (Jflag) 307908Sbill asargs[asargx++] = "-J"; 308*12870Speter # ifdef vax 309*12870Speter if (tflag) { 310*12870Speter asargs[asargx++] = "-t"; 311*12870Speter asargs[asargx++] = tmpdir; 312*12870Speter } 313*12870Speter # endif vax 314908Sbill asargs[asargx++] = tfile[0]; 315908Sbill asargs[asargx++] = "-o"; 316621Sbill tfile[1] = setsuf(argp, 'o'); 317908Sbill asargs[asargx++] = tfile[1]; 318908Sbill asargs[asargx] = 0; 319621Sbill if (dosys(as, asargs, 0, 0)) 320621Sbill continue; 321621Sbill tfile[1] = 0; 322621Sbill remove(); 323621Sbill } 324621Sbill if (errs || cflag || Sflag) 325621Sbill done(); 3267596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 327621Sbill pc3args[0] = "pc3"; 3287596Smckusick if (wflag) 3297596Smckusick pc3args[pc3argx++] = "-w"; 3307596Smckusick pc3args[pc3argx++] = "/usr/lib/pcexterns.o"; 331621Sbill for (i = 0; i < argc; i++) { 332621Sbill argp = argv[i]; 333621Sbill if (!strcmp(argp, "-o")) 334621Sbill i++; 335621Sbill if (argp[0] == '-') 336621Sbill continue; 337621Sbill switch (getsuf(argp)) { 338621Sbill 339621Sbill case 'o': 340621Sbill pc3args[pc3argx++] = argp; 341621Sbill nxo++; 342621Sbill continue; 3431211Speter case 's': 344621Sbill case 'p': 345621Sbill onepso = pc3args[pc3argx++] = 346621Sbill savestr(setsuf(argp, 'o')); 347621Sbill np++; 348621Sbill continue; 349621Sbill } 350621Sbill } 351621Sbill pc3args[pc3argx] = 0; 3527596Smckusick if (dosys(pc3, pc3args, 0, 0) > 1) 353621Sbill done(); 35410672Speter errs = 0; 355908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 356621Sbill ldargs[0] = "ld"; 357621Sbill ldargs[1] = "-X"; 358654Sbill ldargs[2] = crt0; 359621Sbill for (i = 0; i < argc; i++) { 360621Sbill argp = argv[i]; 361621Sbill if (argp[0] != '-') { 362621Sbill switch (getsuf(argp)) { 363621Sbill 364621Sbill case 'p': 3651211Speter case 's': 366621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 367621Sbill break; 368621Sbill default: 369621Sbill ldargs[ldargx] = argp; 370621Sbill break; 371621Sbill } 372621Sbill if (getsuf(ldargs[ldargx]) == 'o') 373621Sbill for (j = 0; j < ldargx; j++) 374621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 375621Sbill goto duplicate; 376621Sbill ldargx++; 377621Sbill duplicate: 378621Sbill continue; 379621Sbill } 380621Sbill switch (argp[1]) { 381621Sbill 382621Sbill case 'i': 383621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 384621Sbill getsuf(argv[i+1]) != 'p') 385621Sbill i++; 386621Sbill continue; 387621Sbill case 'd': 388621Sbill if (argp[2] == 0) 389621Sbill continue; 390621Sbill ldargs[ldargx++] = argp; 391621Sbill continue; 392621Sbill case 'o': 393621Sbill ldargs[ldargx++] = argp; 394621Sbill i++; 395621Sbill ldargs[ldargx++] = argv[i]; 396621Sbill continue; 397621Sbill case 'l': 398621Sbill if (argp[2]) 399621Sbill ldargs[ldargx++] = argp; 400621Sbill continue; 401*12870Speter case 't': 402*12870Speter i++; 403*12870Speter continue; 404621Sbill case 'c': 405621Sbill case 'g': 406621Sbill case 'w': 407621Sbill case 'p': 408621Sbill case 'S': 409908Sbill case 'J': 410621Sbill case 'T': 411621Sbill case 'O': 412621Sbill case 'C': 413621Sbill case 'b': 414621Sbill case 's': 415621Sbill case 'z': 416621Sbill continue; 417621Sbill default: 418621Sbill ldargs[ldargx++] = argp; 419621Sbill continue; 420621Sbill } 421621Sbill } 422621Sbill ldargs[ldargx++] = lpc; 423621Sbill if (gflag) 424621Sbill ldargs[ldargx++] = "-lg"; 4255054Smckusic if (pflag) { 4265054Smckusic ldargs[ldargx++] = "-lm_p"; 4275054Smckusic ldargs[ldargx++] = "-lc_p"; 4285054Smckusic } else { 4295054Smckusic ldargs[ldargx++] = "-lm"; 4305054Smckusic ldargs[ldargx++] = "-lc"; 4315054Smckusic } 432621Sbill ldargs[ldargx] = 0; 433621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 434621Sbill unlink(onepso); 435621Sbill done(); 436621Sbill } 437621Sbill 438621Sbill dosys(cmd, argv, in, out) 439621Sbill char *cmd, **argv, *in, *out; 440621Sbill { 441621Sbill union wait status; 442621Sbill int pid; 443621Sbill 444621Sbill if (debug) { 445621Sbill int i; 446621Sbill printf("%s:", cmd); 447621Sbill for (i = 0; argv[i]; i++) 448621Sbill printf(" %s", argv[i]); 449621Sbill if (in) 450621Sbill printf(" <%s", in); 451621Sbill if (out) 452621Sbill printf(" >%s", out); 453621Sbill printf("\n"); 454621Sbill } 455621Sbill pid = vfork(); 456621Sbill if (pid < 0) { 457621Sbill fprintf(stderr, "pc: No more processes\n"); 458621Sbill done(); 459621Sbill } 460621Sbill if (pid == 0) { 461621Sbill if (in) { 462621Sbill close(0); 463621Sbill if (open(in, 0) != 0) { 464621Sbill perror(in); 465621Sbill exit(1); 466621Sbill } 467621Sbill } 468621Sbill if (out) { 469621Sbill close(1); 470621Sbill unlink(out); 471621Sbill if (creat(out, 0666) != 1) { 472621Sbill perror(out); 473621Sbill exit(1); 474621Sbill } 475621Sbill } 476621Sbill signal(SIGINT, SIG_DFL); 477621Sbill execv(cmd, argv); 478621Sbill perror(cmd); 479621Sbill exit(1); 480621Sbill } 481621Sbill while (wait(&status) != pid) 482621Sbill ; 483621Sbill if (WIFSIGNALED(status)) { 4847766Smckusick if (status.w_termsig != SIGINT) { 4857766Smckusick fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 4867766Smckusick if (status.w_coredump) 4877766Smckusick fprintf(stderr, " (core dumped)"); 4887766Smckusick fprintf(stderr, "\n"); 4897766Smckusick } 490621Sbill errs = 100; 491621Sbill done(); 492621Sbill /*NOTREACHED*/ 493621Sbill } 494621Sbill if (status.w_retcode) { 495621Sbill errs = 1; 496621Sbill remove(); 497621Sbill } 498621Sbill return (status.w_retcode); 499621Sbill } 500621Sbill 501621Sbill done() 502621Sbill { 503621Sbill 504621Sbill remove(); 505621Sbill exit(errs); 506621Sbill } 507621Sbill 508621Sbill remove() 509621Sbill { 510621Sbill 511621Sbill if (tfile[0]) 512621Sbill unlink(tfile[0]); 513621Sbill if (tfile[1]) 514621Sbill unlink(tfile[1]); 515621Sbill } 516621Sbill 517621Sbill onintr() 518621Sbill { 519621Sbill 520621Sbill errs = 1; 521621Sbill done(); 522621Sbill } 523621Sbill 524621Sbill getsuf(cp) 525621Sbill char *cp; 526621Sbill { 527621Sbill 528621Sbill if (*cp == 0) 529621Sbill return; 530621Sbill while (cp[1]) 531621Sbill cp++; 532621Sbill if (cp[-1] != '.') 533621Sbill return (0); 534621Sbill return (*cp); 535621Sbill } 536621Sbill 537621Sbill char * 538654Sbill setsuf(as, ch) 539654Sbill char *as; 540621Sbill { 541654Sbill register char *s, *s1; 542621Sbill 543654Sbill s = s1 = savestr(as); 544654Sbill while (*s) 545654Sbill if (*s++ == '/') 546654Sbill s1 = s; 547654Sbill s[-1] = ch; 548654Sbill return (s1); 549621Sbill } 550621Sbill 551621Sbill #define NSAVETAB 512 552621Sbill char *savetab; 553621Sbill int saveleft; 554621Sbill 555621Sbill char * 556621Sbill savestr(cp) 557621Sbill register char *cp; 558621Sbill { 559621Sbill register int len; 560621Sbill 561621Sbill len = strlen(cp) + 1; 562621Sbill if (len > saveleft) { 563621Sbill saveleft = NSAVETAB; 564621Sbill if (len > saveleft) 565621Sbill saveleft = len; 566621Sbill savetab = (char *)malloc(saveleft); 567621Sbill if (savetab == 0) { 568621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 569621Sbill exit(1); 570621Sbill } 571621Sbill } 572621Sbill strncpy(savetab, cp, len); 573621Sbill cp = savetab; 574621Sbill savetab += len; 575621Sbill return (cp); 576621Sbill } 577621Sbill 578621Sbill suffix(cp) 579621Sbill char *cp; 580621Sbill { 581621Sbill 582621Sbill if (cp[0] == 0 || cp[1] == 0) 583621Sbill return (0); 584621Sbill while (cp[1]) 585621Sbill cp++; 586621Sbill if (cp[-1] == '.') 587621Sbill return (*cp); 588621Sbill return (0); 589621Sbill } 590