1*44606Sbostic /*- 2*44606Sbostic * Copyright (c) 1990 The Regents of the University of California. 3*44606Sbostic * All rights reserved. 4*44606Sbostic * 5*44606Sbostic * %sccs.include.redist.c% 622260Sdist */ 722260Sdist 813724Ssam #ifndef lint 922260Sdist char copyright[] = 10*44606Sbostic "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ 1122260Sdist All rights reserved.\n"; 12*44606Sbostic #endif /* not lint */ 135054Smckusic 1422260Sdist #ifndef lint 15*44606Sbostic static char sccsid[] = "@(#)pc.c 5.5 (Berkeley) 06/29/90"; 16*44606Sbostic #endif /* not lint */ 1722260Sdist 1831043Ssam #include <sys/param.h> 19*44606Sbostic #include <sys/signal.h> 2013724Ssam #include <sys/wait.h> 21*44606Sbostic #include <stdio.h> 22*44606Sbostic #include "pathnames.h" 23621Sbill 24621Sbill /* 25654Sbill * Pc - front end for Pascal compiler. 26621Sbill */ 27*44606Sbostic char *pc0 = _PATH_PC0; 28*44606Sbostic char *pc1 = _PATH_PC1; 29*44606Sbostic char *pc2 = _PATH_PC2; 30*44606Sbostic char *c2 = _PATH_C2; 31*44606Sbostic char *pc3 = _PATH_PC3; 32*44606Sbostic char *ld = _PATH_LD; 33*44606Sbostic char *as = _PATH_AS; 34621Sbill char *lpc = "-lpc"; 35*44606Sbostic char *crt0 = _PATH_CRT0; 36*44606Sbostic char *mcrt0 = _PATH_MCRT0; 37*44606Sbostic char *gcrt0 = _PATH_GCRT0; 38621Sbill 39621Sbill char *mktemp(); 40*44606Sbostic char *tmpdir = _PATH_TMP; 4112870Speter char tmp0[MAXPATHLEN], tmp1[MAXPATHLEN]; 42621Sbill char *tname[2]; 43621Sbill char *tfile[2]; 44621Sbill 45621Sbill char *setsuf(), *savestr(); 46621Sbill 4712870Speter int Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag, wflag, tflag; 48621Sbill int debug; 49621Sbill 50621Sbill #define NARGS 512 51621Sbill int ldargx = 3; 52621Sbill int pc0argx = 3; 53621Sbill char *pc0args[NARGS] = { "pc0", "-o", "XXX" }; 54621Sbill char *pc1args[3] = { "pc1", 0, }; 55621Sbill char *pc2args[2] = { "pc2", 0 }; 56621Sbill char *c2args[4] = { "c2", 0, 0, 0 }; 577596Smckusick int pc3argx = 1; 58621Sbill #define pc3args pc0args 59621Sbill #define ldargs pc0args 607596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 61*44606Sbostic /* char *ldargs[NARGS] = { "ld", "-X", _PATH_CRT0, 0, }; */ 6212870Speter 6312870Speter /* as -J -t tmpdir -o objfile srcfile \0 */ 64908Sbill int asargx; 6512870Speter char *asargs[8] = { "as", 0, }; 66621Sbill 677766Smckusick char *mesg[] = { 687766Smckusick 0, 697766Smckusick "Hangup", 707766Smckusick "Interrupt", 717766Smckusick "Quit", 727766Smckusick "Illegal instruction", 737766Smckusick "Trace/BPT trap", 747766Smckusick "IOT trap", 757766Smckusick "EMT trap", 767766Smckusick "Floating exception", 777766Smckusick "Killed", 787766Smckusick "Bus error", 797766Smckusick "Segmentation fault", 807766Smckusick "Bad system call", 817766Smckusick "Broken pipe", 827766Smckusick "Alarm clock", 837766Smckusick "Terminated", 847766Smckusick "Signal 16", 857766Smckusick "Stopped (signal)", 867766Smckusick "Stopped", 877766Smckusick "Continued", 887766Smckusick "Child exited", 897766Smckusick "Stopped (tty input)", 907766Smckusick "Stopped (tty output)", 917766Smckusick "Tty input interrupt", 927766Smckusick "Cputime limit exceeded", 937766Smckusick "Filesize limit exceeded", 947766Smckusick "Signal 26", 957766Smckusick "Signal 27", 967766Smckusick "Signal 28", 977766Smckusick "Signal 29", 987766Smckusick "Signal 30", 997766Smckusick "Signal 31", 1007766Smckusick "Signal 32" 1017766Smckusick }; 1027766Smckusick 103621Sbill /* 104621Sbill * If the number of .p arguments (np) is 1, and the number of .o arguments 105621Sbill * (nxo) is 0, and we successfully create an ``a.out'', then we remove 106621Sbill * the one .ps .o file (onepso). 107621Sbill */ 108621Sbill int np, nxo; 109621Sbill char *onepso; 110621Sbill int errs; 111621Sbill 112621Sbill int onintr(); 113621Sbill 114621Sbill main(argc, argv) 115621Sbill int argc; 116621Sbill char **argv; 117621Sbill { 118621Sbill register char *argp; 119621Sbill register int i; 120621Sbill int savargx; 121621Sbill char *t, c; 122621Sbill int j; 123621Sbill 124621Sbill argc--, argv++; 125621Sbill if (argc == 0) { 126*44606Sbostic execl(_PATH_CAT, "cat", _PATH_HOWPC); 127621Sbill exit(1); 128621Sbill } 129621Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 130621Sbill signal(SIGINT, onintr); 131621Sbill signal(SIGTERM, onintr); 132621Sbill } 133621Sbill for (i = 0; i < argc; i++) { 134621Sbill argp = argv[i]; 135621Sbill if (argp[0] != '-') 136621Sbill continue; 137621Sbill switch (argp[1]) { 138621Sbill 139621Sbill case 'd': 140621Sbill if (argp[2] == 0) 141621Sbill debug++; 142621Sbill continue; 143621Sbill case 'i': 144621Sbill pc0args[pc0argx++] = "-i"; 145621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 146621Sbill getsuf(argv[i+1]) != 'p') { 147621Sbill pc0args[pc0argx++] = argv[i+1]; 148621Sbill i++; 149621Sbill } 150621Sbill if (i+1 == argc) { 151621Sbill fprintf(stderr, "pc: bad -i construction\n"); 152621Sbill exit(1); 153621Sbill } 154621Sbill continue; 155621Sbill case 'o': 156621Sbill i++; 157621Sbill if (i == argc) { 158621Sbill fprintf(stderr, "pc: -o must specify file\n"); 159621Sbill exit(1); 160621Sbill } 161621Sbill c = getsuf(argv[i]); 162621Sbill if (c == 'o' || c == 'p' || c == 'c') { 163621Sbill fprintf(stderr, "pc: -o would overwrite %s\n", 164621Sbill argv[i]); 165621Sbill exit(1); 166621Sbill } 167621Sbill continue; 16812870Speter case 't': 16912870Speter i++; 17012870Speter if (i == argc) { 17112931Speter fprintf(stderr, "pc: -t but no directory\n"); 17212870Speter exit(1); 17312870Speter } 17412931Speter if (argp[2] != '\0') { 17512931Speter fprintf(stderr, "pc: bad -t option\n"); 17612931Speter exit(1); 17712931Speter } 17812870Speter tmpdir = argv[i]; 17912931Speter if (tmpdir[0] == '-') { 18012931Speter fprintf(stderr, "pc: bad -t option\n"); 18112931Speter exit(1); 18212931Speter } 18312870Speter tflag = 1; 18412870Speter continue; 185621Sbill case 'O': 186621Sbill Oflag = 1; 187621Sbill continue; 188621Sbill case 'S': 189621Sbill Sflag = 1; 190621Sbill continue; 191908Sbill case 'J': 192908Sbill Jflag = 1; 193908Sbill continue; 194621Sbill case 'T': 195621Sbill switch (argp[2]) { 196621Sbill 197621Sbill case '0': 198*44606Sbostic pc0 = _PATH_DPC0; 1993862Smckusic if (argp[3] != '\0') { 2003862Smckusic pc0 = &argp[3]; 2013862Smckusic } 202621Sbill continue; 203621Sbill case '1': 204*44606Sbostic pc1 = _PATH_DPC1; 2053862Smckusic if (argp[3] != '\0') { 2063862Smckusic pc1 = &argp[3]; 2073862Smckusic } 208621Sbill continue; 209621Sbill case '2': 210*44606Sbostic pc2 = _PATH_DPC2; 2113862Smckusic if (argp[3] != '\0') { 2123862Smckusic pc2 = &argp[3]; 2133862Smckusic } 214621Sbill continue; 215621Sbill case '3': 216*44606Sbostic pc3 = _PATH_DPC3; 2173862Smckusic if (argp[3] != '\0') { 2183862Smckusic pc3 = &argp[3]; 2193862Smckusic } 220621Sbill continue; 221621Sbill case 'l': 2225054Smckusic Tlflag = 1; 223*44606Sbostic lpc = _PATH_DLPC; 2243862Smckusic if (argp[3] != '\0') { 2253862Smckusic lpc = &argp[3]; 2263862Smckusic } 227621Sbill continue; 228621Sbill } 229621Sbill continue; 230621Sbill case 'c': 231621Sbill cflag = 1; 232621Sbill continue; 233621Sbill case 'l': 234621Sbill if (argp[2]) 235621Sbill continue; 236621Sbill /* fall into ... */ 237621Sbill case 'b': 238621Sbill case 's': 239621Sbill case 'z': 240621Sbill case 'C': 241621Sbill pc0args[pc0argx++] = argp; 242621Sbill continue; 2437596Smckusick case 'w': 2447596Smckusick wflag = 1; 2457596Smckusick pc0args[pc0argx++] = argp; 2467596Smckusick continue; 2477596Smckusick case 'g': 2487596Smckusick gflag = 1; 2497596Smckusick pc0args[pc0argx++] = argp; 2507596Smckusick continue; 251621Sbill case 'p': 2525054Smckusic if (argp[2] == 'g') 2535054Smckusic crt0 = gcrt0; 2545054Smckusic else 2555054Smckusic crt0 = mcrt0; 2565054Smckusic if (!Tlflag) 2575054Smckusic lpc = "-lpc_p"; 2585054Smckusic pflag = 1; 259654Sbill continue; 260621Sbill } 261621Sbill } 262621Sbill if (gflag && Oflag) { 263621Sbill fprintf(stderr, "pc: warning: -g overrides -O\n"); 264621Sbill Oflag = 0; 265621Sbill } 26612870Speter sprintf(tmp0, "%s/%s", tmpdir, "p0XXXXXX"); 26712870Speter tname[0] = mktemp(tmp0); 26812870Speter sprintf(tmp1, "%s/%s", tmpdir, "p1XXXXXX"); 26912870Speter tname[1] = mktemp(tmp1); 270621Sbill savargx = pc0argx; 271621Sbill for (i = 0; i < argc; i++) { 272621Sbill argp = argv[i]; 273621Sbill if (argp[0] == '-') 274621Sbill continue; 2751211Speter if (suffix(argp) == 's') { 2761211Speter asargx = 1; 2771211Speter if (Jflag) 2781211Speter asargs[asargx++] = "-J"; 27930092Smckusick # if defined(vax) || defined(tahoe) 28012870Speter if (tflag) { 28112870Speter asargs[asargx++] = "-t"; 28212870Speter asargs[asargx++] = tmpdir; 28312870Speter } 28430092Smckusick # endif vax || tahoe 2851211Speter asargs[asargx++] = argp; 2861211Speter asargs[asargx++] = "-o"; 2871211Speter tfile[1] = setsuf(argp, 'o'); 2881211Speter asargs[asargx++] = tfile[1]; 2891211Speter asargs[asargx] = 0; 2901211Speter if (dosys(as, asargs, 0, 0)) 2911211Speter continue; 2921211Speter tfile[1] = 0; 2931211Speter continue; 2941211Speter } 295621Sbill if (suffix(argp) != 'p') 296621Sbill continue; 297621Sbill tfile[0] = tname[0]; 298621Sbill pc0args[2] = tfile[0]; 299621Sbill pc0argx = savargx; 300654Sbill if (pflag) 301654Sbill pc0args[pc0argx++] = "-p"; 30212966Smckusick if (Jflag) 30312966Smckusick pc0args[pc0argx++] = "-J"; 304621Sbill pc0args[pc0argx++] = argp; 305621Sbill pc0args[pc0argx] = 0; 306621Sbill if (dosys(pc0, pc0args, 0, 0)) 307621Sbill continue; 308621Sbill pc1args[1] = tfile[0]; 309654Sbill tfile[1] = tname[1]; 310621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 311621Sbill continue; 312621Sbill unlink(tfile[0]); 3132340Smckusic tfile[0] = tname[0]; 3142340Smckusic if (Oflag) { 3152340Smckusic if (dosys(c2, c2args, tfile[1], tfile[0])) 3162340Smckusic continue; 3172340Smckusic unlink(tfile[1]); 3182340Smckusic tfile[1] = tfile[0]; 3192340Smckusic tfile[0] = tname[1]; 3202340Smckusic } 3212340Smckusic if (Sflag) 322654Sbill tfile[0] = setsuf(argp, 's'); 323621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 324621Sbill continue; 325621Sbill unlink(tfile[1]); 326621Sbill tfile[1] = 0; 327654Sbill if (Sflag) { 328654Sbill tfile[0] = 0; 329621Sbill continue; 330654Sbill } 331908Sbill asargx = 1; 332908Sbill if (Jflag) 333908Sbill asargs[asargx++] = "-J"; 33430092Smckusick # if defined(vax) || defined(tahoe) 33512870Speter if (tflag) { 33612870Speter asargs[asargx++] = "-t"; 33712870Speter asargs[asargx++] = tmpdir; 33812870Speter } 33930092Smckusick # endif vax || tahoe 340908Sbill asargs[asargx++] = tfile[0]; 341908Sbill asargs[asargx++] = "-o"; 342621Sbill tfile[1] = setsuf(argp, 'o'); 343908Sbill asargs[asargx++] = tfile[1]; 344908Sbill asargs[asargx] = 0; 345621Sbill if (dosys(as, asargs, 0, 0)) 346621Sbill continue; 347621Sbill tfile[1] = 0; 348621Sbill remove(); 349621Sbill } 350621Sbill if (errs || cflag || Sflag) 351621Sbill done(); 3527596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 353621Sbill pc3args[0] = "pc3"; 3547596Smckusick if (wflag) 3557596Smckusick pc3args[pc3argx++] = "-w"; 356*44606Sbostic pc3args[pc3argx++] = _PATH_PCEXTERN; 357621Sbill for (i = 0; i < argc; i++) { 358621Sbill argp = argv[i]; 359621Sbill if (!strcmp(argp, "-o")) 360621Sbill i++; 361621Sbill if (argp[0] == '-') 362621Sbill continue; 363621Sbill switch (getsuf(argp)) { 364621Sbill 365621Sbill case 'o': 366621Sbill pc3args[pc3argx++] = argp; 367621Sbill nxo++; 368621Sbill continue; 3691211Speter case 's': 370621Sbill case 'p': 371621Sbill onepso = pc3args[pc3argx++] = 372621Sbill savestr(setsuf(argp, 'o')); 373621Sbill np++; 374621Sbill continue; 375621Sbill } 376621Sbill } 377621Sbill pc3args[pc3argx] = 0; 3787596Smckusick if (dosys(pc3, pc3args, 0, 0) > 1) 379621Sbill done(); 38010672Speter errs = 0; 381*44606Sbostic /* char *ldargs[NARGS] = { "ld", "-X", _PATH_CRT0, 0, }; */ 382621Sbill ldargs[0] = "ld"; 383621Sbill ldargs[1] = "-X"; 384654Sbill ldargs[2] = crt0; 385621Sbill for (i = 0; i < argc; i++) { 386621Sbill argp = argv[i]; 387621Sbill if (argp[0] != '-') { 388621Sbill switch (getsuf(argp)) { 389621Sbill 390621Sbill case 'p': 3911211Speter case 's': 392621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 393621Sbill break; 394621Sbill default: 395621Sbill ldargs[ldargx] = argp; 396621Sbill break; 397621Sbill } 398621Sbill if (getsuf(ldargs[ldargx]) == 'o') 399621Sbill for (j = 0; j < ldargx; j++) 400621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 401621Sbill goto duplicate; 402621Sbill ldargx++; 403621Sbill duplicate: 404621Sbill continue; 405621Sbill } 406621Sbill switch (argp[1]) { 407621Sbill 408621Sbill case 'i': 409621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 410621Sbill getsuf(argv[i+1]) != 'p') 411621Sbill i++; 412621Sbill continue; 413621Sbill case 'd': 414621Sbill if (argp[2] == 0) 415621Sbill continue; 416621Sbill ldargs[ldargx++] = argp; 417621Sbill continue; 418621Sbill case 'o': 419621Sbill ldargs[ldargx++] = argp; 420621Sbill i++; 421621Sbill ldargs[ldargx++] = argv[i]; 422621Sbill continue; 423621Sbill case 'l': 424621Sbill if (argp[2]) 425621Sbill ldargs[ldargx++] = argp; 426621Sbill continue; 42712870Speter case 't': 42812870Speter i++; 42912870Speter continue; 430621Sbill case 'c': 431621Sbill case 'g': 432621Sbill case 'w': 433621Sbill case 'p': 434621Sbill case 'S': 435908Sbill case 'J': 436621Sbill case 'T': 437621Sbill case 'O': 438621Sbill case 'C': 439621Sbill case 'b': 440621Sbill case 's': 441621Sbill case 'z': 442621Sbill continue; 443621Sbill default: 444621Sbill ldargs[ldargx++] = argp; 445621Sbill continue; 446621Sbill } 447621Sbill } 448621Sbill ldargs[ldargx++] = lpc; 449621Sbill if (gflag) 450621Sbill ldargs[ldargx++] = "-lg"; 4515054Smckusic if (pflag) { 4525054Smckusic ldargs[ldargx++] = "-lm_p"; 4535054Smckusic ldargs[ldargx++] = "-lc_p"; 4545054Smckusic } else { 4555054Smckusic ldargs[ldargx++] = "-lm"; 4565054Smckusic ldargs[ldargx++] = "-lc"; 4575054Smckusic } 458621Sbill ldargs[ldargx] = 0; 459621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 460621Sbill unlink(onepso); 461621Sbill done(); 462621Sbill } 463621Sbill 464621Sbill dosys(cmd, argv, in, out) 465621Sbill char *cmd, **argv, *in, *out; 466621Sbill { 467621Sbill union wait status; 468621Sbill int pid; 469621Sbill 470621Sbill if (debug) { 471621Sbill int i; 472621Sbill printf("%s:", cmd); 473621Sbill for (i = 0; argv[i]; i++) 474621Sbill printf(" %s", argv[i]); 475621Sbill if (in) 476621Sbill printf(" <%s", in); 477621Sbill if (out) 478621Sbill printf(" >%s", out); 479621Sbill printf("\n"); 480621Sbill } 48115776Saoki /* 48215776Saoki * warning: vfork doesn't work here, because the call to signal() 48315776Saoki * done by the child process destroys the parent's SIGINT handler. 48415776Saoki */ 48515776Saoki pid = fork(); 486621Sbill if (pid < 0) { 487621Sbill fprintf(stderr, "pc: No more processes\n"); 488621Sbill done(); 489621Sbill } 490621Sbill if (pid == 0) { 491621Sbill if (in) { 492621Sbill close(0); 493621Sbill if (open(in, 0) != 0) { 494621Sbill perror(in); 495621Sbill exit(1); 496621Sbill } 497621Sbill } 498621Sbill if (out) { 499621Sbill close(1); 500621Sbill unlink(out); 501621Sbill if (creat(out, 0666) != 1) { 502621Sbill perror(out); 503621Sbill exit(1); 504621Sbill } 505621Sbill } 506621Sbill signal(SIGINT, SIG_DFL); 507621Sbill execv(cmd, argv); 508621Sbill perror(cmd); 509621Sbill exit(1); 510621Sbill } 511621Sbill while (wait(&status) != pid) 512621Sbill ; 513621Sbill if (WIFSIGNALED(status)) { 5147766Smckusick if (status.w_termsig != SIGINT) { 5157766Smckusick fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 5167766Smckusick if (status.w_coredump) 5177766Smckusick fprintf(stderr, " (core dumped)"); 5187766Smckusick fprintf(stderr, "\n"); 5197766Smckusick } 520621Sbill errs = 100; 521621Sbill done(); 522621Sbill /*NOTREACHED*/ 523621Sbill } 524621Sbill if (status.w_retcode) { 525621Sbill errs = 1; 526621Sbill remove(); 527621Sbill } 528621Sbill return (status.w_retcode); 529621Sbill } 530621Sbill 531621Sbill done() 532621Sbill { 533621Sbill 534621Sbill remove(); 535621Sbill exit(errs); 536621Sbill } 537621Sbill 538621Sbill remove() 539621Sbill { 540621Sbill 541621Sbill if (tfile[0]) 542621Sbill unlink(tfile[0]); 543621Sbill if (tfile[1]) 544621Sbill unlink(tfile[1]); 545621Sbill } 546621Sbill 547621Sbill onintr() 548621Sbill { 549621Sbill 550621Sbill errs = 1; 551621Sbill done(); 552621Sbill } 553621Sbill 554621Sbill getsuf(cp) 555621Sbill char *cp; 556621Sbill { 557621Sbill 558621Sbill if (*cp == 0) 559621Sbill return; 560621Sbill while (cp[1]) 561621Sbill cp++; 562621Sbill if (cp[-1] != '.') 563621Sbill return (0); 564621Sbill return (*cp); 565621Sbill } 566621Sbill 567621Sbill char * 568654Sbill setsuf(as, ch) 569654Sbill char *as; 570621Sbill { 571654Sbill register char *s, *s1; 572621Sbill 573654Sbill s = s1 = savestr(as); 574654Sbill while (*s) 575654Sbill if (*s++ == '/') 576654Sbill s1 = s; 577654Sbill s[-1] = ch; 578654Sbill return (s1); 579621Sbill } 580621Sbill 581621Sbill #define NSAVETAB 512 582621Sbill char *savetab; 583621Sbill int saveleft; 584621Sbill 585621Sbill char * 586621Sbill savestr(cp) 587621Sbill register char *cp; 588621Sbill { 589621Sbill register int len; 590621Sbill 591621Sbill len = strlen(cp) + 1; 592621Sbill if (len > saveleft) { 593621Sbill saveleft = NSAVETAB; 594621Sbill if (len > saveleft) 595621Sbill saveleft = len; 596621Sbill savetab = (char *)malloc(saveleft); 597621Sbill if (savetab == 0) { 598621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 599621Sbill exit(1); 600621Sbill } 601621Sbill } 602621Sbill strncpy(savetab, cp, len); 603621Sbill cp = savetab; 604621Sbill savetab += len; 605621Sbill return (cp); 606621Sbill } 607621Sbill 608621Sbill suffix(cp) 609621Sbill char *cp; 610621Sbill { 611621Sbill 612621Sbill if (cp[0] == 0 || cp[1] == 0) 613621Sbill return (0); 614621Sbill while (cp[1]) 615621Sbill cp++; 616621Sbill if (cp[-1] == '.') 617621Sbill return (*cp); 618621Sbill return (0); 619621Sbill } 620