1*2340Smckusic static char sccsid[] = "@(#)pc.c 3.11 02/04/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"; 123621Sbill continue; 124621Sbill case '1': 125908Sbill pc1 = "/usr/src/cmd/pcc/pc1"; 126621Sbill continue; 127621Sbill case '2': 1282194Smckusic pc2 = "/usr/src/cmd/pascal/pc2"; 129621Sbill continue; 130621Sbill case '3': 1312194Smckusic pc3 = "/usr/src/cmd/pascal/pc3"; 132621Sbill continue; 133621Sbill case 'l': 1342127Smckusic lpc = "/usr/src/lib/libpc/libpc"; 135621Sbill continue; 136621Sbill } 137621Sbill continue; 138621Sbill case 'c': 139621Sbill cflag = 1; 140621Sbill continue; 141621Sbill case 'l': 142621Sbill if (argp[2]) 143621Sbill continue; 144621Sbill /* fall into ... */ 145621Sbill case 'b': 146621Sbill case 'g': 147621Sbill case 's': 148621Sbill case 'w': 149621Sbill case 'z': 150621Sbill case 'C': 151621Sbill pc0args[pc0argx++] = argp; 152621Sbill if (argp[1] == 'g') 153621Sbill gflag = 1; 154621Sbill continue; 155621Sbill case 't': 156621Sbill fprintf(stderr, "pc: -t is default; -C for checking\n"); 157621Sbill continue; 158621Sbill case 'p': 159654Sbill crt0 = mcrt0; 160654Sbill pflag++; 161654Sbill continue; 162621Sbill } 163621Sbill } 164621Sbill if (gflag && Oflag) { 165621Sbill fprintf(stderr, "pc: warning: -g overrides -O\n"); 166621Sbill Oflag = 0; 167621Sbill } 168621Sbill tname[0] = mktemp("/tmp/p0XXXXXX"); 169621Sbill tname[1] = mktemp("/tmp/p1XXXXXX"); 170621Sbill savargx = pc0argx; 171621Sbill for (i = 0; i < argc; i++) { 172621Sbill argp = argv[i]; 173621Sbill if (argp[0] == '-') 174621Sbill continue; 1751211Speter if (suffix(argp) == 's') { 1761211Speter asargx = 1; 1771211Speter if (Jflag) 1781211Speter asargs[asargx++] = "-J"; 1791211Speter asargs[asargx++] = argp; 1801211Speter asargs[asargx++] = "-o"; 1811211Speter tfile[1] = setsuf(argp, 'o'); 1821211Speter asargs[asargx++] = tfile[1]; 1831211Speter asargs[asargx] = 0; 1841211Speter if (dosys(as, asargs, 0, 0)) 1851211Speter continue; 1861211Speter tfile[1] = 0; 1871211Speter continue; 1881211Speter } 189621Sbill if (suffix(argp) != 'p') 190621Sbill continue; 191621Sbill tfile[0] = tname[0]; 192621Sbill pc0args[2] = tfile[0]; 193621Sbill pc0argx = savargx; 194654Sbill if (pflag) 195654Sbill pc0args[pc0argx++] = "-p"; 196621Sbill pc0args[pc0argx++] = argp; 197621Sbill pc0args[pc0argx] = 0; 198621Sbill if (dosys(pc0, pc0args, 0, 0)) 199621Sbill continue; 200621Sbill pc1args[1] = tfile[0]; 201654Sbill tfile[1] = tname[1]; 202621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 203621Sbill continue; 204621Sbill unlink(tfile[0]); 205*2340Smckusic tfile[0] = tname[0]; 206*2340Smckusic if (Oflag) { 207*2340Smckusic if (dosys(c2, c2args, tfile[1], tfile[0])) 208*2340Smckusic continue; 209*2340Smckusic unlink(tfile[1]); 210*2340Smckusic tfile[1] = tfile[0]; 211*2340Smckusic tfile[0] = tname[1]; 212*2340Smckusic } 213*2340Smckusic if (Sflag) 214654Sbill tfile[0] = setsuf(argp, 's'); 215621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 216621Sbill continue; 217621Sbill unlink(tfile[1]); 218621Sbill tfile[1] = 0; 219654Sbill if (Sflag) { 220654Sbill tfile[0] = 0; 221621Sbill continue; 222654Sbill } 223908Sbill asargx = 1; 224908Sbill if (Jflag) 225908Sbill asargs[asargx++] = "-J"; 226908Sbill asargs[asargx++] = tfile[0]; 227908Sbill asargs[asargx++] = "-o"; 228621Sbill tfile[1] = setsuf(argp, 'o'); 229908Sbill asargs[asargx++] = tfile[1]; 230908Sbill asargs[asargx] = 0; 231621Sbill if (dosys(as, asargs, 0, 0)) 232621Sbill continue; 233621Sbill tfile[1] = 0; 234621Sbill remove(); 235621Sbill } 236621Sbill if (errs || cflag || Sflag) 237621Sbill done(); 238621Sbill /* char *pc3args[NARGS] = { "pc3", 0 }; */ 239621Sbill pc3args[0] = "pc3"; 240621Sbill for (i = 0; i < argc; i++) { 241621Sbill argp = argv[i]; 242621Sbill if (!strcmp(argp, "-o")) 243621Sbill i++; 244621Sbill if (argp[0] == '-') 245621Sbill continue; 246621Sbill switch (getsuf(argp)) { 247621Sbill 248621Sbill case 'o': 249621Sbill pc3args[pc3argx++] = argp; 250621Sbill nxo++; 251621Sbill continue; 2521211Speter case 's': 253621Sbill case 'p': 254621Sbill onepso = pc3args[pc3argx++] = 255621Sbill savestr(setsuf(argp, 'o')); 256621Sbill np++; 257621Sbill continue; 258621Sbill } 259621Sbill } 260621Sbill pc3args[pc3argx] = 0; 261621Sbill if (dosys(pc3, pc3args, 0, 0)) 262621Sbill done(); 263908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 264621Sbill ldargs[0] = "ld"; 265621Sbill ldargs[1] = "-X"; 266654Sbill ldargs[2] = crt0; 267621Sbill for (i = 0; i < argc; i++) { 268621Sbill argp = argv[i]; 269621Sbill if (argp[0] != '-') { 270621Sbill switch (getsuf(argp)) { 271621Sbill 272621Sbill case 'p': 2731211Speter case 's': 274621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 275621Sbill break; 276621Sbill default: 277621Sbill ldargs[ldargx] = argp; 278621Sbill break; 279621Sbill } 280621Sbill if (getsuf(ldargs[ldargx]) == 'o') 281621Sbill for (j = 0; j < ldargx; j++) 282621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 283621Sbill goto duplicate; 284621Sbill ldargx++; 285621Sbill duplicate: 286621Sbill continue; 287621Sbill } 288621Sbill switch (argp[1]) { 289621Sbill 290621Sbill case 'i': 291621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 292621Sbill getsuf(argv[i+1]) != 'p') 293621Sbill i++; 294621Sbill continue; 295621Sbill case 'd': 296621Sbill if (argp[2] == 0) 297621Sbill continue; 298621Sbill ldargs[ldargx++] = argp; 299621Sbill continue; 300621Sbill case 'o': 301621Sbill ldargs[ldargx++] = argp; 302621Sbill i++; 303621Sbill ldargs[ldargx++] = argv[i]; 304621Sbill continue; 305621Sbill case 'l': 306621Sbill if (argp[2]) 307621Sbill ldargs[ldargx++] = argp; 308621Sbill continue; 309621Sbill case 'c': 310621Sbill case 'g': 311621Sbill case 'w': 312621Sbill case 'p': 313621Sbill case 'S': 314908Sbill case 'J': 315621Sbill case 'T': 316621Sbill case 'O': 317621Sbill case 'C': 318621Sbill case 'b': 319621Sbill case 's': 320621Sbill case 'z': 321621Sbill continue; 322621Sbill default: 323621Sbill ldargs[ldargx++] = argp; 324621Sbill continue; 325621Sbill } 326621Sbill } 327621Sbill ldargs[ldargx++] = lpc; 328621Sbill if (gflag) 329621Sbill ldargs[ldargx++] = "-lg"; 3302128Smckusic ldargs[ldargx++] = "-lnm"; 331621Sbill ldargs[ldargx++] = "-lc"; 332621Sbill ldargs[ldargx] = 0; 333621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 334621Sbill unlink(onepso); 335621Sbill done(); 336621Sbill } 337621Sbill 338621Sbill dosys(cmd, argv, in, out) 339621Sbill char *cmd, **argv, *in, *out; 340621Sbill { 341621Sbill union wait status; 342621Sbill int pid; 343621Sbill 344621Sbill if (debug) { 345621Sbill int i; 346621Sbill printf("%s:", cmd); 347621Sbill for (i = 0; argv[i]; i++) 348621Sbill printf(" %s", argv[i]); 349621Sbill if (in) 350621Sbill printf(" <%s", in); 351621Sbill if (out) 352621Sbill printf(" >%s", out); 353621Sbill printf("\n"); 354621Sbill } 355621Sbill pid = vfork(); 356621Sbill if (pid < 0) { 357621Sbill fprintf(stderr, "pc: No more processes\n"); 358621Sbill done(); 359621Sbill } 360621Sbill if (pid == 0) { 361621Sbill if (in) { 362621Sbill close(0); 363621Sbill if (open(in, 0) != 0) { 364621Sbill perror(in); 365621Sbill exit(1); 366621Sbill } 367621Sbill } 368621Sbill if (out) { 369621Sbill close(1); 370621Sbill unlink(out); 371621Sbill if (creat(out, 0666) != 1) { 372621Sbill perror(out); 373621Sbill exit(1); 374621Sbill } 375621Sbill } 376621Sbill signal(SIGINT, SIG_DFL); 377621Sbill execv(cmd, argv); 378621Sbill perror(cmd); 379621Sbill exit(1); 380621Sbill } 381621Sbill while (wait(&status) != pid) 382621Sbill ; 383621Sbill if (WIFSIGNALED(status)) { 384621Sbill if (status.w_termsig != SIGINT) 385621Sbill fprintf(stderr, "Fatal error in %s\n", cmd); 386621Sbill errs = 100; 387621Sbill done(); 388621Sbill /*NOTREACHED*/ 389621Sbill } 390621Sbill if (status.w_retcode) { 391621Sbill errs = 1; 392621Sbill remove(); 393621Sbill } 394621Sbill return (status.w_retcode); 395621Sbill } 396621Sbill 397621Sbill done() 398621Sbill { 399621Sbill 400621Sbill remove(); 401621Sbill exit(errs); 402621Sbill } 403621Sbill 404621Sbill remove() 405621Sbill { 406621Sbill 407621Sbill if (tfile[0]) 408621Sbill unlink(tfile[0]); 409621Sbill if (tfile[1]) 410621Sbill unlink(tfile[1]); 411621Sbill } 412621Sbill 413621Sbill onintr() 414621Sbill { 415621Sbill 416621Sbill errs = 1; 417621Sbill done(); 418621Sbill } 419621Sbill 420621Sbill getsuf(cp) 421621Sbill char *cp; 422621Sbill { 423621Sbill 424621Sbill if (*cp == 0) 425621Sbill return; 426621Sbill while (cp[1]) 427621Sbill cp++; 428621Sbill if (cp[-1] != '.') 429621Sbill return (0); 430621Sbill return (*cp); 431621Sbill } 432621Sbill 433621Sbill char * 434654Sbill setsuf(as, ch) 435654Sbill char *as; 436621Sbill { 437654Sbill register char *s, *s1; 438621Sbill 439654Sbill s = s1 = savestr(as); 440654Sbill while (*s) 441654Sbill if (*s++ == '/') 442654Sbill s1 = s; 443654Sbill s[-1] = ch; 444654Sbill return (s1); 445621Sbill } 446621Sbill 447621Sbill #define NSAVETAB 512 448621Sbill char *savetab; 449621Sbill int saveleft; 450621Sbill 451621Sbill char * 452621Sbill savestr(cp) 453621Sbill register char *cp; 454621Sbill { 455621Sbill register int len; 456621Sbill 457621Sbill len = strlen(cp) + 1; 458621Sbill if (len > saveleft) { 459621Sbill saveleft = NSAVETAB; 460621Sbill if (len > saveleft) 461621Sbill saveleft = len; 462621Sbill savetab = (char *)malloc(saveleft); 463621Sbill if (savetab == 0) { 464621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 465621Sbill exit(1); 466621Sbill } 467621Sbill } 468621Sbill strncpy(savetab, cp, len); 469621Sbill cp = savetab; 470621Sbill savetab += len; 471621Sbill return (cp); 472621Sbill } 473621Sbill 474621Sbill suffix(cp) 475621Sbill char *cp; 476621Sbill { 477621Sbill 478621Sbill if (cp[0] == 0 || cp[1] == 0) 479621Sbill return (0); 480621Sbill while (cp[1]) 481621Sbill cp++; 482621Sbill if (cp[-1] == '.') 483621Sbill return (*cp); 484621Sbill return (0); 485621Sbill } 486