1*22260Sdist /* 2*22260Sdist * Copyright (c) 1980 Regents of the University of California. 3*22260Sdist * All rights reserved. The Berkeley software License Agreement 4*22260Sdist * specifies the terms and conditions for redistribution. 5*22260Sdist */ 6*22260Sdist 713724Ssam #ifndef lint 8*22260Sdist char copyright[] = 9*22260Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10*22260Sdist All rights reserved.\n"; 11*22260Sdist #endif not lint 125054Smckusic 13*22260Sdist #ifndef lint 14*22260Sdist static char sccsid[] = "@(#)pc.c 5.1 (Berkeley) 06/05/85"; 15*22260Sdist #endif not lint 16*22260Sdist 17621Sbill #include <stdio.h> 18621Sbill #include <signal.h> 1913724Ssam #include <sys/wait.h> 2012870Speter #include <sys/param.h> 21621Sbill 22621Sbill /* 23654Sbill * Pc - front end for Pascal compiler. 24621Sbill */ 25908Sbill char *pc0 = "/usr/lib/pc0"; 26908Sbill char *pc1 = "/lib/f1"; 27908Sbill char *pc2 = "/usr/lib/pc2"; 28908Sbill char *c2 = "/lib/c2"; 29908Sbill char *pc3 = "/usr/lib/pc3"; 30908Sbill char *ld = "/bin/ld"; 31908Sbill char *as = "/bin/as"; 32621Sbill char *lpc = "-lpc"; 33908Sbill char *crt0 = "/lib/crt0.o"; 34908Sbill char *mcrt0 = "/lib/mcrt0.o"; 355054Smckusic char *gcrt0 = "/usr/lib/gcrt0.o"; 36621Sbill 37621Sbill char *mktemp(); 3812870Speter char *tmpdir = "/tmp"; 3912870Speter char tmp0[MAXPATHLEN], tmp1[MAXPATHLEN]; 40621Sbill char *tname[2]; 41621Sbill char *tfile[2]; 42621Sbill 43621Sbill char *setsuf(), *savestr(); 44621Sbill 4512870Speter int Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag, wflag, tflag; 46621Sbill int debug; 47621Sbill 48621Sbill #define NARGS 512 49621Sbill int ldargx = 3; 50621Sbill int pc0argx = 3; 51621Sbill char *pc0args[NARGS] = { "pc0", "-o", "XXX" }; 52621Sbill char *pc1args[3] = { "pc1", 0, }; 53621Sbill char *pc2args[2] = { "pc2", 0 }; 54621Sbill char *c2args[4] = { "c2", 0, 0, 0 }; 557596Smckusick int pc3argx = 1; 56621Sbill #define pc3args pc0args 57621Sbill #define ldargs pc0args 587596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 59908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 6012870Speter 6112870Speter /* as -J -t tmpdir -o objfile srcfile \0 */ 62908Sbill int asargx; 6312870Speter char *asargs[8] = { "as", 0, }; 64621Sbill 657766Smckusick char *mesg[] = { 667766Smckusick 0, 677766Smckusick "Hangup", 687766Smckusick "Interrupt", 697766Smckusick "Quit", 707766Smckusick "Illegal instruction", 717766Smckusick "Trace/BPT trap", 727766Smckusick "IOT trap", 737766Smckusick "EMT trap", 747766Smckusick "Floating exception", 757766Smckusick "Killed", 767766Smckusick "Bus error", 777766Smckusick "Segmentation fault", 787766Smckusick "Bad system call", 797766Smckusick "Broken pipe", 807766Smckusick "Alarm clock", 817766Smckusick "Terminated", 827766Smckusick "Signal 16", 837766Smckusick "Stopped (signal)", 847766Smckusick "Stopped", 857766Smckusick "Continued", 867766Smckusick "Child exited", 877766Smckusick "Stopped (tty input)", 887766Smckusick "Stopped (tty output)", 897766Smckusick "Tty input interrupt", 907766Smckusick "Cputime limit exceeded", 917766Smckusick "Filesize limit exceeded", 927766Smckusick "Signal 26", 937766Smckusick "Signal 27", 947766Smckusick "Signal 28", 957766Smckusick "Signal 29", 967766Smckusick "Signal 30", 977766Smckusick "Signal 31", 987766Smckusick "Signal 32" 997766Smckusick }; 1007766Smckusick 101621Sbill /* 102621Sbill * If the number of .p arguments (np) is 1, and the number of .o arguments 103621Sbill * (nxo) is 0, and we successfully create an ``a.out'', then we remove 104621Sbill * the one .ps .o file (onepso). 105621Sbill */ 106621Sbill int np, nxo; 107621Sbill char *onepso; 108621Sbill int errs; 109621Sbill 110621Sbill int onintr(); 111621Sbill 112621Sbill main(argc, argv) 113621Sbill int argc; 114621Sbill char **argv; 115621Sbill { 116621Sbill register char *argp; 117621Sbill register int i; 118621Sbill int savargx; 119621Sbill char *t, c; 120621Sbill int j; 121621Sbill 122621Sbill argc--, argv++; 123621Sbill if (argc == 0) { 124621Sbill execl("/bin/cat", "cat", "/usr/lib/how_pc"); 125621Sbill exit(1); 126621Sbill } 127621Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 128621Sbill signal(SIGINT, onintr); 129621Sbill signal(SIGTERM, onintr); 130621Sbill } 131621Sbill for (i = 0; i < argc; i++) { 132621Sbill argp = argv[i]; 133621Sbill if (argp[0] != '-') 134621Sbill continue; 135621Sbill switch (argp[1]) { 136621Sbill 137621Sbill case 'd': 138621Sbill if (argp[2] == 0) 139621Sbill debug++; 140621Sbill continue; 141621Sbill case 'i': 142621Sbill pc0args[pc0argx++] = "-i"; 143621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 144621Sbill getsuf(argv[i+1]) != 'p') { 145621Sbill pc0args[pc0argx++] = argv[i+1]; 146621Sbill i++; 147621Sbill } 148621Sbill if (i+1 == argc) { 149621Sbill fprintf(stderr, "pc: bad -i construction\n"); 150621Sbill exit(1); 151621Sbill } 152621Sbill continue; 153621Sbill case 'o': 154621Sbill i++; 155621Sbill if (i == argc) { 156621Sbill fprintf(stderr, "pc: -o must specify file\n"); 157621Sbill exit(1); 158621Sbill } 159621Sbill c = getsuf(argv[i]); 160621Sbill if (c == 'o' || c == 'p' || c == 'c') { 161621Sbill fprintf(stderr, "pc: -o would overwrite %s\n", 162621Sbill argv[i]); 163621Sbill exit(1); 164621Sbill } 165621Sbill continue; 16612870Speter case 't': 16712870Speter i++; 16812870Speter if (i == argc) { 16912931Speter fprintf(stderr, "pc: -t but no directory\n"); 17012870Speter exit(1); 17112870Speter } 17212931Speter if (argp[2] != '\0') { 17312931Speter fprintf(stderr, "pc: bad -t option\n"); 17412931Speter exit(1); 17512931Speter } 17612870Speter tmpdir = argv[i]; 17712931Speter if (tmpdir[0] == '-') { 17812931Speter fprintf(stderr, "pc: bad -t option\n"); 17912931Speter exit(1); 18012931Speter } 18112870Speter tflag = 1; 18212870Speter continue; 183621Sbill case 'O': 184621Sbill Oflag = 1; 185621Sbill continue; 186621Sbill case 'S': 187621Sbill Sflag = 1; 188621Sbill continue; 189908Sbill case 'J': 190908Sbill Jflag = 1; 191908Sbill continue; 192621Sbill case 'T': 193621Sbill switch (argp[2]) { 194621Sbill 195621Sbill case '0': 19610721Smckusick pc0 = "/usr/src/ucb/pascal/pc0/a.out"; 1973862Smckusic if (argp[3] != '\0') { 1983862Smckusic pc0 = &argp[3]; 1993862Smckusic } 200621Sbill continue; 201621Sbill case '1': 2029140Smckusick pc1 = "/usr/src/lib/pcc/fort"; 2033862Smckusic if (argp[3] != '\0') { 2043862Smckusic pc1 = &argp[3]; 2053862Smckusic } 206621Sbill continue; 207621Sbill case '2': 20810721Smckusick pc2 = "/usr/src/ucb/pascal/utilities/pc2"; 2093862Smckusic if (argp[3] != '\0') { 2103862Smckusic pc2 = &argp[3]; 2113862Smckusic } 212621Sbill continue; 213621Sbill case '3': 21410721Smckusick pc3 = "/usr/src/ucb/pascal/utilities/pc3"; 2153862Smckusic if (argp[3] != '\0') { 2163862Smckusic pc3 = &argp[3]; 2173862Smckusic } 218621Sbill continue; 219621Sbill case 'l': 2205054Smckusic Tlflag = 1; 2219140Smckusick lpc = "/usr/src/usr.lib/libpc/libpc"; 2223862Smckusic if (argp[3] != '\0') { 2233862Smckusic lpc = &argp[3]; 2243862Smckusic } 225621Sbill continue; 226621Sbill } 227621Sbill continue; 228621Sbill case 'c': 229621Sbill cflag = 1; 230621Sbill continue; 231621Sbill case 'l': 232621Sbill if (argp[2]) 233621Sbill continue; 234621Sbill /* fall into ... */ 235621Sbill case 'b': 236621Sbill case 's': 237621Sbill case 'z': 238621Sbill case 'C': 239621Sbill pc0args[pc0argx++] = argp; 240621Sbill continue; 2417596Smckusick case 'w': 2427596Smckusick wflag = 1; 2437596Smckusick pc0args[pc0argx++] = argp; 2447596Smckusick continue; 2457596Smckusick case 'g': 2467596Smckusick gflag = 1; 2477596Smckusick pc0args[pc0argx++] = argp; 2487596Smckusick continue; 249621Sbill case 'p': 2505054Smckusic if (argp[2] == 'g') 2515054Smckusic crt0 = gcrt0; 2525054Smckusic else 2535054Smckusic crt0 = mcrt0; 2545054Smckusic if (!Tlflag) 2555054Smckusic lpc = "-lpc_p"; 2565054Smckusic pflag = 1; 257654Sbill continue; 258621Sbill } 259621Sbill } 260621Sbill if (gflag && Oflag) { 261621Sbill fprintf(stderr, "pc: warning: -g overrides -O\n"); 262621Sbill Oflag = 0; 263621Sbill } 26412870Speter sprintf(tmp0, "%s/%s", tmpdir, "p0XXXXXX"); 26512870Speter tname[0] = mktemp(tmp0); 26612870Speter sprintf(tmp1, "%s/%s", tmpdir, "p1XXXXXX"); 26712870Speter tname[1] = mktemp(tmp1); 268621Sbill savargx = pc0argx; 269621Sbill for (i = 0; i < argc; i++) { 270621Sbill argp = argv[i]; 271621Sbill if (argp[0] == '-') 272621Sbill continue; 2731211Speter if (suffix(argp) == 's') { 2741211Speter asargx = 1; 2751211Speter if (Jflag) 2761211Speter asargs[asargx++] = "-J"; 27712870Speter # ifdef vax 27812870Speter if (tflag) { 27912870Speter asargs[asargx++] = "-t"; 28012870Speter asargs[asargx++] = tmpdir; 28112870Speter } 28212870Speter # endif vax 2831211Speter asargs[asargx++] = argp; 2841211Speter asargs[asargx++] = "-o"; 2851211Speter tfile[1] = setsuf(argp, 'o'); 2861211Speter asargs[asargx++] = tfile[1]; 2871211Speter asargs[asargx] = 0; 2881211Speter if (dosys(as, asargs, 0, 0)) 2891211Speter continue; 2901211Speter tfile[1] = 0; 2911211Speter continue; 2921211Speter } 293621Sbill if (suffix(argp) != 'p') 294621Sbill continue; 295621Sbill tfile[0] = tname[0]; 296621Sbill pc0args[2] = tfile[0]; 297621Sbill pc0argx = savargx; 298654Sbill if (pflag) 299654Sbill pc0args[pc0argx++] = "-p"; 30012966Smckusick if (Jflag) 30112966Smckusick pc0args[pc0argx++] = "-J"; 302621Sbill pc0args[pc0argx++] = argp; 303621Sbill pc0args[pc0argx] = 0; 304621Sbill if (dosys(pc0, pc0args, 0, 0)) 305621Sbill continue; 306621Sbill pc1args[1] = tfile[0]; 307654Sbill tfile[1] = tname[1]; 308621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 309621Sbill continue; 310621Sbill unlink(tfile[0]); 3112340Smckusic tfile[0] = tname[0]; 3122340Smckusic if (Oflag) { 3132340Smckusic if (dosys(c2, c2args, tfile[1], tfile[0])) 3142340Smckusic continue; 3152340Smckusic unlink(tfile[1]); 3162340Smckusic tfile[1] = tfile[0]; 3172340Smckusic tfile[0] = tname[1]; 3182340Smckusic } 3192340Smckusic if (Sflag) 320654Sbill tfile[0] = setsuf(argp, 's'); 321621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 322621Sbill continue; 323621Sbill unlink(tfile[1]); 324621Sbill tfile[1] = 0; 325654Sbill if (Sflag) { 326654Sbill tfile[0] = 0; 327621Sbill continue; 328654Sbill } 329908Sbill asargx = 1; 330908Sbill if (Jflag) 331908Sbill asargs[asargx++] = "-J"; 33212870Speter # ifdef vax 33312870Speter if (tflag) { 33412870Speter asargs[asargx++] = "-t"; 33512870Speter asargs[asargx++] = tmpdir; 33612870Speter } 33712870Speter # endif vax 338908Sbill asargs[asargx++] = tfile[0]; 339908Sbill asargs[asargx++] = "-o"; 340621Sbill tfile[1] = setsuf(argp, 'o'); 341908Sbill asargs[asargx++] = tfile[1]; 342908Sbill asargs[asargx] = 0; 343621Sbill if (dosys(as, asargs, 0, 0)) 344621Sbill continue; 345621Sbill tfile[1] = 0; 346621Sbill remove(); 347621Sbill } 348621Sbill if (errs || cflag || Sflag) 349621Sbill done(); 3507596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 351621Sbill pc3args[0] = "pc3"; 3527596Smckusick if (wflag) 3537596Smckusick pc3args[pc3argx++] = "-w"; 3547596Smckusick pc3args[pc3argx++] = "/usr/lib/pcexterns.o"; 355621Sbill for (i = 0; i < argc; i++) { 356621Sbill argp = argv[i]; 357621Sbill if (!strcmp(argp, "-o")) 358621Sbill i++; 359621Sbill if (argp[0] == '-') 360621Sbill continue; 361621Sbill switch (getsuf(argp)) { 362621Sbill 363621Sbill case 'o': 364621Sbill pc3args[pc3argx++] = argp; 365621Sbill nxo++; 366621Sbill continue; 3671211Speter case 's': 368621Sbill case 'p': 369621Sbill onepso = pc3args[pc3argx++] = 370621Sbill savestr(setsuf(argp, 'o')); 371621Sbill np++; 372621Sbill continue; 373621Sbill } 374621Sbill } 375621Sbill pc3args[pc3argx] = 0; 3767596Smckusick if (dosys(pc3, pc3args, 0, 0) > 1) 377621Sbill done(); 37810672Speter errs = 0; 379908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 380621Sbill ldargs[0] = "ld"; 381621Sbill ldargs[1] = "-X"; 382654Sbill ldargs[2] = crt0; 383621Sbill for (i = 0; i < argc; i++) { 384621Sbill argp = argv[i]; 385621Sbill if (argp[0] != '-') { 386621Sbill switch (getsuf(argp)) { 387621Sbill 388621Sbill case 'p': 3891211Speter case 's': 390621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 391621Sbill break; 392621Sbill default: 393621Sbill ldargs[ldargx] = argp; 394621Sbill break; 395621Sbill } 396621Sbill if (getsuf(ldargs[ldargx]) == 'o') 397621Sbill for (j = 0; j < ldargx; j++) 398621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 399621Sbill goto duplicate; 400621Sbill ldargx++; 401621Sbill duplicate: 402621Sbill continue; 403621Sbill } 404621Sbill switch (argp[1]) { 405621Sbill 406621Sbill case 'i': 407621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 408621Sbill getsuf(argv[i+1]) != 'p') 409621Sbill i++; 410621Sbill continue; 411621Sbill case 'd': 412621Sbill if (argp[2] == 0) 413621Sbill continue; 414621Sbill ldargs[ldargx++] = argp; 415621Sbill continue; 416621Sbill case 'o': 417621Sbill ldargs[ldargx++] = argp; 418621Sbill i++; 419621Sbill ldargs[ldargx++] = argv[i]; 420621Sbill continue; 421621Sbill case 'l': 422621Sbill if (argp[2]) 423621Sbill ldargs[ldargx++] = argp; 424621Sbill continue; 42512870Speter case 't': 42612870Speter i++; 42712870Speter continue; 428621Sbill case 'c': 429621Sbill case 'g': 430621Sbill case 'w': 431621Sbill case 'p': 432621Sbill case 'S': 433908Sbill case 'J': 434621Sbill case 'T': 435621Sbill case 'O': 436621Sbill case 'C': 437621Sbill case 'b': 438621Sbill case 's': 439621Sbill case 'z': 440621Sbill continue; 441621Sbill default: 442621Sbill ldargs[ldargx++] = argp; 443621Sbill continue; 444621Sbill } 445621Sbill } 446621Sbill ldargs[ldargx++] = lpc; 447621Sbill if (gflag) 448621Sbill ldargs[ldargx++] = "-lg"; 4495054Smckusic if (pflag) { 4505054Smckusic ldargs[ldargx++] = "-lm_p"; 4515054Smckusic ldargs[ldargx++] = "-lc_p"; 4525054Smckusic } else { 4535054Smckusic ldargs[ldargx++] = "-lm"; 4545054Smckusic ldargs[ldargx++] = "-lc"; 4555054Smckusic } 456621Sbill ldargs[ldargx] = 0; 457621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 458621Sbill unlink(onepso); 459621Sbill done(); 460621Sbill } 461621Sbill 462621Sbill dosys(cmd, argv, in, out) 463621Sbill char *cmd, **argv, *in, *out; 464621Sbill { 465621Sbill union wait status; 466621Sbill int pid; 467621Sbill 468621Sbill if (debug) { 469621Sbill int i; 470621Sbill printf("%s:", cmd); 471621Sbill for (i = 0; argv[i]; i++) 472621Sbill printf(" %s", argv[i]); 473621Sbill if (in) 474621Sbill printf(" <%s", in); 475621Sbill if (out) 476621Sbill printf(" >%s", out); 477621Sbill printf("\n"); 478621Sbill } 47915776Saoki /* 48015776Saoki * warning: vfork doesn't work here, because the call to signal() 48115776Saoki * done by the child process destroys the parent's SIGINT handler. 48215776Saoki */ 48315776Saoki pid = fork(); 484621Sbill if (pid < 0) { 485621Sbill fprintf(stderr, "pc: No more processes\n"); 486621Sbill done(); 487621Sbill } 488621Sbill if (pid == 0) { 489621Sbill if (in) { 490621Sbill close(0); 491621Sbill if (open(in, 0) != 0) { 492621Sbill perror(in); 493621Sbill exit(1); 494621Sbill } 495621Sbill } 496621Sbill if (out) { 497621Sbill close(1); 498621Sbill unlink(out); 499621Sbill if (creat(out, 0666) != 1) { 500621Sbill perror(out); 501621Sbill exit(1); 502621Sbill } 503621Sbill } 504621Sbill signal(SIGINT, SIG_DFL); 505621Sbill execv(cmd, argv); 506621Sbill perror(cmd); 507621Sbill exit(1); 508621Sbill } 509621Sbill while (wait(&status) != pid) 510621Sbill ; 511621Sbill if (WIFSIGNALED(status)) { 5127766Smckusick if (status.w_termsig != SIGINT) { 5137766Smckusick fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 5147766Smckusick if (status.w_coredump) 5157766Smckusick fprintf(stderr, " (core dumped)"); 5167766Smckusick fprintf(stderr, "\n"); 5177766Smckusick } 518621Sbill errs = 100; 519621Sbill done(); 520621Sbill /*NOTREACHED*/ 521621Sbill } 522621Sbill if (status.w_retcode) { 523621Sbill errs = 1; 524621Sbill remove(); 525621Sbill } 526621Sbill return (status.w_retcode); 527621Sbill } 528621Sbill 529621Sbill done() 530621Sbill { 531621Sbill 532621Sbill remove(); 533621Sbill exit(errs); 534621Sbill } 535621Sbill 536621Sbill remove() 537621Sbill { 538621Sbill 539621Sbill if (tfile[0]) 540621Sbill unlink(tfile[0]); 541621Sbill if (tfile[1]) 542621Sbill unlink(tfile[1]); 543621Sbill } 544621Sbill 545621Sbill onintr() 546621Sbill { 547621Sbill 548621Sbill errs = 1; 549621Sbill done(); 550621Sbill } 551621Sbill 552621Sbill getsuf(cp) 553621Sbill char *cp; 554621Sbill { 555621Sbill 556621Sbill if (*cp == 0) 557621Sbill return; 558621Sbill while (cp[1]) 559621Sbill cp++; 560621Sbill if (cp[-1] != '.') 561621Sbill return (0); 562621Sbill return (*cp); 563621Sbill } 564621Sbill 565621Sbill char * 566654Sbill setsuf(as, ch) 567654Sbill char *as; 568621Sbill { 569654Sbill register char *s, *s1; 570621Sbill 571654Sbill s = s1 = savestr(as); 572654Sbill while (*s) 573654Sbill if (*s++ == '/') 574654Sbill s1 = s; 575654Sbill s[-1] = ch; 576654Sbill return (s1); 577621Sbill } 578621Sbill 579621Sbill #define NSAVETAB 512 580621Sbill char *savetab; 581621Sbill int saveleft; 582621Sbill 583621Sbill char * 584621Sbill savestr(cp) 585621Sbill register char *cp; 586621Sbill { 587621Sbill register int len; 588621Sbill 589621Sbill len = strlen(cp) + 1; 590621Sbill if (len > saveleft) { 591621Sbill saveleft = NSAVETAB; 592621Sbill if (len > saveleft) 593621Sbill saveleft = len; 594621Sbill savetab = (char *)malloc(saveleft); 595621Sbill if (savetab == 0) { 596621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 597621Sbill exit(1); 598621Sbill } 599621Sbill } 600621Sbill strncpy(savetab, cp, len); 601621Sbill cp = savetab; 602621Sbill savetab += len; 603621Sbill return (cp); 604621Sbill } 605621Sbill 606621Sbill suffix(cp) 607621Sbill char *cp; 608621Sbill { 609621Sbill 610621Sbill if (cp[0] == 0 || cp[1] == 0) 611621Sbill return (0); 612621Sbill while (cp[1]) 613621Sbill cp++; 614621Sbill if (cp[-1] == '.') 615621Sbill return (*cp); 616621Sbill return (0); 617621Sbill } 618