1*10672Speter static char sccsid[] = "@(#)pc.c 3.19 02/01/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(); 329*10672Speter errs = 0; 330908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 331621Sbill ldargs[0] = "ld"; 332621Sbill ldargs[1] = "-X"; 333654Sbill ldargs[2] = crt0; 334621Sbill for (i = 0; i < argc; i++) { 335621Sbill argp = argv[i]; 336621Sbill if (argp[0] != '-') { 337621Sbill switch (getsuf(argp)) { 338621Sbill 339621Sbill case 'p': 3401211Speter case 's': 341621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 342621Sbill break; 343621Sbill default: 344621Sbill ldargs[ldargx] = argp; 345621Sbill break; 346621Sbill } 347621Sbill if (getsuf(ldargs[ldargx]) == 'o') 348621Sbill for (j = 0; j < ldargx; j++) 349621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 350621Sbill goto duplicate; 351621Sbill ldargx++; 352621Sbill duplicate: 353621Sbill continue; 354621Sbill } 355621Sbill switch (argp[1]) { 356621Sbill 357621Sbill case 'i': 358621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 359621Sbill getsuf(argv[i+1]) != 'p') 360621Sbill i++; 361621Sbill continue; 362621Sbill case 'd': 363621Sbill if (argp[2] == 0) 364621Sbill continue; 365621Sbill ldargs[ldargx++] = argp; 366621Sbill continue; 367621Sbill case 'o': 368621Sbill ldargs[ldargx++] = argp; 369621Sbill i++; 370621Sbill ldargs[ldargx++] = argv[i]; 371621Sbill continue; 372621Sbill case 'l': 373621Sbill if (argp[2]) 374621Sbill ldargs[ldargx++] = argp; 375621Sbill continue; 376621Sbill case 'c': 377621Sbill case 'g': 378621Sbill case 'w': 379621Sbill case 'p': 380621Sbill case 'S': 381908Sbill case 'J': 382621Sbill case 'T': 383621Sbill case 'O': 384621Sbill case 'C': 385621Sbill case 'b': 386621Sbill case 's': 387621Sbill case 'z': 388621Sbill continue; 389621Sbill default: 390621Sbill ldargs[ldargx++] = argp; 391621Sbill continue; 392621Sbill } 393621Sbill } 394621Sbill ldargs[ldargx++] = lpc; 395621Sbill if (gflag) 396621Sbill ldargs[ldargx++] = "-lg"; 3975054Smckusic if (pflag) { 3985054Smckusic ldargs[ldargx++] = "-lm_p"; 3995054Smckusic ldargs[ldargx++] = "-lc_p"; 4005054Smckusic } else { 40110561Smckusick #ifndef sun 4025054Smckusic ldargs[ldargx++] = "-lm"; 4035054Smckusic ldargs[ldargx++] = "-lc"; 40410561Smckusick #else 40510561Smckusick ldargs[ldargx++] = "-lMm"; 40610561Smckusick ldargs[ldargx++] = "-lMc"; 40710561Smckusick #endif 4085054Smckusic } 409621Sbill ldargs[ldargx] = 0; 410621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 411621Sbill unlink(onepso); 412621Sbill done(); 413621Sbill } 414621Sbill 415621Sbill dosys(cmd, argv, in, out) 416621Sbill char *cmd, **argv, *in, *out; 417621Sbill { 418621Sbill union wait status; 419621Sbill int pid; 420621Sbill 421621Sbill if (debug) { 422621Sbill int i; 423621Sbill printf("%s:", cmd); 424621Sbill for (i = 0; argv[i]; i++) 425621Sbill printf(" %s", argv[i]); 426621Sbill if (in) 427621Sbill printf(" <%s", in); 428621Sbill if (out) 429621Sbill printf(" >%s", out); 430621Sbill printf("\n"); 431621Sbill } 432621Sbill pid = vfork(); 433621Sbill if (pid < 0) { 434621Sbill fprintf(stderr, "pc: No more processes\n"); 435621Sbill done(); 436621Sbill } 437621Sbill if (pid == 0) { 438621Sbill if (in) { 439621Sbill close(0); 440621Sbill if (open(in, 0) != 0) { 441621Sbill perror(in); 442621Sbill exit(1); 443621Sbill } 444621Sbill } 445621Sbill if (out) { 446621Sbill close(1); 447621Sbill unlink(out); 448621Sbill if (creat(out, 0666) != 1) { 449621Sbill perror(out); 450621Sbill exit(1); 451621Sbill } 452621Sbill } 453621Sbill signal(SIGINT, SIG_DFL); 454621Sbill execv(cmd, argv); 455621Sbill perror(cmd); 456621Sbill exit(1); 457621Sbill } 458621Sbill while (wait(&status) != pid) 459621Sbill ; 460621Sbill if (WIFSIGNALED(status)) { 4617766Smckusick if (status.w_termsig != SIGINT) { 4627766Smckusick fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 4637766Smckusick if (status.w_coredump) 4647766Smckusick fprintf(stderr, " (core dumped)"); 4657766Smckusick fprintf(stderr, "\n"); 4667766Smckusick } 467621Sbill errs = 100; 468621Sbill done(); 469621Sbill /*NOTREACHED*/ 470621Sbill } 471621Sbill if (status.w_retcode) { 472621Sbill errs = 1; 473621Sbill remove(); 474621Sbill } 475621Sbill return (status.w_retcode); 476621Sbill } 477621Sbill 478621Sbill done() 479621Sbill { 480621Sbill 481621Sbill remove(); 482621Sbill exit(errs); 483621Sbill } 484621Sbill 485621Sbill remove() 486621Sbill { 487621Sbill 488621Sbill if (tfile[0]) 489621Sbill unlink(tfile[0]); 490621Sbill if (tfile[1]) 491621Sbill unlink(tfile[1]); 492621Sbill } 493621Sbill 494621Sbill onintr() 495621Sbill { 496621Sbill 497621Sbill errs = 1; 498621Sbill done(); 499621Sbill } 500621Sbill 501621Sbill getsuf(cp) 502621Sbill char *cp; 503621Sbill { 504621Sbill 505621Sbill if (*cp == 0) 506621Sbill return; 507621Sbill while (cp[1]) 508621Sbill cp++; 509621Sbill if (cp[-1] != '.') 510621Sbill return (0); 511621Sbill return (*cp); 512621Sbill } 513621Sbill 514621Sbill char * 515654Sbill setsuf(as, ch) 516654Sbill char *as; 517621Sbill { 518654Sbill register char *s, *s1; 519621Sbill 520654Sbill s = s1 = savestr(as); 521654Sbill while (*s) 522654Sbill if (*s++ == '/') 523654Sbill s1 = s; 524654Sbill s[-1] = ch; 525654Sbill return (s1); 526621Sbill } 527621Sbill 528621Sbill #define NSAVETAB 512 529621Sbill char *savetab; 530621Sbill int saveleft; 531621Sbill 532621Sbill char * 533621Sbill savestr(cp) 534621Sbill register char *cp; 535621Sbill { 536621Sbill register int len; 537621Sbill 538621Sbill len = strlen(cp) + 1; 539621Sbill if (len > saveleft) { 540621Sbill saveleft = NSAVETAB; 541621Sbill if (len > saveleft) 542621Sbill saveleft = len; 543621Sbill savetab = (char *)malloc(saveleft); 544621Sbill if (savetab == 0) { 545621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 546621Sbill exit(1); 547621Sbill } 548621Sbill } 549621Sbill strncpy(savetab, cp, len); 550621Sbill cp = savetab; 551621Sbill savetab += len; 552621Sbill return (cp); 553621Sbill } 554621Sbill 555621Sbill suffix(cp) 556621Sbill char *cp; 557621Sbill { 558621Sbill 559621Sbill if (cp[0] == 0 || cp[1] == 0) 560621Sbill return (0); 561621Sbill while (cp[1]) 562621Sbill cp++; 563621Sbill if (cp[-1] == '.') 564621Sbill return (*cp); 565621Sbill return (0); 566621Sbill } 567