1*7766Smckusick static char sccsid[] = "@(#)pc.c 3.16 08/16/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 46*7766Smckusick char *mesg[] = { 47*7766Smckusick 0, 48*7766Smckusick "Hangup", 49*7766Smckusick "Interrupt", 50*7766Smckusick "Quit", 51*7766Smckusick "Illegal instruction", 52*7766Smckusick "Trace/BPT trap", 53*7766Smckusick "IOT trap", 54*7766Smckusick "EMT trap", 55*7766Smckusick "Floating exception", 56*7766Smckusick "Killed", 57*7766Smckusick "Bus error", 58*7766Smckusick "Segmentation fault", 59*7766Smckusick "Bad system call", 60*7766Smckusick "Broken pipe", 61*7766Smckusick "Alarm clock", 62*7766Smckusick "Terminated", 63*7766Smckusick "Signal 16", 64*7766Smckusick "Stopped (signal)", 65*7766Smckusick "Stopped", 66*7766Smckusick "Continued", 67*7766Smckusick "Child exited", 68*7766Smckusick "Stopped (tty input)", 69*7766Smckusick "Stopped (tty output)", 70*7766Smckusick "Tty input interrupt", 71*7766Smckusick "Cputime limit exceeded", 72*7766Smckusick "Filesize limit exceeded", 73*7766Smckusick "Signal 26", 74*7766Smckusick "Signal 27", 75*7766Smckusick "Signal 28", 76*7766Smckusick "Signal 29", 77*7766Smckusick "Signal 30", 78*7766Smckusick "Signal 31", 79*7766Smckusick "Signal 32" 80*7766Smckusick }; 81*7766Smckusick 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': 160908Sbill pc0 = "/usr/src/cmd/pc0/a.out"; 1613862Smckusic if (argp[3] != '\0') { 1623862Smckusic pc0 = &argp[3]; 1633862Smckusic } 164621Sbill continue; 165621Sbill case '1': 166908Sbill pc1 = "/usr/src/cmd/pcc/pc1"; 1673862Smckusic if (argp[3] != '\0') { 1683862Smckusic pc1 = &argp[3]; 1693862Smckusic } 170621Sbill continue; 171621Sbill case '2': 1722194Smckusic pc2 = "/usr/src/cmd/pascal/pc2"; 1733862Smckusic if (argp[3] != '\0') { 1743862Smckusic pc2 = &argp[3]; 1753862Smckusic } 176621Sbill continue; 177621Sbill case '3': 1782194Smckusic pc3 = "/usr/src/cmd/pascal/pc3"; 1793862Smckusic if (argp[3] != '\0') { 1803862Smckusic pc3 = &argp[3]; 1813862Smckusic } 182621Sbill continue; 183621Sbill case 'l': 1845054Smckusic Tlflag = 1; 1852127Smckusic lpc = "/usr/src/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)) { 455*7766Smckusick if (status.w_termsig != SIGINT) { 456*7766Smckusick fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 457*7766Smckusick if (status.w_coredump) 458*7766Smckusick fprintf(stderr, " (core dumped)"); 459*7766Smckusick fprintf(stderr, "\n"); 460*7766Smckusick } 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