1*3862Smckusic static char sccsid[] = "@(#)pc.c 3.12 06/08/81"; 2621Sbill #include <stdio.h> 3621Sbill #include <signal.h> 4621Sbill #include <wait.h> 5621Sbill 6621Sbill /* 7654Sbill * Pc - front end for Pascal compiler. 8621Sbill */ 9908Sbill char *pc0 = "/usr/lib/pc0"; 10908Sbill char *pc1 = "/lib/f1"; 11908Sbill char *pc2 = "/usr/lib/pc2"; 12908Sbill char *c2 = "/lib/c2"; 13908Sbill char *pc3 = "/usr/lib/pc3"; 14908Sbill char *ld = "/bin/ld"; 15908Sbill char *as = "/bin/as"; 16621Sbill char *lpc = "-lpc"; 17908Sbill char *crt0 = "/lib/crt0.o"; 18908Sbill char *mcrt0 = "/lib/mcrt0.o"; 19621Sbill 20621Sbill char *mktemp(); 21621Sbill char *tname[2]; 22621Sbill char *tfile[2]; 23621Sbill 24621Sbill char *setsuf(), *savestr(); 25621Sbill 26908Sbill int Jflag, Sflag, Oflag, cflag, gflag, pflag; 27621Sbill int debug; 28621Sbill 29621Sbill #define NARGS 512 30621Sbill int ldargx = 3; 31621Sbill int pc0argx = 3; 32621Sbill char *pc0args[NARGS] = { "pc0", "-o", "XXX" }; 33621Sbill char *pc1args[3] = { "pc1", 0, }; 34621Sbill char *pc2args[2] = { "pc2", 0 }; 35621Sbill char *c2args[4] = { "c2", 0, 0, 0 }; 36621Sbill int pc3argx = 1; 37621Sbill #define pc3args pc0args 38621Sbill #define ldargs pc0args 39621Sbill /* char *pc3args[NARGS] = { "pc3", 0 }; */ 40908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 41908Sbill int asargx; 42908Sbill char *asargs[6] = { "as", 0, }; 43621Sbill 44621Sbill /* 45621Sbill * If the number of .p arguments (np) is 1, and the number of .o arguments 46621Sbill * (nxo) is 0, and we successfully create an ``a.out'', then we remove 47621Sbill * the one .ps .o file (onepso). 48621Sbill */ 49621Sbill int np, nxo; 50621Sbill char *onepso; 51621Sbill int errs; 52621Sbill 53621Sbill int onintr(); 54621Sbill 55621Sbill main(argc, argv) 56621Sbill int argc; 57621Sbill char **argv; 58621Sbill { 59621Sbill register char *argp; 60621Sbill register int i; 61621Sbill int savargx; 62621Sbill char *t, c; 63621Sbill int j; 64621Sbill 65621Sbill argc--, argv++; 66621Sbill if (argc == 0) { 67621Sbill execl("/bin/cat", "cat", "/usr/lib/how_pc"); 68621Sbill exit(1); 69621Sbill } 70621Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 71621Sbill signal(SIGINT, onintr); 72621Sbill signal(SIGTERM, onintr); 73621Sbill } 74621Sbill for (i = 0; i < argc; i++) { 75621Sbill argp = argv[i]; 76621Sbill if (argp[0] != '-') 77621Sbill continue; 78621Sbill switch (argp[1]) { 79621Sbill 80621Sbill case 'd': 81621Sbill if (argp[2] == 0) 82621Sbill debug++; 83621Sbill continue; 84621Sbill case 'i': 85621Sbill pc0args[pc0argx++] = "-i"; 86621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 87621Sbill getsuf(argv[i+1]) != 'p') { 88621Sbill pc0args[pc0argx++] = argv[i+1]; 89621Sbill i++; 90621Sbill } 91621Sbill if (i+1 == argc) { 92621Sbill fprintf(stderr, "pc: bad -i construction\n"); 93621Sbill exit(1); 94621Sbill } 95621Sbill continue; 96621Sbill case 'o': 97621Sbill i++; 98621Sbill if (i == argc) { 99621Sbill fprintf(stderr, "pc: -o must specify file\n"); 100621Sbill exit(1); 101621Sbill } 102621Sbill c = getsuf(argv[i]); 103621Sbill if (c == 'o' || c == 'p' || c == 'c') { 104621Sbill fprintf(stderr, "pc: -o would overwrite %s\n", 105621Sbill argv[i]); 106621Sbill exit(1); 107621Sbill } 108621Sbill continue; 109621Sbill case 'O': 110621Sbill Oflag = 1; 111621Sbill continue; 112621Sbill case 'S': 113621Sbill Sflag = 1; 114621Sbill continue; 115908Sbill case 'J': 116908Sbill Jflag = 1; 117908Sbill continue; 118621Sbill case 'T': 119621Sbill switch (argp[2]) { 120621Sbill 121621Sbill case '0': 122908Sbill pc0 = "/usr/src/cmd/pc0/a.out"; 123*3862Smckusic if (argp[3] != '\0') { 124*3862Smckusic pc0 = &argp[3]; 125*3862Smckusic } 126621Sbill continue; 127621Sbill case '1': 128908Sbill pc1 = "/usr/src/cmd/pcc/pc1"; 129*3862Smckusic if (argp[3] != '\0') { 130*3862Smckusic pc1 = &argp[3]; 131*3862Smckusic } 132621Sbill continue; 133621Sbill case '2': 1342194Smckusic pc2 = "/usr/src/cmd/pascal/pc2"; 135*3862Smckusic if (argp[3] != '\0') { 136*3862Smckusic pc2 = &argp[3]; 137*3862Smckusic } 138621Sbill continue; 139621Sbill case '3': 1402194Smckusic pc3 = "/usr/src/cmd/pascal/pc3"; 141*3862Smckusic if (argp[3] != '\0') { 142*3862Smckusic pc3 = &argp[3]; 143*3862Smckusic } 144621Sbill continue; 145621Sbill case 'l': 1462127Smckusic lpc = "/usr/src/lib/libpc/libpc"; 147*3862Smckusic if (argp[3] != '\0') { 148*3862Smckusic lpc = &argp[3]; 149*3862Smckusic } 150621Sbill continue; 151621Sbill } 152621Sbill continue; 153621Sbill case 'c': 154621Sbill cflag = 1; 155621Sbill continue; 156621Sbill case 'l': 157621Sbill if (argp[2]) 158621Sbill continue; 159621Sbill /* fall into ... */ 160621Sbill case 'b': 161621Sbill case 'g': 162621Sbill case 's': 163621Sbill case 'w': 164621Sbill case 'z': 165621Sbill case 'C': 166621Sbill pc0args[pc0argx++] = argp; 167621Sbill if (argp[1] == 'g') 168621Sbill gflag = 1; 169621Sbill continue; 170621Sbill case 't': 171621Sbill fprintf(stderr, "pc: -t is default; -C for checking\n"); 172621Sbill continue; 173621Sbill case 'p': 174654Sbill crt0 = mcrt0; 175654Sbill pflag++; 176654Sbill continue; 177621Sbill } 178621Sbill } 179621Sbill if (gflag && Oflag) { 180621Sbill fprintf(stderr, "pc: warning: -g overrides -O\n"); 181621Sbill Oflag = 0; 182621Sbill } 183621Sbill tname[0] = mktemp("/tmp/p0XXXXXX"); 184621Sbill tname[1] = mktemp("/tmp/p1XXXXXX"); 185621Sbill savargx = pc0argx; 186621Sbill for (i = 0; i < argc; i++) { 187621Sbill argp = argv[i]; 188621Sbill if (argp[0] == '-') 189621Sbill continue; 1901211Speter if (suffix(argp) == 's') { 1911211Speter asargx = 1; 1921211Speter if (Jflag) 1931211Speter asargs[asargx++] = "-J"; 1941211Speter asargs[asargx++] = argp; 1951211Speter asargs[asargx++] = "-o"; 1961211Speter tfile[1] = setsuf(argp, 'o'); 1971211Speter asargs[asargx++] = tfile[1]; 1981211Speter asargs[asargx] = 0; 1991211Speter if (dosys(as, asargs, 0, 0)) 2001211Speter continue; 2011211Speter tfile[1] = 0; 2021211Speter continue; 2031211Speter } 204621Sbill if (suffix(argp) != 'p') 205621Sbill continue; 206621Sbill tfile[0] = tname[0]; 207621Sbill pc0args[2] = tfile[0]; 208621Sbill pc0argx = savargx; 209654Sbill if (pflag) 210654Sbill pc0args[pc0argx++] = "-p"; 211621Sbill pc0args[pc0argx++] = argp; 212621Sbill pc0args[pc0argx] = 0; 213621Sbill if (dosys(pc0, pc0args, 0, 0)) 214621Sbill continue; 215621Sbill pc1args[1] = tfile[0]; 216654Sbill tfile[1] = tname[1]; 217621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 218621Sbill continue; 219621Sbill unlink(tfile[0]); 2202340Smckusic tfile[0] = tname[0]; 2212340Smckusic if (Oflag) { 2222340Smckusic if (dosys(c2, c2args, tfile[1], tfile[0])) 2232340Smckusic continue; 2242340Smckusic unlink(tfile[1]); 2252340Smckusic tfile[1] = tfile[0]; 2262340Smckusic tfile[0] = tname[1]; 2272340Smckusic } 2282340Smckusic if (Sflag) 229654Sbill tfile[0] = setsuf(argp, 's'); 230621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 231621Sbill continue; 232621Sbill unlink(tfile[1]); 233621Sbill tfile[1] = 0; 234654Sbill if (Sflag) { 235654Sbill tfile[0] = 0; 236621Sbill continue; 237654Sbill } 238908Sbill asargx = 1; 239908Sbill if (Jflag) 240908Sbill asargs[asargx++] = "-J"; 241908Sbill asargs[asargx++] = tfile[0]; 242908Sbill asargs[asargx++] = "-o"; 243621Sbill tfile[1] = setsuf(argp, 'o'); 244908Sbill asargs[asargx++] = tfile[1]; 245908Sbill asargs[asargx] = 0; 246621Sbill if (dosys(as, asargs, 0, 0)) 247621Sbill continue; 248621Sbill tfile[1] = 0; 249621Sbill remove(); 250621Sbill } 251621Sbill if (errs || cflag || Sflag) 252621Sbill done(); 253621Sbill /* char *pc3args[NARGS] = { "pc3", 0 }; */ 254621Sbill pc3args[0] = "pc3"; 255621Sbill for (i = 0; i < argc; i++) { 256621Sbill argp = argv[i]; 257621Sbill if (!strcmp(argp, "-o")) 258621Sbill i++; 259621Sbill if (argp[0] == '-') 260621Sbill continue; 261621Sbill switch (getsuf(argp)) { 262621Sbill 263621Sbill case 'o': 264621Sbill pc3args[pc3argx++] = argp; 265621Sbill nxo++; 266621Sbill continue; 2671211Speter case 's': 268621Sbill case 'p': 269621Sbill onepso = pc3args[pc3argx++] = 270621Sbill savestr(setsuf(argp, 'o')); 271621Sbill np++; 272621Sbill continue; 273621Sbill } 274621Sbill } 275621Sbill pc3args[pc3argx] = 0; 276621Sbill if (dosys(pc3, pc3args, 0, 0)) 277621Sbill done(); 278908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 279621Sbill ldargs[0] = "ld"; 280621Sbill ldargs[1] = "-X"; 281654Sbill ldargs[2] = crt0; 282621Sbill for (i = 0; i < argc; i++) { 283621Sbill argp = argv[i]; 284621Sbill if (argp[0] != '-') { 285621Sbill switch (getsuf(argp)) { 286621Sbill 287621Sbill case 'p': 2881211Speter case 's': 289621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 290621Sbill break; 291621Sbill default: 292621Sbill ldargs[ldargx] = argp; 293621Sbill break; 294621Sbill } 295621Sbill if (getsuf(ldargs[ldargx]) == 'o') 296621Sbill for (j = 0; j < ldargx; j++) 297621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 298621Sbill goto duplicate; 299621Sbill ldargx++; 300621Sbill duplicate: 301621Sbill continue; 302621Sbill } 303621Sbill switch (argp[1]) { 304621Sbill 305621Sbill case 'i': 306621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 307621Sbill getsuf(argv[i+1]) != 'p') 308621Sbill i++; 309621Sbill continue; 310621Sbill case 'd': 311621Sbill if (argp[2] == 0) 312621Sbill continue; 313621Sbill ldargs[ldargx++] = argp; 314621Sbill continue; 315621Sbill case 'o': 316621Sbill ldargs[ldargx++] = argp; 317621Sbill i++; 318621Sbill ldargs[ldargx++] = argv[i]; 319621Sbill continue; 320621Sbill case 'l': 321621Sbill if (argp[2]) 322621Sbill ldargs[ldargx++] = argp; 323621Sbill continue; 324621Sbill case 'c': 325621Sbill case 'g': 326621Sbill case 'w': 327621Sbill case 'p': 328621Sbill case 'S': 329908Sbill case 'J': 330621Sbill case 'T': 331621Sbill case 'O': 332621Sbill case 'C': 333621Sbill case 'b': 334621Sbill case 's': 335621Sbill case 'z': 336621Sbill continue; 337621Sbill default: 338621Sbill ldargs[ldargx++] = argp; 339621Sbill continue; 340621Sbill } 341621Sbill } 342621Sbill ldargs[ldargx++] = lpc; 343621Sbill if (gflag) 344621Sbill ldargs[ldargx++] = "-lg"; 3452128Smckusic ldargs[ldargx++] = "-lnm"; 346621Sbill ldargs[ldargx++] = "-lc"; 347621Sbill ldargs[ldargx] = 0; 348621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 349621Sbill unlink(onepso); 350621Sbill done(); 351621Sbill } 352621Sbill 353621Sbill dosys(cmd, argv, in, out) 354621Sbill char *cmd, **argv, *in, *out; 355621Sbill { 356621Sbill union wait status; 357621Sbill int pid; 358621Sbill 359621Sbill if (debug) { 360621Sbill int i; 361621Sbill printf("%s:", cmd); 362621Sbill for (i = 0; argv[i]; i++) 363621Sbill printf(" %s", argv[i]); 364621Sbill if (in) 365621Sbill printf(" <%s", in); 366621Sbill if (out) 367621Sbill printf(" >%s", out); 368621Sbill printf("\n"); 369621Sbill } 370621Sbill pid = vfork(); 371621Sbill if (pid < 0) { 372621Sbill fprintf(stderr, "pc: No more processes\n"); 373621Sbill done(); 374621Sbill } 375621Sbill if (pid == 0) { 376621Sbill if (in) { 377621Sbill close(0); 378621Sbill if (open(in, 0) != 0) { 379621Sbill perror(in); 380621Sbill exit(1); 381621Sbill } 382621Sbill } 383621Sbill if (out) { 384621Sbill close(1); 385621Sbill unlink(out); 386621Sbill if (creat(out, 0666) != 1) { 387621Sbill perror(out); 388621Sbill exit(1); 389621Sbill } 390621Sbill } 391621Sbill signal(SIGINT, SIG_DFL); 392621Sbill execv(cmd, argv); 393621Sbill perror(cmd); 394621Sbill exit(1); 395621Sbill } 396621Sbill while (wait(&status) != pid) 397621Sbill ; 398621Sbill if (WIFSIGNALED(status)) { 399621Sbill if (status.w_termsig != SIGINT) 400621Sbill fprintf(stderr, "Fatal error in %s\n", cmd); 401621Sbill errs = 100; 402621Sbill done(); 403621Sbill /*NOTREACHED*/ 404621Sbill } 405621Sbill if (status.w_retcode) { 406621Sbill errs = 1; 407621Sbill remove(); 408621Sbill } 409621Sbill return (status.w_retcode); 410621Sbill } 411621Sbill 412621Sbill done() 413621Sbill { 414621Sbill 415621Sbill remove(); 416621Sbill exit(errs); 417621Sbill } 418621Sbill 419621Sbill remove() 420621Sbill { 421621Sbill 422621Sbill if (tfile[0]) 423621Sbill unlink(tfile[0]); 424621Sbill if (tfile[1]) 425621Sbill unlink(tfile[1]); 426621Sbill } 427621Sbill 428621Sbill onintr() 429621Sbill { 430621Sbill 431621Sbill errs = 1; 432621Sbill done(); 433621Sbill } 434621Sbill 435621Sbill getsuf(cp) 436621Sbill char *cp; 437621Sbill { 438621Sbill 439621Sbill if (*cp == 0) 440621Sbill return; 441621Sbill while (cp[1]) 442621Sbill cp++; 443621Sbill if (cp[-1] != '.') 444621Sbill return (0); 445621Sbill return (*cp); 446621Sbill } 447621Sbill 448621Sbill char * 449654Sbill setsuf(as, ch) 450654Sbill char *as; 451621Sbill { 452654Sbill register char *s, *s1; 453621Sbill 454654Sbill s = s1 = savestr(as); 455654Sbill while (*s) 456654Sbill if (*s++ == '/') 457654Sbill s1 = s; 458654Sbill s[-1] = ch; 459654Sbill return (s1); 460621Sbill } 461621Sbill 462621Sbill #define NSAVETAB 512 463621Sbill char *savetab; 464621Sbill int saveleft; 465621Sbill 466621Sbill char * 467621Sbill savestr(cp) 468621Sbill register char *cp; 469621Sbill { 470621Sbill register int len; 471621Sbill 472621Sbill len = strlen(cp) + 1; 473621Sbill if (len > saveleft) { 474621Sbill saveleft = NSAVETAB; 475621Sbill if (len > saveleft) 476621Sbill saveleft = len; 477621Sbill savetab = (char *)malloc(saveleft); 478621Sbill if (savetab == 0) { 479621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 480621Sbill exit(1); 481621Sbill } 482621Sbill } 483621Sbill strncpy(savetab, cp, len); 484621Sbill cp = savetab; 485621Sbill savetab += len; 486621Sbill return (cp); 487621Sbill } 488621Sbill 489621Sbill suffix(cp) 490621Sbill char *cp; 491621Sbill { 492621Sbill 493621Sbill if (cp[0] == 0 || cp[1] == 0) 494621Sbill return (0); 495621Sbill while (cp[1]) 496621Sbill cp++; 497621Sbill if (cp[-1] == '.') 498621Sbill return (*cp); 499621Sbill return (0); 500621Sbill } 501