1*9140Smckusick static char sccsid[] = "@(#)pc.c 3.17 11/12/82"; 25054Smckusic 3621Sbill #include <stdio.h> 4621Sbill #include <signal.h> 5621Sbill #include <wait.h> 6621Sbill 7621Sbill /* 8654Sbill * Pc - front end for Pascal compiler. 9621Sbill */ 10908Sbill char *pc0 = "/usr/lib/pc0"; 11908Sbill char *pc1 = "/lib/f1"; 12908Sbill char *pc2 = "/usr/lib/pc2"; 13908Sbill char *c2 = "/lib/c2"; 14908Sbill char *pc3 = "/usr/lib/pc3"; 15908Sbill char *ld = "/bin/ld"; 16908Sbill char *as = "/bin/as"; 17621Sbill char *lpc = "-lpc"; 18908Sbill char *crt0 = "/lib/crt0.o"; 19908Sbill char *mcrt0 = "/lib/mcrt0.o"; 205054Smckusic char *gcrt0 = "/usr/lib/gcrt0.o"; 21621Sbill 22621Sbill char *mktemp(); 23621Sbill char *tname[2]; 24621Sbill char *tfile[2]; 25621Sbill 26621Sbill char *setsuf(), *savestr(); 27621Sbill 287596Smckusick int Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag, wflag; 29621Sbill int debug; 30621Sbill 31621Sbill #define NARGS 512 32621Sbill int ldargx = 3; 33621Sbill int pc0argx = 3; 34621Sbill char *pc0args[NARGS] = { "pc0", "-o", "XXX" }; 35621Sbill char *pc1args[3] = { "pc1", 0, }; 36621Sbill char *pc2args[2] = { "pc2", 0 }; 37621Sbill char *c2args[4] = { "c2", 0, 0, 0 }; 387596Smckusick int pc3argx = 1; 39621Sbill #define pc3args pc0args 40621Sbill #define ldargs pc0args 417596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 42908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 43908Sbill int asargx; 44908Sbill char *asargs[6] = { "as", 0, }; 45621Sbill 467766Smckusick char *mesg[] = { 477766Smckusick 0, 487766Smckusick "Hangup", 497766Smckusick "Interrupt", 507766Smckusick "Quit", 517766Smckusick "Illegal instruction", 527766Smckusick "Trace/BPT trap", 537766Smckusick "IOT trap", 547766Smckusick "EMT trap", 557766Smckusick "Floating exception", 567766Smckusick "Killed", 577766Smckusick "Bus error", 587766Smckusick "Segmentation fault", 597766Smckusick "Bad system call", 607766Smckusick "Broken pipe", 617766Smckusick "Alarm clock", 627766Smckusick "Terminated", 637766Smckusick "Signal 16", 647766Smckusick "Stopped (signal)", 657766Smckusick "Stopped", 667766Smckusick "Continued", 677766Smckusick "Child exited", 687766Smckusick "Stopped (tty input)", 697766Smckusick "Stopped (tty output)", 707766Smckusick "Tty input interrupt", 717766Smckusick "Cputime limit exceeded", 727766Smckusick "Filesize limit exceeded", 737766Smckusick "Signal 26", 747766Smckusick "Signal 27", 757766Smckusick "Signal 28", 767766Smckusick "Signal 29", 777766Smckusick "Signal 30", 787766Smckusick "Signal 31", 797766Smckusick "Signal 32" 807766Smckusick }; 817766Smckusick 82621Sbill /* 83621Sbill * If the number of .p arguments (np) is 1, and the number of .o arguments 84621Sbill * (nxo) is 0, and we successfully create an ``a.out'', then we remove 85621Sbill * the one .ps .o file (onepso). 86621Sbill */ 87621Sbill int np, nxo; 88621Sbill char *onepso; 89621Sbill int errs; 90621Sbill 91621Sbill int onintr(); 92621Sbill 93621Sbill main(argc, argv) 94621Sbill int argc; 95621Sbill char **argv; 96621Sbill { 97621Sbill register char *argp; 98621Sbill register int i; 99621Sbill int savargx; 100621Sbill char *t, c; 101621Sbill int j; 102621Sbill 103621Sbill argc--, argv++; 104621Sbill if (argc == 0) { 105621Sbill execl("/bin/cat", "cat", "/usr/lib/how_pc"); 106621Sbill exit(1); 107621Sbill } 108621Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 109621Sbill signal(SIGINT, onintr); 110621Sbill signal(SIGTERM, onintr); 111621Sbill } 112621Sbill for (i = 0; i < argc; i++) { 113621Sbill argp = argv[i]; 114621Sbill if (argp[0] != '-') 115621Sbill continue; 116621Sbill switch (argp[1]) { 117621Sbill 118621Sbill case 'd': 119621Sbill if (argp[2] == 0) 120621Sbill debug++; 121621Sbill continue; 122621Sbill case 'i': 123621Sbill pc0args[pc0argx++] = "-i"; 124621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 125621Sbill getsuf(argv[i+1]) != 'p') { 126621Sbill pc0args[pc0argx++] = argv[i+1]; 127621Sbill i++; 128621Sbill } 129621Sbill if (i+1 == argc) { 130621Sbill fprintf(stderr, "pc: bad -i construction\n"); 131621Sbill exit(1); 132621Sbill } 133621Sbill continue; 134621Sbill case 'o': 135621Sbill i++; 136621Sbill if (i == argc) { 137621Sbill fprintf(stderr, "pc: -o must specify file\n"); 138621Sbill exit(1); 139621Sbill } 140621Sbill c = getsuf(argv[i]); 141621Sbill if (c == 'o' || c == 'p' || c == 'c') { 142621Sbill fprintf(stderr, "pc: -o would overwrite %s\n", 143621Sbill argv[i]); 144621Sbill exit(1); 145621Sbill } 146621Sbill continue; 147621Sbill case 'O': 148621Sbill Oflag = 1; 149621Sbill continue; 150621Sbill case 'S': 151621Sbill Sflag = 1; 152621Sbill continue; 153908Sbill case 'J': 154908Sbill Jflag = 1; 155908Sbill continue; 156621Sbill case 'T': 157621Sbill switch (argp[2]) { 158621Sbill 159621Sbill case '0': 160*9140Smckusick pc0 = "/usr/src/ucb/pc0/a.out"; 1613862Smckusic if (argp[3] != '\0') { 1623862Smckusic pc0 = &argp[3]; 1633862Smckusic } 164621Sbill continue; 165621Sbill case '1': 166*9140Smckusick pc1 = "/usr/src/lib/pcc/fort"; 1673862Smckusic if (argp[3] != '\0') { 1683862Smckusic pc1 = &argp[3]; 1693862Smckusic } 170621Sbill continue; 171621Sbill case '2': 172*9140Smckusick pc2 = "/usr/src/ucb/pascal/pc2"; 1733862Smckusic if (argp[3] != '\0') { 1743862Smckusic pc2 = &argp[3]; 1753862Smckusic } 176621Sbill continue; 177621Sbill case '3': 178*9140Smckusick pc3 = "/usr/src/ucb/pascal/pc3"; 1793862Smckusic if (argp[3] != '\0') { 1803862Smckusic pc3 = &argp[3]; 1813862Smckusic } 182621Sbill continue; 183621Sbill case 'l': 1845054Smckusic Tlflag = 1; 185*9140Smckusick lpc = "/usr/src/usr.lib/libpc/libpc"; 1863862Smckusic if (argp[3] != '\0') { 1873862Smckusic lpc = &argp[3]; 1883862Smckusic } 189621Sbill continue; 190621Sbill } 191621Sbill continue; 192621Sbill case 'c': 193621Sbill cflag = 1; 194621Sbill continue; 195621Sbill case 'l': 196621Sbill if (argp[2]) 197621Sbill continue; 198621Sbill /* fall into ... */ 199621Sbill case 'b': 200621Sbill case 's': 201621Sbill case 'z': 202621Sbill case 'C': 203621Sbill pc0args[pc0argx++] = argp; 204621Sbill continue; 2057596Smckusick case 'w': 2067596Smckusick wflag = 1; 2077596Smckusick pc0args[pc0argx++] = argp; 2087596Smckusick continue; 2097596Smckusick case 'g': 2107596Smckusick gflag = 1; 2117596Smckusick pc0args[pc0argx++] = argp; 2127596Smckusick continue; 213621Sbill case 't': 214621Sbill fprintf(stderr, "pc: -t is default; -C for checking\n"); 215621Sbill continue; 216621Sbill case 'p': 2175054Smckusic if (argp[2] == 'g') 2185054Smckusic crt0 = gcrt0; 2195054Smckusic else 2205054Smckusic crt0 = mcrt0; 2215054Smckusic if (!Tlflag) 2225054Smckusic lpc = "-lpc_p"; 2235054Smckusic pflag = 1; 224654Sbill continue; 225621Sbill } 226621Sbill } 227621Sbill if (gflag && Oflag) { 228621Sbill fprintf(stderr, "pc: warning: -g overrides -O\n"); 229621Sbill Oflag = 0; 230621Sbill } 231621Sbill tname[0] = mktemp("/tmp/p0XXXXXX"); 232621Sbill tname[1] = mktemp("/tmp/p1XXXXXX"); 233621Sbill savargx = pc0argx; 234621Sbill for (i = 0; i < argc; i++) { 235621Sbill argp = argv[i]; 236621Sbill if (argp[0] == '-') 237621Sbill continue; 2381211Speter if (suffix(argp) == 's') { 2391211Speter asargx = 1; 2401211Speter if (Jflag) 2411211Speter asargs[asargx++] = "-J"; 2421211Speter asargs[asargx++] = argp; 2431211Speter asargs[asargx++] = "-o"; 2441211Speter tfile[1] = setsuf(argp, 'o'); 2451211Speter asargs[asargx++] = tfile[1]; 2461211Speter asargs[asargx] = 0; 2471211Speter if (dosys(as, asargs, 0, 0)) 2481211Speter continue; 2491211Speter tfile[1] = 0; 2501211Speter continue; 2511211Speter } 252621Sbill if (suffix(argp) != 'p') 253621Sbill continue; 254621Sbill tfile[0] = tname[0]; 255621Sbill pc0args[2] = tfile[0]; 256621Sbill pc0argx = savargx; 257654Sbill if (pflag) 258654Sbill pc0args[pc0argx++] = "-p"; 259621Sbill pc0args[pc0argx++] = argp; 260621Sbill pc0args[pc0argx] = 0; 261621Sbill if (dosys(pc0, pc0args, 0, 0)) 262621Sbill continue; 263621Sbill pc1args[1] = tfile[0]; 264654Sbill tfile[1] = tname[1]; 265621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 266621Sbill continue; 267621Sbill unlink(tfile[0]); 2682340Smckusic tfile[0] = tname[0]; 2692340Smckusic if (Oflag) { 2702340Smckusic if (dosys(c2, c2args, tfile[1], tfile[0])) 2712340Smckusic continue; 2722340Smckusic unlink(tfile[1]); 2732340Smckusic tfile[1] = tfile[0]; 2742340Smckusic tfile[0] = tname[1]; 2752340Smckusic } 2762340Smckusic if (Sflag) 277654Sbill tfile[0] = setsuf(argp, 's'); 278621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 279621Sbill continue; 280621Sbill unlink(tfile[1]); 281621Sbill tfile[1] = 0; 282654Sbill if (Sflag) { 283654Sbill tfile[0] = 0; 284621Sbill continue; 285654Sbill } 286908Sbill asargx = 1; 287908Sbill if (Jflag) 288908Sbill asargs[asargx++] = "-J"; 289908Sbill asargs[asargx++] = tfile[0]; 290908Sbill asargs[asargx++] = "-o"; 291621Sbill tfile[1] = setsuf(argp, 'o'); 292908Sbill asargs[asargx++] = tfile[1]; 293908Sbill asargs[asargx] = 0; 294621Sbill if (dosys(as, asargs, 0, 0)) 295621Sbill continue; 296621Sbill tfile[1] = 0; 297621Sbill remove(); 298621Sbill } 299621Sbill if (errs || cflag || Sflag) 300621Sbill done(); 3017596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 302621Sbill pc3args[0] = "pc3"; 3037596Smckusick if (wflag) 3047596Smckusick pc3args[pc3argx++] = "-w"; 3057596Smckusick pc3args[pc3argx++] = "/usr/lib/pcexterns.o"; 306621Sbill for (i = 0; i < argc; i++) { 307621Sbill argp = argv[i]; 308621Sbill if (!strcmp(argp, "-o")) 309621Sbill i++; 310621Sbill if (argp[0] == '-') 311621Sbill continue; 312621Sbill switch (getsuf(argp)) { 313621Sbill 314621Sbill case 'o': 315621Sbill pc3args[pc3argx++] = argp; 316621Sbill nxo++; 317621Sbill continue; 3181211Speter case 's': 319621Sbill case 'p': 320621Sbill onepso = pc3args[pc3argx++] = 321621Sbill savestr(setsuf(argp, 'o')); 322621Sbill np++; 323621Sbill continue; 324621Sbill } 325621Sbill } 326621Sbill pc3args[pc3argx] = 0; 3277596Smckusick if (dosys(pc3, pc3args, 0, 0) > 1) 328621Sbill done(); 329908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 330621Sbill ldargs[0] = "ld"; 331621Sbill ldargs[1] = "-X"; 332654Sbill ldargs[2] = crt0; 333621Sbill for (i = 0; i < argc; i++) { 334621Sbill argp = argv[i]; 335621Sbill if (argp[0] != '-') { 336621Sbill switch (getsuf(argp)) { 337621Sbill 338621Sbill case 'p': 3391211Speter case 's': 340621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 341621Sbill break; 342621Sbill default: 343621Sbill ldargs[ldargx] = argp; 344621Sbill break; 345621Sbill } 346621Sbill if (getsuf(ldargs[ldargx]) == 'o') 347621Sbill for (j = 0; j < ldargx; j++) 348621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 349621Sbill goto duplicate; 350621Sbill ldargx++; 351621Sbill duplicate: 352621Sbill continue; 353621Sbill } 354621Sbill switch (argp[1]) { 355621Sbill 356621Sbill case 'i': 357621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 358621Sbill getsuf(argv[i+1]) != 'p') 359621Sbill i++; 360621Sbill continue; 361621Sbill case 'd': 362621Sbill if (argp[2] == 0) 363621Sbill continue; 364621Sbill ldargs[ldargx++] = argp; 365621Sbill continue; 366621Sbill case 'o': 367621Sbill ldargs[ldargx++] = argp; 368621Sbill i++; 369621Sbill ldargs[ldargx++] = argv[i]; 370621Sbill continue; 371621Sbill case 'l': 372621Sbill if (argp[2]) 373621Sbill ldargs[ldargx++] = argp; 374621Sbill continue; 375621Sbill case 'c': 376621Sbill case 'g': 377621Sbill case 'w': 378621Sbill case 'p': 379621Sbill case 'S': 380908Sbill case 'J': 381621Sbill case 'T': 382621Sbill case 'O': 383621Sbill case 'C': 384621Sbill case 'b': 385621Sbill case 's': 386621Sbill case 'z': 387621Sbill continue; 388621Sbill default: 389621Sbill ldargs[ldargx++] = argp; 390621Sbill continue; 391621Sbill } 392621Sbill } 393621Sbill ldargs[ldargx++] = lpc; 394621Sbill if (gflag) 395621Sbill ldargs[ldargx++] = "-lg"; 3965054Smckusic if (pflag) { 3975054Smckusic ldargs[ldargx++] = "-lm_p"; 3985054Smckusic ldargs[ldargx++] = "-lc_p"; 3995054Smckusic } else { 4005054Smckusic ldargs[ldargx++] = "-lm"; 4015054Smckusic ldargs[ldargx++] = "-lc"; 4025054Smckusic } 403621Sbill ldargs[ldargx] = 0; 404621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 405621Sbill unlink(onepso); 406621Sbill done(); 407621Sbill } 408621Sbill 409621Sbill dosys(cmd, argv, in, out) 410621Sbill char *cmd, **argv, *in, *out; 411621Sbill { 412621Sbill union wait status; 413621Sbill int pid; 414621Sbill 415621Sbill if (debug) { 416621Sbill int i; 417621Sbill printf("%s:", cmd); 418621Sbill for (i = 0; argv[i]; i++) 419621Sbill printf(" %s", argv[i]); 420621Sbill if (in) 421621Sbill printf(" <%s", in); 422621Sbill if (out) 423621Sbill printf(" >%s", out); 424621Sbill printf("\n"); 425621Sbill } 426621Sbill pid = vfork(); 427621Sbill if (pid < 0) { 428621Sbill fprintf(stderr, "pc: No more processes\n"); 429621Sbill done(); 430621Sbill } 431621Sbill if (pid == 0) { 432621Sbill if (in) { 433621Sbill close(0); 434621Sbill if (open(in, 0) != 0) { 435621Sbill perror(in); 436621Sbill exit(1); 437621Sbill } 438621Sbill } 439621Sbill if (out) { 440621Sbill close(1); 441621Sbill unlink(out); 442621Sbill if (creat(out, 0666) != 1) { 443621Sbill perror(out); 444621Sbill exit(1); 445621Sbill } 446621Sbill } 447621Sbill signal(SIGINT, SIG_DFL); 448621Sbill execv(cmd, argv); 449621Sbill perror(cmd); 450621Sbill exit(1); 451621Sbill } 452621Sbill while (wait(&status) != pid) 453621Sbill ; 454621Sbill if (WIFSIGNALED(status)) { 4557766Smckusick if (status.w_termsig != SIGINT) { 4567766Smckusick fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 4577766Smckusick if (status.w_coredump) 4587766Smckusick fprintf(stderr, " (core dumped)"); 4597766Smckusick fprintf(stderr, "\n"); 4607766Smckusick } 461621Sbill errs = 100; 462621Sbill done(); 463621Sbill /*NOTREACHED*/ 464621Sbill } 465621Sbill if (status.w_retcode) { 466621Sbill errs = 1; 467621Sbill remove(); 468621Sbill } 469621Sbill return (status.w_retcode); 470621Sbill } 471621Sbill 472621Sbill done() 473621Sbill { 474621Sbill 475621Sbill remove(); 476621Sbill exit(errs); 477621Sbill } 478621Sbill 479621Sbill remove() 480621Sbill { 481621Sbill 482621Sbill if (tfile[0]) 483621Sbill unlink(tfile[0]); 484621Sbill if (tfile[1]) 485621Sbill unlink(tfile[1]); 486621Sbill } 487621Sbill 488621Sbill onintr() 489621Sbill { 490621Sbill 491621Sbill errs = 1; 492621Sbill done(); 493621Sbill } 494621Sbill 495621Sbill getsuf(cp) 496621Sbill char *cp; 497621Sbill { 498621Sbill 499621Sbill if (*cp == 0) 500621Sbill return; 501621Sbill while (cp[1]) 502621Sbill cp++; 503621Sbill if (cp[-1] != '.') 504621Sbill return (0); 505621Sbill return (*cp); 506621Sbill } 507621Sbill 508621Sbill char * 509654Sbill setsuf(as, ch) 510654Sbill char *as; 511621Sbill { 512654Sbill register char *s, *s1; 513621Sbill 514654Sbill s = s1 = savestr(as); 515654Sbill while (*s) 516654Sbill if (*s++ == '/') 517654Sbill s1 = s; 518654Sbill s[-1] = ch; 519654Sbill return (s1); 520621Sbill } 521621Sbill 522621Sbill #define NSAVETAB 512 523621Sbill char *savetab; 524621Sbill int saveleft; 525621Sbill 526621Sbill char * 527621Sbill savestr(cp) 528621Sbill register char *cp; 529621Sbill { 530621Sbill register int len; 531621Sbill 532621Sbill len = strlen(cp) + 1; 533621Sbill if (len > saveleft) { 534621Sbill saveleft = NSAVETAB; 535621Sbill if (len > saveleft) 536621Sbill saveleft = len; 537621Sbill savetab = (char *)malloc(saveleft); 538621Sbill if (savetab == 0) { 539621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 540621Sbill exit(1); 541621Sbill } 542621Sbill } 543621Sbill strncpy(savetab, cp, len); 544621Sbill cp = savetab; 545621Sbill savetab += len; 546621Sbill return (cp); 547621Sbill } 548621Sbill 549621Sbill suffix(cp) 550621Sbill char *cp; 551621Sbill { 552621Sbill 553621Sbill if (cp[0] == 0 || cp[1] == 0) 554621Sbill return (0); 555621Sbill while (cp[1]) 556621Sbill cp++; 557621Sbill if (cp[-1] == '.') 558621Sbill return (*cp); 559621Sbill return (0); 560621Sbill } 561