1*10561Smckusick static char sccsid[] = "@(#)pc.c 3.18 01/21/83"; 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': 1609140Smckusick pc0 = "/usr/src/ucb/pc0/a.out"; 1613862Smckusic if (argp[3] != '\0') { 1623862Smckusic pc0 = &argp[3]; 1633862Smckusic } 164621Sbill continue; 165621Sbill case '1': 1669140Smckusick pc1 = "/usr/src/lib/pcc/fort"; 1673862Smckusic if (argp[3] != '\0') { 1683862Smckusic pc1 = &argp[3]; 1693862Smckusic } 170621Sbill continue; 171621Sbill case '2': 1729140Smckusick pc2 = "/usr/src/ucb/pascal/pc2"; 1733862Smckusic if (argp[3] != '\0') { 1743862Smckusic pc2 = &argp[3]; 1753862Smckusic } 176621Sbill continue; 177621Sbill case '3': 1789140Smckusick pc3 = "/usr/src/ucb/pascal/pc3"; 1793862Smckusic if (argp[3] != '\0') { 1803862Smckusic pc3 = &argp[3]; 1813862Smckusic } 182621Sbill continue; 183621Sbill case 'l': 1845054Smckusic Tlflag = 1; 1859140Smckusick 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 { 400*10561Smckusick #ifndef sun 4015054Smckusic ldargs[ldargx++] = "-lm"; 4025054Smckusic ldargs[ldargx++] = "-lc"; 403*10561Smckusick #else 404*10561Smckusick ldargs[ldargx++] = "-lMm"; 405*10561Smckusick ldargs[ldargx++] = "-lMc"; 406*10561Smckusick #endif 4075054Smckusic } 408621Sbill ldargs[ldargx] = 0; 409621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 410621Sbill unlink(onepso); 411621Sbill done(); 412621Sbill } 413621Sbill 414621Sbill dosys(cmd, argv, in, out) 415621Sbill char *cmd, **argv, *in, *out; 416621Sbill { 417621Sbill union wait status; 418621Sbill int pid; 419621Sbill 420621Sbill if (debug) { 421621Sbill int i; 422621Sbill printf("%s:", cmd); 423621Sbill for (i = 0; argv[i]; i++) 424621Sbill printf(" %s", argv[i]); 425621Sbill if (in) 426621Sbill printf(" <%s", in); 427621Sbill if (out) 428621Sbill printf(" >%s", out); 429621Sbill printf("\n"); 430621Sbill } 431621Sbill pid = vfork(); 432621Sbill if (pid < 0) { 433621Sbill fprintf(stderr, "pc: No more processes\n"); 434621Sbill done(); 435621Sbill } 436621Sbill if (pid == 0) { 437621Sbill if (in) { 438621Sbill close(0); 439621Sbill if (open(in, 0) != 0) { 440621Sbill perror(in); 441621Sbill exit(1); 442621Sbill } 443621Sbill } 444621Sbill if (out) { 445621Sbill close(1); 446621Sbill unlink(out); 447621Sbill if (creat(out, 0666) != 1) { 448621Sbill perror(out); 449621Sbill exit(1); 450621Sbill } 451621Sbill } 452621Sbill signal(SIGINT, SIG_DFL); 453621Sbill execv(cmd, argv); 454621Sbill perror(cmd); 455621Sbill exit(1); 456621Sbill } 457621Sbill while (wait(&status) != pid) 458621Sbill ; 459621Sbill if (WIFSIGNALED(status)) { 4607766Smckusick if (status.w_termsig != SIGINT) { 4617766Smckusick fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 4627766Smckusick if (status.w_coredump) 4637766Smckusick fprintf(stderr, " (core dumped)"); 4647766Smckusick fprintf(stderr, "\n"); 4657766Smckusick } 466621Sbill errs = 100; 467621Sbill done(); 468621Sbill /*NOTREACHED*/ 469621Sbill } 470621Sbill if (status.w_retcode) { 471621Sbill errs = 1; 472621Sbill remove(); 473621Sbill } 474621Sbill return (status.w_retcode); 475621Sbill } 476621Sbill 477621Sbill done() 478621Sbill { 479621Sbill 480621Sbill remove(); 481621Sbill exit(errs); 482621Sbill } 483621Sbill 484621Sbill remove() 485621Sbill { 486621Sbill 487621Sbill if (tfile[0]) 488621Sbill unlink(tfile[0]); 489621Sbill if (tfile[1]) 490621Sbill unlink(tfile[1]); 491621Sbill } 492621Sbill 493621Sbill onintr() 494621Sbill { 495621Sbill 496621Sbill errs = 1; 497621Sbill done(); 498621Sbill } 499621Sbill 500621Sbill getsuf(cp) 501621Sbill char *cp; 502621Sbill { 503621Sbill 504621Sbill if (*cp == 0) 505621Sbill return; 506621Sbill while (cp[1]) 507621Sbill cp++; 508621Sbill if (cp[-1] != '.') 509621Sbill return (0); 510621Sbill return (*cp); 511621Sbill } 512621Sbill 513621Sbill char * 514654Sbill setsuf(as, ch) 515654Sbill char *as; 516621Sbill { 517654Sbill register char *s, *s1; 518621Sbill 519654Sbill s = s1 = savestr(as); 520654Sbill while (*s) 521654Sbill if (*s++ == '/') 522654Sbill s1 = s; 523654Sbill s[-1] = ch; 524654Sbill return (s1); 525621Sbill } 526621Sbill 527621Sbill #define NSAVETAB 512 528621Sbill char *savetab; 529621Sbill int saveleft; 530621Sbill 531621Sbill char * 532621Sbill savestr(cp) 533621Sbill register char *cp; 534621Sbill { 535621Sbill register int len; 536621Sbill 537621Sbill len = strlen(cp) + 1; 538621Sbill if (len > saveleft) { 539621Sbill saveleft = NSAVETAB; 540621Sbill if (len > saveleft) 541621Sbill saveleft = len; 542621Sbill savetab = (char *)malloc(saveleft); 543621Sbill if (savetab == 0) { 544621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 545621Sbill exit(1); 546621Sbill } 547621Sbill } 548621Sbill strncpy(savetab, cp, len); 549621Sbill cp = savetab; 550621Sbill savetab += len; 551621Sbill return (cp); 552621Sbill } 553621Sbill 554621Sbill suffix(cp) 555621Sbill char *cp; 556621Sbill { 557621Sbill 558621Sbill if (cp[0] == 0 || cp[1] == 0) 559621Sbill return (0); 560621Sbill while (cp[1]) 561621Sbill cp++; 562621Sbill if (cp[-1] == '.') 563621Sbill return (*cp); 564621Sbill return (0); 565621Sbill } 566