1*7596Smckusick static char sccsid[] = "@(#)pc.c 3.15 07/29/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 28*7596Smckusick 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 }; 38*7596Smckusick int pc3argx = 1; 39621Sbill #define pc3args pc0args 40621Sbill #define ldargs pc0args 41*7596Smckusick /* 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 46621Sbill /* 47621Sbill * If the number of .p arguments (np) is 1, and the number of .o arguments 48621Sbill * (nxo) is 0, and we successfully create an ``a.out'', then we remove 49621Sbill * the one .ps .o file (onepso). 50621Sbill */ 51621Sbill int np, nxo; 52621Sbill char *onepso; 53621Sbill int errs; 54621Sbill 55621Sbill int onintr(); 56621Sbill 57621Sbill main(argc, argv) 58621Sbill int argc; 59621Sbill char **argv; 60621Sbill { 61621Sbill register char *argp; 62621Sbill register int i; 63621Sbill int savargx; 64621Sbill char *t, c; 65621Sbill int j; 66621Sbill 67621Sbill argc--, argv++; 68621Sbill if (argc == 0) { 69621Sbill execl("/bin/cat", "cat", "/usr/lib/how_pc"); 70621Sbill exit(1); 71621Sbill } 72621Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 73621Sbill signal(SIGINT, onintr); 74621Sbill signal(SIGTERM, onintr); 75621Sbill } 76621Sbill for (i = 0; i < argc; i++) { 77621Sbill argp = argv[i]; 78621Sbill if (argp[0] != '-') 79621Sbill continue; 80621Sbill switch (argp[1]) { 81621Sbill 82621Sbill case 'd': 83621Sbill if (argp[2] == 0) 84621Sbill debug++; 85621Sbill continue; 86621Sbill case 'i': 87621Sbill pc0args[pc0argx++] = "-i"; 88621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 89621Sbill getsuf(argv[i+1]) != 'p') { 90621Sbill pc0args[pc0argx++] = argv[i+1]; 91621Sbill i++; 92621Sbill } 93621Sbill if (i+1 == argc) { 94621Sbill fprintf(stderr, "pc: bad -i construction\n"); 95621Sbill exit(1); 96621Sbill } 97621Sbill continue; 98621Sbill case 'o': 99621Sbill i++; 100621Sbill if (i == argc) { 101621Sbill fprintf(stderr, "pc: -o must specify file\n"); 102621Sbill exit(1); 103621Sbill } 104621Sbill c = getsuf(argv[i]); 105621Sbill if (c == 'o' || c == 'p' || c == 'c') { 106621Sbill fprintf(stderr, "pc: -o would overwrite %s\n", 107621Sbill argv[i]); 108621Sbill exit(1); 109621Sbill } 110621Sbill continue; 111621Sbill case 'O': 112621Sbill Oflag = 1; 113621Sbill continue; 114621Sbill case 'S': 115621Sbill Sflag = 1; 116621Sbill continue; 117908Sbill case 'J': 118908Sbill Jflag = 1; 119908Sbill continue; 120621Sbill case 'T': 121621Sbill switch (argp[2]) { 122621Sbill 123621Sbill case '0': 124908Sbill pc0 = "/usr/src/cmd/pc0/a.out"; 1253862Smckusic if (argp[3] != '\0') { 1263862Smckusic pc0 = &argp[3]; 1273862Smckusic } 128621Sbill continue; 129621Sbill case '1': 130908Sbill pc1 = "/usr/src/cmd/pcc/pc1"; 1313862Smckusic if (argp[3] != '\0') { 1323862Smckusic pc1 = &argp[3]; 1333862Smckusic } 134621Sbill continue; 135621Sbill case '2': 1362194Smckusic pc2 = "/usr/src/cmd/pascal/pc2"; 1373862Smckusic if (argp[3] != '\0') { 1383862Smckusic pc2 = &argp[3]; 1393862Smckusic } 140621Sbill continue; 141621Sbill case '3': 1422194Smckusic pc3 = "/usr/src/cmd/pascal/pc3"; 1433862Smckusic if (argp[3] != '\0') { 1443862Smckusic pc3 = &argp[3]; 1453862Smckusic } 146621Sbill continue; 147621Sbill case 'l': 1485054Smckusic Tlflag = 1; 1492127Smckusic lpc = "/usr/src/lib/libpc/libpc"; 1503862Smckusic if (argp[3] != '\0') { 1513862Smckusic lpc = &argp[3]; 1523862Smckusic } 153621Sbill continue; 154621Sbill } 155621Sbill continue; 156621Sbill case 'c': 157621Sbill cflag = 1; 158621Sbill continue; 159621Sbill case 'l': 160621Sbill if (argp[2]) 161621Sbill continue; 162621Sbill /* fall into ... */ 163621Sbill case 'b': 164621Sbill case 's': 165621Sbill case 'z': 166621Sbill case 'C': 167621Sbill pc0args[pc0argx++] = argp; 168621Sbill continue; 169*7596Smckusick case 'w': 170*7596Smckusick wflag = 1; 171*7596Smckusick pc0args[pc0argx++] = argp; 172*7596Smckusick continue; 173*7596Smckusick case 'g': 174*7596Smckusick gflag = 1; 175*7596Smckusick pc0args[pc0argx++] = argp; 176*7596Smckusick continue; 177621Sbill case 't': 178621Sbill fprintf(stderr, "pc: -t is default; -C for checking\n"); 179621Sbill continue; 180621Sbill case 'p': 1815054Smckusic if (argp[2] == 'g') 1825054Smckusic crt0 = gcrt0; 1835054Smckusic else 1845054Smckusic crt0 = mcrt0; 1855054Smckusic if (!Tlflag) 1865054Smckusic lpc = "-lpc_p"; 1875054Smckusic pflag = 1; 188654Sbill continue; 189621Sbill } 190621Sbill } 191621Sbill if (gflag && Oflag) { 192621Sbill fprintf(stderr, "pc: warning: -g overrides -O\n"); 193621Sbill Oflag = 0; 194621Sbill } 195621Sbill tname[0] = mktemp("/tmp/p0XXXXXX"); 196621Sbill tname[1] = mktemp("/tmp/p1XXXXXX"); 197621Sbill savargx = pc0argx; 198621Sbill for (i = 0; i < argc; i++) { 199621Sbill argp = argv[i]; 200621Sbill if (argp[0] == '-') 201621Sbill continue; 2021211Speter if (suffix(argp) == 's') { 2031211Speter asargx = 1; 2041211Speter if (Jflag) 2051211Speter asargs[asargx++] = "-J"; 2061211Speter asargs[asargx++] = argp; 2071211Speter asargs[asargx++] = "-o"; 2081211Speter tfile[1] = setsuf(argp, 'o'); 2091211Speter asargs[asargx++] = tfile[1]; 2101211Speter asargs[asargx] = 0; 2111211Speter if (dosys(as, asargs, 0, 0)) 2121211Speter continue; 2131211Speter tfile[1] = 0; 2141211Speter continue; 2151211Speter } 216621Sbill if (suffix(argp) != 'p') 217621Sbill continue; 218621Sbill tfile[0] = tname[0]; 219621Sbill pc0args[2] = tfile[0]; 220621Sbill pc0argx = savargx; 221654Sbill if (pflag) 222654Sbill pc0args[pc0argx++] = "-p"; 223621Sbill pc0args[pc0argx++] = argp; 224621Sbill pc0args[pc0argx] = 0; 225621Sbill if (dosys(pc0, pc0args, 0, 0)) 226621Sbill continue; 227621Sbill pc1args[1] = tfile[0]; 228654Sbill tfile[1] = tname[1]; 229621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 230621Sbill continue; 231621Sbill unlink(tfile[0]); 2322340Smckusic tfile[0] = tname[0]; 2332340Smckusic if (Oflag) { 2342340Smckusic if (dosys(c2, c2args, tfile[1], tfile[0])) 2352340Smckusic continue; 2362340Smckusic unlink(tfile[1]); 2372340Smckusic tfile[1] = tfile[0]; 2382340Smckusic tfile[0] = tname[1]; 2392340Smckusic } 2402340Smckusic if (Sflag) 241654Sbill tfile[0] = setsuf(argp, 's'); 242621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 243621Sbill continue; 244621Sbill unlink(tfile[1]); 245621Sbill tfile[1] = 0; 246654Sbill if (Sflag) { 247654Sbill tfile[0] = 0; 248621Sbill continue; 249654Sbill } 250908Sbill asargx = 1; 251908Sbill if (Jflag) 252908Sbill asargs[asargx++] = "-J"; 253908Sbill asargs[asargx++] = tfile[0]; 254908Sbill asargs[asargx++] = "-o"; 255621Sbill tfile[1] = setsuf(argp, 'o'); 256908Sbill asargs[asargx++] = tfile[1]; 257908Sbill asargs[asargx] = 0; 258621Sbill if (dosys(as, asargs, 0, 0)) 259621Sbill continue; 260621Sbill tfile[1] = 0; 261621Sbill remove(); 262621Sbill } 263621Sbill if (errs || cflag || Sflag) 264621Sbill done(); 265*7596Smckusick /* char *pc3args[NARGS] = { "pc3", 0 }; */ 266621Sbill pc3args[0] = "pc3"; 267*7596Smckusick if (wflag) 268*7596Smckusick pc3args[pc3argx++] = "-w"; 269*7596Smckusick pc3args[pc3argx++] = "/usr/lib/pcexterns.o"; 270621Sbill for (i = 0; i < argc; i++) { 271621Sbill argp = argv[i]; 272621Sbill if (!strcmp(argp, "-o")) 273621Sbill i++; 274621Sbill if (argp[0] == '-') 275621Sbill continue; 276621Sbill switch (getsuf(argp)) { 277621Sbill 278621Sbill case 'o': 279621Sbill pc3args[pc3argx++] = argp; 280621Sbill nxo++; 281621Sbill continue; 2821211Speter case 's': 283621Sbill case 'p': 284621Sbill onepso = pc3args[pc3argx++] = 285621Sbill savestr(setsuf(argp, 'o')); 286621Sbill np++; 287621Sbill continue; 288621Sbill } 289621Sbill } 290621Sbill pc3args[pc3argx] = 0; 291*7596Smckusick if (dosys(pc3, pc3args, 0, 0) > 1) 292621Sbill done(); 293908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 294621Sbill ldargs[0] = "ld"; 295621Sbill ldargs[1] = "-X"; 296654Sbill ldargs[2] = crt0; 297621Sbill for (i = 0; i < argc; i++) { 298621Sbill argp = argv[i]; 299621Sbill if (argp[0] != '-') { 300621Sbill switch (getsuf(argp)) { 301621Sbill 302621Sbill case 'p': 3031211Speter case 's': 304621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 305621Sbill break; 306621Sbill default: 307621Sbill ldargs[ldargx] = argp; 308621Sbill break; 309621Sbill } 310621Sbill if (getsuf(ldargs[ldargx]) == 'o') 311621Sbill for (j = 0; j < ldargx; j++) 312621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 313621Sbill goto duplicate; 314621Sbill ldargx++; 315621Sbill duplicate: 316621Sbill continue; 317621Sbill } 318621Sbill switch (argp[1]) { 319621Sbill 320621Sbill case 'i': 321621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 322621Sbill getsuf(argv[i+1]) != 'p') 323621Sbill i++; 324621Sbill continue; 325621Sbill case 'd': 326621Sbill if (argp[2] == 0) 327621Sbill continue; 328621Sbill ldargs[ldargx++] = argp; 329621Sbill continue; 330621Sbill case 'o': 331621Sbill ldargs[ldargx++] = argp; 332621Sbill i++; 333621Sbill ldargs[ldargx++] = argv[i]; 334621Sbill continue; 335621Sbill case 'l': 336621Sbill if (argp[2]) 337621Sbill ldargs[ldargx++] = argp; 338621Sbill continue; 339621Sbill case 'c': 340621Sbill case 'g': 341621Sbill case 'w': 342621Sbill case 'p': 343621Sbill case 'S': 344908Sbill case 'J': 345621Sbill case 'T': 346621Sbill case 'O': 347621Sbill case 'C': 348621Sbill case 'b': 349621Sbill case 's': 350621Sbill case 'z': 351621Sbill continue; 352621Sbill default: 353621Sbill ldargs[ldargx++] = argp; 354621Sbill continue; 355621Sbill } 356621Sbill } 357621Sbill ldargs[ldargx++] = lpc; 358621Sbill if (gflag) 359621Sbill ldargs[ldargx++] = "-lg"; 3605054Smckusic if (pflag) { 3615054Smckusic ldargs[ldargx++] = "-lm_p"; 3625054Smckusic ldargs[ldargx++] = "-lc_p"; 3635054Smckusic } else { 3645054Smckusic ldargs[ldargx++] = "-lm"; 3655054Smckusic ldargs[ldargx++] = "-lc"; 3665054Smckusic } 367621Sbill ldargs[ldargx] = 0; 368621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 369621Sbill unlink(onepso); 370621Sbill done(); 371621Sbill } 372621Sbill 373621Sbill dosys(cmd, argv, in, out) 374621Sbill char *cmd, **argv, *in, *out; 375621Sbill { 376621Sbill union wait status; 377621Sbill int pid; 378621Sbill 379621Sbill if (debug) { 380621Sbill int i; 381621Sbill printf("%s:", cmd); 382621Sbill for (i = 0; argv[i]; i++) 383621Sbill printf(" %s", argv[i]); 384621Sbill if (in) 385621Sbill printf(" <%s", in); 386621Sbill if (out) 387621Sbill printf(" >%s", out); 388621Sbill printf("\n"); 389621Sbill } 390621Sbill pid = vfork(); 391621Sbill if (pid < 0) { 392621Sbill fprintf(stderr, "pc: No more processes\n"); 393621Sbill done(); 394621Sbill } 395621Sbill if (pid == 0) { 396621Sbill if (in) { 397621Sbill close(0); 398621Sbill if (open(in, 0) != 0) { 399621Sbill perror(in); 400621Sbill exit(1); 401621Sbill } 402621Sbill } 403621Sbill if (out) { 404621Sbill close(1); 405621Sbill unlink(out); 406621Sbill if (creat(out, 0666) != 1) { 407621Sbill perror(out); 408621Sbill exit(1); 409621Sbill } 410621Sbill } 411621Sbill signal(SIGINT, SIG_DFL); 412621Sbill execv(cmd, argv); 413621Sbill perror(cmd); 414621Sbill exit(1); 415621Sbill } 416621Sbill while (wait(&status) != pid) 417621Sbill ; 418621Sbill if (WIFSIGNALED(status)) { 419621Sbill if (status.w_termsig != SIGINT) 420621Sbill fprintf(stderr, "Fatal error in %s\n", cmd); 421621Sbill errs = 100; 422621Sbill done(); 423621Sbill /*NOTREACHED*/ 424621Sbill } 425621Sbill if (status.w_retcode) { 426621Sbill errs = 1; 427621Sbill remove(); 428621Sbill } 429621Sbill return (status.w_retcode); 430621Sbill } 431621Sbill 432621Sbill done() 433621Sbill { 434621Sbill 435621Sbill remove(); 436621Sbill exit(errs); 437621Sbill } 438621Sbill 439621Sbill remove() 440621Sbill { 441621Sbill 442621Sbill if (tfile[0]) 443621Sbill unlink(tfile[0]); 444621Sbill if (tfile[1]) 445621Sbill unlink(tfile[1]); 446621Sbill } 447621Sbill 448621Sbill onintr() 449621Sbill { 450621Sbill 451621Sbill errs = 1; 452621Sbill done(); 453621Sbill } 454621Sbill 455621Sbill getsuf(cp) 456621Sbill char *cp; 457621Sbill { 458621Sbill 459621Sbill if (*cp == 0) 460621Sbill return; 461621Sbill while (cp[1]) 462621Sbill cp++; 463621Sbill if (cp[-1] != '.') 464621Sbill return (0); 465621Sbill return (*cp); 466621Sbill } 467621Sbill 468621Sbill char * 469654Sbill setsuf(as, ch) 470654Sbill char *as; 471621Sbill { 472654Sbill register char *s, *s1; 473621Sbill 474654Sbill s = s1 = savestr(as); 475654Sbill while (*s) 476654Sbill if (*s++ == '/') 477654Sbill s1 = s; 478654Sbill s[-1] = ch; 479654Sbill return (s1); 480621Sbill } 481621Sbill 482621Sbill #define NSAVETAB 512 483621Sbill char *savetab; 484621Sbill int saveleft; 485621Sbill 486621Sbill char * 487621Sbill savestr(cp) 488621Sbill register char *cp; 489621Sbill { 490621Sbill register int len; 491621Sbill 492621Sbill len = strlen(cp) + 1; 493621Sbill if (len > saveleft) { 494621Sbill saveleft = NSAVETAB; 495621Sbill if (len > saveleft) 496621Sbill saveleft = len; 497621Sbill savetab = (char *)malloc(saveleft); 498621Sbill if (savetab == 0) { 499621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 500621Sbill exit(1); 501621Sbill } 502621Sbill } 503621Sbill strncpy(savetab, cp, len); 504621Sbill cp = savetab; 505621Sbill savetab += len; 506621Sbill return (cp); 507621Sbill } 508621Sbill 509621Sbill suffix(cp) 510621Sbill char *cp; 511621Sbill { 512621Sbill 513621Sbill if (cp[0] == 0 || cp[1] == 0) 514621Sbill return (0); 515621Sbill while (cp[1]) 516621Sbill cp++; 517621Sbill if (cp[-1] == '.') 518621Sbill return (*cp); 519621Sbill return (0); 520621Sbill } 521