1*5054Smckusic static char sccsid[] = "@(#)pc.c 3.13 11/23/81"; 2*5054Smckusic 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"; 20*5054Smckusic 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*5054Smckusic int Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag; 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 }; 38621Sbill int pc3argx = 1; 39621Sbill #define pc3args pc0args 40621Sbill #define ldargs pc0args 41621Sbill /* 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': 148*5054Smckusic 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 'g': 165621Sbill case 's': 166621Sbill case 'w': 167621Sbill case 'z': 168621Sbill case 'C': 169621Sbill pc0args[pc0argx++] = argp; 170621Sbill if (argp[1] == 'g') 171621Sbill gflag = 1; 172621Sbill continue; 173621Sbill case 't': 174621Sbill fprintf(stderr, "pc: -t is default; -C for checking\n"); 175621Sbill continue; 176621Sbill case 'p': 177*5054Smckusic if (argp[2] == 'g') 178*5054Smckusic crt0 = gcrt0; 179*5054Smckusic else 180*5054Smckusic crt0 = mcrt0; 181*5054Smckusic if (!Tlflag) 182*5054Smckusic lpc = "-lpc_p"; 183*5054Smckusic pflag = 1; 184654Sbill continue; 185621Sbill } 186621Sbill } 187621Sbill if (gflag && Oflag) { 188621Sbill fprintf(stderr, "pc: warning: -g overrides -O\n"); 189621Sbill Oflag = 0; 190621Sbill } 191621Sbill tname[0] = mktemp("/tmp/p0XXXXXX"); 192621Sbill tname[1] = mktemp("/tmp/p1XXXXXX"); 193621Sbill savargx = pc0argx; 194621Sbill for (i = 0; i < argc; i++) { 195621Sbill argp = argv[i]; 196621Sbill if (argp[0] == '-') 197621Sbill continue; 1981211Speter if (suffix(argp) == 's') { 1991211Speter asargx = 1; 2001211Speter if (Jflag) 2011211Speter asargs[asargx++] = "-J"; 2021211Speter asargs[asargx++] = argp; 2031211Speter asargs[asargx++] = "-o"; 2041211Speter tfile[1] = setsuf(argp, 'o'); 2051211Speter asargs[asargx++] = tfile[1]; 2061211Speter asargs[asargx] = 0; 2071211Speter if (dosys(as, asargs, 0, 0)) 2081211Speter continue; 2091211Speter tfile[1] = 0; 2101211Speter continue; 2111211Speter } 212621Sbill if (suffix(argp) != 'p') 213621Sbill continue; 214621Sbill tfile[0] = tname[0]; 215621Sbill pc0args[2] = tfile[0]; 216621Sbill pc0argx = savargx; 217654Sbill if (pflag) 218654Sbill pc0args[pc0argx++] = "-p"; 219621Sbill pc0args[pc0argx++] = argp; 220621Sbill pc0args[pc0argx] = 0; 221621Sbill if (dosys(pc0, pc0args, 0, 0)) 222621Sbill continue; 223621Sbill pc1args[1] = tfile[0]; 224654Sbill tfile[1] = tname[1]; 225621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 226621Sbill continue; 227621Sbill unlink(tfile[0]); 2282340Smckusic tfile[0] = tname[0]; 2292340Smckusic if (Oflag) { 2302340Smckusic if (dosys(c2, c2args, tfile[1], tfile[0])) 2312340Smckusic continue; 2322340Smckusic unlink(tfile[1]); 2332340Smckusic tfile[1] = tfile[0]; 2342340Smckusic tfile[0] = tname[1]; 2352340Smckusic } 2362340Smckusic if (Sflag) 237654Sbill tfile[0] = setsuf(argp, 's'); 238621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 239621Sbill continue; 240621Sbill unlink(tfile[1]); 241621Sbill tfile[1] = 0; 242654Sbill if (Sflag) { 243654Sbill tfile[0] = 0; 244621Sbill continue; 245654Sbill } 246908Sbill asargx = 1; 247908Sbill if (Jflag) 248908Sbill asargs[asargx++] = "-J"; 249908Sbill asargs[asargx++] = tfile[0]; 250908Sbill asargs[asargx++] = "-o"; 251621Sbill tfile[1] = setsuf(argp, 'o'); 252908Sbill asargs[asargx++] = tfile[1]; 253908Sbill asargs[asargx] = 0; 254621Sbill if (dosys(as, asargs, 0, 0)) 255621Sbill continue; 256621Sbill tfile[1] = 0; 257621Sbill remove(); 258621Sbill } 259621Sbill if (errs || cflag || Sflag) 260621Sbill done(); 261621Sbill /* char *pc3args[NARGS] = { "pc3", 0 }; */ 262621Sbill pc3args[0] = "pc3"; 263621Sbill for (i = 0; i < argc; i++) { 264621Sbill argp = argv[i]; 265621Sbill if (!strcmp(argp, "-o")) 266621Sbill i++; 267621Sbill if (argp[0] == '-') 268621Sbill continue; 269621Sbill switch (getsuf(argp)) { 270621Sbill 271621Sbill case 'o': 272621Sbill pc3args[pc3argx++] = argp; 273621Sbill nxo++; 274621Sbill continue; 2751211Speter case 's': 276621Sbill case 'p': 277621Sbill onepso = pc3args[pc3argx++] = 278621Sbill savestr(setsuf(argp, 'o')); 279621Sbill np++; 280621Sbill continue; 281621Sbill } 282621Sbill } 283621Sbill pc3args[pc3argx] = 0; 284621Sbill if (dosys(pc3, pc3args, 0, 0)) 285621Sbill done(); 286908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 287621Sbill ldargs[0] = "ld"; 288621Sbill ldargs[1] = "-X"; 289654Sbill ldargs[2] = crt0; 290621Sbill for (i = 0; i < argc; i++) { 291621Sbill argp = argv[i]; 292621Sbill if (argp[0] != '-') { 293621Sbill switch (getsuf(argp)) { 294621Sbill 295621Sbill case 'p': 2961211Speter case 's': 297621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 298621Sbill break; 299621Sbill default: 300621Sbill ldargs[ldargx] = argp; 301621Sbill break; 302621Sbill } 303621Sbill if (getsuf(ldargs[ldargx]) == 'o') 304621Sbill for (j = 0; j < ldargx; j++) 305621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 306621Sbill goto duplicate; 307621Sbill ldargx++; 308621Sbill duplicate: 309621Sbill continue; 310621Sbill } 311621Sbill switch (argp[1]) { 312621Sbill 313621Sbill case 'i': 314621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 315621Sbill getsuf(argv[i+1]) != 'p') 316621Sbill i++; 317621Sbill continue; 318621Sbill case 'd': 319621Sbill if (argp[2] == 0) 320621Sbill continue; 321621Sbill ldargs[ldargx++] = argp; 322621Sbill continue; 323621Sbill case 'o': 324621Sbill ldargs[ldargx++] = argp; 325621Sbill i++; 326621Sbill ldargs[ldargx++] = argv[i]; 327621Sbill continue; 328621Sbill case 'l': 329621Sbill if (argp[2]) 330621Sbill ldargs[ldargx++] = argp; 331621Sbill continue; 332621Sbill case 'c': 333621Sbill case 'g': 334621Sbill case 'w': 335621Sbill case 'p': 336621Sbill case 'S': 337908Sbill case 'J': 338621Sbill case 'T': 339621Sbill case 'O': 340621Sbill case 'C': 341621Sbill case 'b': 342621Sbill case 's': 343621Sbill case 'z': 344621Sbill continue; 345621Sbill default: 346621Sbill ldargs[ldargx++] = argp; 347621Sbill continue; 348621Sbill } 349621Sbill } 350621Sbill ldargs[ldargx++] = lpc; 351621Sbill if (gflag) 352621Sbill ldargs[ldargx++] = "-lg"; 353*5054Smckusic if (pflag) { 354*5054Smckusic ldargs[ldargx++] = "-lm_p"; 355*5054Smckusic ldargs[ldargx++] = "-lc_p"; 356*5054Smckusic } else { 357*5054Smckusic ldargs[ldargx++] = "-lm"; 358*5054Smckusic ldargs[ldargx++] = "-lc"; 359*5054Smckusic } 360621Sbill ldargs[ldargx] = 0; 361621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 362621Sbill unlink(onepso); 363621Sbill done(); 364621Sbill } 365621Sbill 366621Sbill dosys(cmd, argv, in, out) 367621Sbill char *cmd, **argv, *in, *out; 368621Sbill { 369621Sbill union wait status; 370621Sbill int pid; 371621Sbill 372621Sbill if (debug) { 373621Sbill int i; 374621Sbill printf("%s:", cmd); 375621Sbill for (i = 0; argv[i]; i++) 376621Sbill printf(" %s", argv[i]); 377621Sbill if (in) 378621Sbill printf(" <%s", in); 379621Sbill if (out) 380621Sbill printf(" >%s", out); 381621Sbill printf("\n"); 382621Sbill } 383621Sbill pid = vfork(); 384621Sbill if (pid < 0) { 385621Sbill fprintf(stderr, "pc: No more processes\n"); 386621Sbill done(); 387621Sbill } 388621Sbill if (pid == 0) { 389621Sbill if (in) { 390621Sbill close(0); 391621Sbill if (open(in, 0) != 0) { 392621Sbill perror(in); 393621Sbill exit(1); 394621Sbill } 395621Sbill } 396621Sbill if (out) { 397621Sbill close(1); 398621Sbill unlink(out); 399621Sbill if (creat(out, 0666) != 1) { 400621Sbill perror(out); 401621Sbill exit(1); 402621Sbill } 403621Sbill } 404621Sbill signal(SIGINT, SIG_DFL); 405621Sbill execv(cmd, argv); 406621Sbill perror(cmd); 407621Sbill exit(1); 408621Sbill } 409621Sbill while (wait(&status) != pid) 410621Sbill ; 411621Sbill if (WIFSIGNALED(status)) { 412621Sbill if (status.w_termsig != SIGINT) 413621Sbill fprintf(stderr, "Fatal error in %s\n", cmd); 414621Sbill errs = 100; 415621Sbill done(); 416621Sbill /*NOTREACHED*/ 417621Sbill } 418621Sbill if (status.w_retcode) { 419621Sbill errs = 1; 420621Sbill remove(); 421621Sbill } 422621Sbill return (status.w_retcode); 423621Sbill } 424621Sbill 425621Sbill done() 426621Sbill { 427621Sbill 428621Sbill remove(); 429621Sbill exit(errs); 430621Sbill } 431621Sbill 432621Sbill remove() 433621Sbill { 434621Sbill 435621Sbill if (tfile[0]) 436621Sbill unlink(tfile[0]); 437621Sbill if (tfile[1]) 438621Sbill unlink(tfile[1]); 439621Sbill } 440621Sbill 441621Sbill onintr() 442621Sbill { 443621Sbill 444621Sbill errs = 1; 445621Sbill done(); 446621Sbill } 447621Sbill 448621Sbill getsuf(cp) 449621Sbill char *cp; 450621Sbill { 451621Sbill 452621Sbill if (*cp == 0) 453621Sbill return; 454621Sbill while (cp[1]) 455621Sbill cp++; 456621Sbill if (cp[-1] != '.') 457621Sbill return (0); 458621Sbill return (*cp); 459621Sbill } 460621Sbill 461621Sbill char * 462654Sbill setsuf(as, ch) 463654Sbill char *as; 464621Sbill { 465654Sbill register char *s, *s1; 466621Sbill 467654Sbill s = s1 = savestr(as); 468654Sbill while (*s) 469654Sbill if (*s++ == '/') 470654Sbill s1 = s; 471654Sbill s[-1] = ch; 472654Sbill return (s1); 473621Sbill } 474621Sbill 475621Sbill #define NSAVETAB 512 476621Sbill char *savetab; 477621Sbill int saveleft; 478621Sbill 479621Sbill char * 480621Sbill savestr(cp) 481621Sbill register char *cp; 482621Sbill { 483621Sbill register int len; 484621Sbill 485621Sbill len = strlen(cp) + 1; 486621Sbill if (len > saveleft) { 487621Sbill saveleft = NSAVETAB; 488621Sbill if (len > saveleft) 489621Sbill saveleft = len; 490621Sbill savetab = (char *)malloc(saveleft); 491621Sbill if (savetab == 0) { 492621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 493621Sbill exit(1); 494621Sbill } 495621Sbill } 496621Sbill strncpy(savetab, cp, len); 497621Sbill cp = savetab; 498621Sbill savetab += len; 499621Sbill return (cp); 500621Sbill } 501621Sbill 502621Sbill suffix(cp) 503621Sbill char *cp; 504621Sbill { 505621Sbill 506621Sbill if (cp[0] == 0 || cp[1] == 0) 507621Sbill return (0); 508621Sbill while (cp[1]) 509621Sbill cp++; 510621Sbill if (cp[-1] == '.') 511621Sbill return (*cp); 512621Sbill return (0); 513621Sbill } 514