1*1211Speter static char sccsid[] = "@(#)pc.c 3.7 10/06/80"; 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': 128908Sbill pc2 = "/usr/src/cmd/pc2/a.out"; 129621Sbill continue; 130621Sbill case '3': 131908Sbill pc3 = "/usr/src/cmd/pc3/a.out"; 132621Sbill continue; 133621Sbill case 'l': 134*1211Speter lpc = "/usr/src/lib/libpc/pclib"; 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; 175*1211Speter if (suffix(argp) == 's') { 176*1211Speter asargx = 1; 177*1211Speter if (Jflag) 178*1211Speter asargs[asargx++] = "-J"; 179*1211Speter asargs[asargx++] = argp; 180*1211Speter asargs[asargx++] = "-o"; 181*1211Speter tfile[1] = setsuf(argp, 'o'); 182*1211Speter asargs[asargx++] = tfile[1]; 183*1211Speter asargs[asargx] = 0; 184*1211Speter if (dosys(as, asargs, 0, 0)) 185*1211Speter continue; 186*1211Speter tfile[1] = 0; 187*1211Speter continue; 188*1211Speter } 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]); 205654Sbill if (Sflag && !Oflag) 206654Sbill tfile[0] = setsuf(argp, 's'); 207654Sbill else 208654Sbill tfile[0] = tname[0]; 209621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 210621Sbill continue; 211621Sbill unlink(tfile[1]); 212621Sbill tfile[1] = 0; 213621Sbill if (Oflag) { 214621Sbill if (Sflag) 215621Sbill tfile[1] = setsuf(argp, 's'); 216621Sbill else 217654Sbill tfile[1] = tname[1]; 218621Sbill if (dosys(c2, c2args, tfile[0], tfile[1])) 219621Sbill continue; 220621Sbill unlink(tfile[0]); 221621Sbill tfile[0] = tfile[1]; 222621Sbill tfile[1] = 0; 223621Sbill } 224654Sbill if (Sflag) { 225654Sbill tfile[0] = 0; 226621Sbill continue; 227654Sbill } 228908Sbill asargx = 1; 229908Sbill if (Jflag) 230908Sbill asargs[asargx++] = "-J"; 231908Sbill asargs[asargx++] = tfile[0]; 232908Sbill asargs[asargx++] = "-o"; 233621Sbill tfile[1] = setsuf(argp, 'o'); 234908Sbill asargs[asargx++] = tfile[1]; 235908Sbill asargs[asargx] = 0; 236621Sbill if (dosys(as, asargs, 0, 0)) 237621Sbill continue; 238621Sbill tfile[1] = 0; 239621Sbill remove(); 240621Sbill } 241621Sbill if (errs || cflag || Sflag) 242621Sbill done(); 243621Sbill /* char *pc3args[NARGS] = { "pc3", 0 }; */ 244621Sbill pc3args[0] = "pc3"; 245621Sbill for (i = 0; i < argc; i++) { 246621Sbill argp = argv[i]; 247621Sbill if (!strcmp(argp, "-o")) 248621Sbill i++; 249621Sbill if (argp[0] == '-') 250621Sbill continue; 251621Sbill switch (getsuf(argp)) { 252621Sbill 253621Sbill case 'o': 254621Sbill pc3args[pc3argx++] = argp; 255621Sbill nxo++; 256621Sbill continue; 257*1211Speter case 's': 258621Sbill case 'p': 259621Sbill onepso = pc3args[pc3argx++] = 260621Sbill savestr(setsuf(argp, 'o')); 261621Sbill np++; 262621Sbill continue; 263621Sbill } 264621Sbill } 265621Sbill pc3args[pc3argx] = 0; 266621Sbill if (dosys(pc3, pc3args, 0, 0)) 267621Sbill done(); 268908Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 269621Sbill ldargs[0] = "ld"; 270621Sbill ldargs[1] = "-X"; 271654Sbill ldargs[2] = crt0; 272621Sbill for (i = 0; i < argc; i++) { 273621Sbill argp = argv[i]; 274621Sbill if (argp[0] != '-') { 275621Sbill switch (getsuf(argp)) { 276621Sbill 277621Sbill case 'p': 278*1211Speter case 's': 279621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 280621Sbill break; 281621Sbill default: 282621Sbill ldargs[ldargx] = argp; 283621Sbill break; 284621Sbill } 285621Sbill if (getsuf(ldargs[ldargx]) == 'o') 286621Sbill for (j = 0; j < ldargx; j++) 287621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 288621Sbill goto duplicate; 289621Sbill ldargx++; 290621Sbill duplicate: 291621Sbill continue; 292621Sbill } 293621Sbill switch (argp[1]) { 294621Sbill 295621Sbill case 'i': 296621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 297621Sbill getsuf(argv[i+1]) != 'p') 298621Sbill i++; 299621Sbill continue; 300621Sbill case 'd': 301621Sbill if (argp[2] == 0) 302621Sbill continue; 303621Sbill ldargs[ldargx++] = argp; 304621Sbill continue; 305621Sbill case 'o': 306621Sbill ldargs[ldargx++] = argp; 307621Sbill i++; 308621Sbill ldargs[ldargx++] = argv[i]; 309621Sbill continue; 310621Sbill case 'l': 311621Sbill if (argp[2]) 312621Sbill ldargs[ldargx++] = argp; 313621Sbill continue; 314621Sbill case 'c': 315621Sbill case 'g': 316621Sbill case 'w': 317621Sbill case 'p': 318621Sbill case 'S': 319908Sbill case 'J': 320621Sbill case 'T': 321621Sbill case 'O': 322621Sbill case 'C': 323621Sbill case 'b': 324621Sbill case 's': 325621Sbill case 'z': 326621Sbill continue; 327621Sbill default: 328621Sbill ldargs[ldargx++] = argp; 329621Sbill continue; 330621Sbill } 331621Sbill } 332621Sbill ldargs[ldargx++] = lpc; 333621Sbill if (gflag) 334621Sbill ldargs[ldargx++] = "-lg"; 335816Sbill ldargs[ldargx++] = "-lm"; 336621Sbill ldargs[ldargx++] = "-lc"; 337621Sbill ldargs[ldargx] = 0; 338621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 339621Sbill unlink(onepso); 340621Sbill done(); 341621Sbill } 342621Sbill 343621Sbill dosys(cmd, argv, in, out) 344621Sbill char *cmd, **argv, *in, *out; 345621Sbill { 346621Sbill union wait status; 347621Sbill int pid; 348621Sbill 349621Sbill if (debug) { 350621Sbill int i; 351621Sbill printf("%s:", cmd); 352621Sbill for (i = 0; argv[i]; i++) 353621Sbill printf(" %s", argv[i]); 354621Sbill if (in) 355621Sbill printf(" <%s", in); 356621Sbill if (out) 357621Sbill printf(" >%s", out); 358621Sbill printf("\n"); 359621Sbill } 360621Sbill pid = vfork(); 361621Sbill if (pid < 0) { 362621Sbill fprintf(stderr, "pc: No more processes\n"); 363621Sbill done(); 364621Sbill } 365621Sbill if (pid == 0) { 366621Sbill if (in) { 367621Sbill close(0); 368621Sbill if (open(in, 0) != 0) { 369621Sbill perror(in); 370621Sbill exit(1); 371621Sbill } 372621Sbill } 373621Sbill if (out) { 374621Sbill close(1); 375621Sbill unlink(out); 376621Sbill if (creat(out, 0666) != 1) { 377621Sbill perror(out); 378621Sbill exit(1); 379621Sbill } 380621Sbill } 381621Sbill signal(SIGINT, SIG_DFL); 382621Sbill execv(cmd, argv); 383621Sbill perror(cmd); 384621Sbill exit(1); 385621Sbill } 386621Sbill while (wait(&status) != pid) 387621Sbill ; 388621Sbill if (WIFSIGNALED(status)) { 389621Sbill if (status.w_termsig != SIGINT) 390621Sbill fprintf(stderr, "Fatal error in %s\n", cmd); 391621Sbill errs = 100; 392621Sbill done(); 393621Sbill /*NOTREACHED*/ 394621Sbill } 395621Sbill if (status.w_retcode) { 396621Sbill errs = 1; 397621Sbill remove(); 398621Sbill } 399621Sbill return (status.w_retcode); 400621Sbill } 401621Sbill 402621Sbill done() 403621Sbill { 404621Sbill 405621Sbill remove(); 406621Sbill exit(errs); 407621Sbill } 408621Sbill 409621Sbill remove() 410621Sbill { 411621Sbill 412621Sbill if (tfile[0]) 413621Sbill unlink(tfile[0]); 414621Sbill if (tfile[1]) 415621Sbill unlink(tfile[1]); 416621Sbill } 417621Sbill 418621Sbill onintr() 419621Sbill { 420621Sbill 421621Sbill errs = 1; 422621Sbill done(); 423621Sbill } 424621Sbill 425621Sbill getsuf(cp) 426621Sbill char *cp; 427621Sbill { 428621Sbill 429621Sbill if (*cp == 0) 430621Sbill return; 431621Sbill while (cp[1]) 432621Sbill cp++; 433621Sbill if (cp[-1] != '.') 434621Sbill return (0); 435621Sbill return (*cp); 436621Sbill } 437621Sbill 438621Sbill char * 439654Sbill setsuf(as, ch) 440654Sbill char *as; 441621Sbill { 442654Sbill register char *s, *s1; 443621Sbill 444654Sbill s = s1 = savestr(as); 445654Sbill while (*s) 446654Sbill if (*s++ == '/') 447654Sbill s1 = s; 448654Sbill s[-1] = ch; 449654Sbill return (s1); 450621Sbill } 451621Sbill 452621Sbill #define NSAVETAB 512 453621Sbill char *savetab; 454621Sbill int saveleft; 455621Sbill 456621Sbill char * 457621Sbill savestr(cp) 458621Sbill register char *cp; 459621Sbill { 460621Sbill register int len; 461621Sbill 462621Sbill len = strlen(cp) + 1; 463621Sbill if (len > saveleft) { 464621Sbill saveleft = NSAVETAB; 465621Sbill if (len > saveleft) 466621Sbill saveleft = len; 467621Sbill savetab = (char *)malloc(saveleft); 468621Sbill if (savetab == 0) { 469621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 470621Sbill exit(1); 471621Sbill } 472621Sbill } 473621Sbill strncpy(savetab, cp, len); 474621Sbill cp = savetab; 475621Sbill savetab += len; 476621Sbill return (cp); 477621Sbill } 478621Sbill 479621Sbill suffix(cp) 480621Sbill char *cp; 481621Sbill { 482621Sbill 483621Sbill if (cp[0] == 0 || cp[1] == 0) 484621Sbill return (0); 485621Sbill while (cp[1]) 486621Sbill cp++; 487621Sbill if (cp[-1] == '.') 488621Sbill return (*cp); 489621Sbill return (0); 490621Sbill } 491