1*816Sbill static char sccsid[] = "@(#)pc.c 3.4 08/29/80"; 2621Sbill #include <stdio.h> 3621Sbill #include <signal.h> 4621Sbill #include <wait.h> 5621Sbill 6621Sbill /* 7654Sbill * Pc - front end for Pascal compiler. 8621Sbill */ 9621Sbill char *pc0 = "/usr/new/pc0"; 10621Sbill char *pc1 = "/usr/new/pc1"; 11621Sbill char *pc2 = "/usr/new/pc2"; 12621Sbill char *c2 = "/usr/new/c2"; 13621Sbill char *pc3 = "/usr/new/pc3"; 14621Sbill char *ld = "/usr/new/ld"; 15621Sbill char *as = "/usr/new/as"; 16621Sbill char *lpc = "-lpc"; 17654Sbill char *crt0 = "/usr/new/crt0.o"; 18654Sbill char *mcrt0 = "/usr/new/mcrt0.o"; 19621Sbill 20621Sbill char *mktemp(); 21621Sbill char *tname[2]; 22621Sbill char *tfile[2]; 23621Sbill 24621Sbill char *setsuf(), *savestr(); 25621Sbill 26654Sbill int 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 }; */ 40621Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/usr/new/crt0.o", 0, }; */ 41621Sbill char *asargs[5] = { "as", 0, }; 42621Sbill 43621Sbill /* 44621Sbill * If the number of .p arguments (np) is 1, and the number of .o arguments 45621Sbill * (nxo) is 0, and we successfully create an ``a.out'', then we remove 46621Sbill * the one .ps .o file (onepso). 47621Sbill */ 48621Sbill int np, nxo; 49621Sbill char *onepso; 50621Sbill int errs; 51621Sbill 52621Sbill int onintr(); 53621Sbill 54621Sbill main(argc, argv) 55621Sbill int argc; 56621Sbill char **argv; 57621Sbill { 58621Sbill register char *argp; 59621Sbill register int i; 60621Sbill int savargx; 61621Sbill char *t, c; 62621Sbill int j; 63621Sbill 64621Sbill argc--, argv++; 65621Sbill if (argc == 0) { 66621Sbill execl("/bin/cat", "cat", "/usr/lib/how_pc"); 67621Sbill exit(1); 68621Sbill } 69621Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 70621Sbill signal(SIGINT, onintr); 71621Sbill signal(SIGTERM, onintr); 72621Sbill } 73621Sbill for (i = 0; i < argc; i++) { 74621Sbill argp = argv[i]; 75621Sbill if (argp[0] != '-') 76621Sbill continue; 77621Sbill switch (argp[1]) { 78621Sbill 79621Sbill case 'd': 80621Sbill if (argp[2] == 0) 81621Sbill debug++; 82621Sbill continue; 83621Sbill case 'i': 84621Sbill pc0args[pc0argx++] = "-i"; 85621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 86621Sbill getsuf(argv[i+1]) != 'p') { 87621Sbill pc0args[pc0argx++] = argv[i+1]; 88621Sbill i++; 89621Sbill } 90621Sbill if (i+1 == argc) { 91621Sbill fprintf(stderr, "pc: bad -i construction\n"); 92621Sbill exit(1); 93621Sbill } 94621Sbill continue; 95621Sbill case 'o': 96621Sbill i++; 97621Sbill if (i == argc) { 98621Sbill fprintf(stderr, "pc: -o must specify file\n"); 99621Sbill exit(1); 100621Sbill } 101621Sbill c = getsuf(argv[i]); 102621Sbill if (c == 'o' || c == 'p' || c == 'c') { 103621Sbill fprintf(stderr, "pc: -o would overwrite %s\n", 104621Sbill argv[i]); 105621Sbill exit(1); 106621Sbill } 107621Sbill continue; 108621Sbill case 'O': 109621Sbill Oflag = 1; 110621Sbill continue; 111621Sbill case 'S': 112621Sbill Sflag = 1; 113621Sbill continue; 114621Sbill case 'T': 115621Sbill switch (argp[2]) { 116621Sbill 117621Sbill case '0': 118*816Sbill pc0 = "/vb/grad/peter/pc/pc0/src/a.out"; 119621Sbill continue; 120621Sbill case '1': 121621Sbill pc1 = "/usr/src/new/pcc/pc1"; 122621Sbill continue; 123621Sbill case '2': 124621Sbill pc2 = "/usr/new/pc2"; 125621Sbill continue; 126621Sbill case '3': 127621Sbill pc3 = "/usr/new/pc3"; 128621Sbill continue; 129621Sbill case 'l': 130621Sbill lpc = "-lnpc"; 131621Sbill continue; 132621Sbill } 133621Sbill continue; 134621Sbill case 'c': 135621Sbill cflag = 1; 136621Sbill continue; 137621Sbill case 'l': 138621Sbill if (argp[2]) 139621Sbill continue; 140621Sbill /* fall into ... */ 141621Sbill case 'b': 142621Sbill case 'g': 143621Sbill case 's': 144621Sbill case 'w': 145621Sbill case 'z': 146621Sbill case 'C': 147621Sbill pc0args[pc0argx++] = argp; 148621Sbill if (argp[1] == 'g') 149621Sbill gflag = 1; 150621Sbill continue; 151621Sbill case 't': 152621Sbill fprintf(stderr, "pc: -t is default; -C for checking\n"); 153621Sbill continue; 154621Sbill case 'p': 155654Sbill crt0 = mcrt0; 156654Sbill pflag++; 157654Sbill continue; 158621Sbill } 159621Sbill } 160621Sbill if (gflag && Oflag) { 161621Sbill fprintf(stderr, "pc: warning: -g overrides -O\n"); 162621Sbill Oflag = 0; 163621Sbill } 164621Sbill tname[0] = mktemp("/tmp/p0XXXXXX"); 165621Sbill tname[1] = mktemp("/tmp/p1XXXXXX"); 166621Sbill savargx = pc0argx; 167621Sbill for (i = 0; i < argc; i++) { 168621Sbill argp = argv[i]; 169621Sbill if (argp[0] == '-') 170621Sbill continue; 171621Sbill if (suffix(argp) != 'p') 172621Sbill continue; 173621Sbill tfile[0] = tname[0]; 174621Sbill pc0args[2] = tfile[0]; 175621Sbill pc0argx = savargx; 176654Sbill if (pflag) 177654Sbill pc0args[pc0argx++] = "-p"; 178621Sbill pc0args[pc0argx++] = argp; 179621Sbill pc0args[pc0argx] = 0; 180621Sbill if (dosys(pc0, pc0args, 0, 0)) 181621Sbill continue; 182621Sbill pc1args[1] = tfile[0]; 183654Sbill tfile[1] = tname[1]; 184621Sbill if (dosys(pc1, pc1args, 0, tfile[1])) 185621Sbill continue; 186621Sbill unlink(tfile[0]); 187654Sbill if (Sflag && !Oflag) 188654Sbill tfile[0] = setsuf(argp, 's'); 189654Sbill else 190654Sbill tfile[0] = tname[0]; 191621Sbill if (dosys(pc2, pc2args, tfile[1], tfile[0])) 192621Sbill continue; 193621Sbill unlink(tfile[1]); 194621Sbill tfile[1] = 0; 195621Sbill if (Oflag) { 196621Sbill if (Sflag) 197621Sbill tfile[1] = setsuf(argp, 's'); 198621Sbill else 199654Sbill tfile[1] = tname[1]; 200621Sbill if (dosys(c2, c2args, tfile[0], tfile[1])) 201621Sbill continue; 202621Sbill unlink(tfile[0]); 203621Sbill tfile[0] = tfile[1]; 204621Sbill tfile[1] = 0; 205621Sbill } 206654Sbill if (Sflag) { 207654Sbill tfile[0] = 0; 208621Sbill continue; 209654Sbill } 210621Sbill asargs[1] = tfile[0]; 211621Sbill asargs[2] = "-o"; 212621Sbill tfile[1] = setsuf(argp, 'o'); 213621Sbill asargs[3] = tfile[1]; 214621Sbill if (dosys(as, asargs, 0, 0)) 215621Sbill continue; 216621Sbill tfile[1] = 0; 217621Sbill remove(); 218621Sbill } 219621Sbill if (errs || cflag || Sflag) 220621Sbill done(); 221621Sbill /* char *pc3args[NARGS] = { "pc3", 0 }; */ 222621Sbill pc3args[0] = "pc3"; 223621Sbill for (i = 0; i < argc; i++) { 224621Sbill argp = argv[i]; 225621Sbill if (!strcmp(argp, "-o")) 226621Sbill i++; 227621Sbill if (argp[0] == '-') 228621Sbill continue; 229621Sbill switch (getsuf(argp)) { 230621Sbill 231621Sbill case 'd': 232621Sbill continue; 233621Sbill case 'o': 234621Sbill pc3args[pc3argx++] = argp; 235621Sbill nxo++; 236621Sbill continue; 237621Sbill case 'p': 238621Sbill onepso = pc3args[pc3argx++] = 239621Sbill savestr(setsuf(argp, 'o')); 240621Sbill np++; 241621Sbill continue; 242621Sbill } 243621Sbill } 244621Sbill pc3args[pc3argx] = 0; 245621Sbill if (dosys(pc3, pc3args, 0, 0)) 246621Sbill done(); 247621Sbill /* char *ldargs[NARGS] = { "ld", "-X", "/usr/new/crt0.o", 0, }; */ 248621Sbill ldargs[0] = "ld"; 249621Sbill ldargs[1] = "-X"; 250654Sbill ldargs[2] = crt0; 251621Sbill for (i = 0; i < argc; i++) { 252621Sbill argp = argv[i]; 253621Sbill if (argp[0] != '-') { 254621Sbill switch (getsuf(argp)) { 255621Sbill 256621Sbill case 'p': 257621Sbill ldargs[ldargx] = savestr(setsuf(argp, 'o')); 258621Sbill break; 259621Sbill default: 260621Sbill ldargs[ldargx] = argp; 261621Sbill break; 262621Sbill } 263621Sbill if (getsuf(ldargs[ldargx]) == 'o') 264621Sbill for (j = 0; j < ldargx; j++) 265621Sbill if (!strcmp(ldargs[j], ldargs[ldargx])) 266621Sbill goto duplicate; 267621Sbill ldargx++; 268621Sbill duplicate: 269621Sbill continue; 270621Sbill } 271621Sbill switch (argp[1]) { 272621Sbill 273621Sbill case 'i': 274621Sbill while (i+1 < argc && argv[i+1][0] != '-' && 275621Sbill getsuf(argv[i+1]) != 'p') 276621Sbill i++; 277621Sbill continue; 278621Sbill case 'd': 279621Sbill if (argp[2] == 0) 280621Sbill continue; 281621Sbill ldargs[ldargx++] = argp; 282621Sbill continue; 283621Sbill case 'o': 284621Sbill ldargs[ldargx++] = argp; 285621Sbill i++; 286621Sbill ldargs[ldargx++] = argv[i]; 287621Sbill continue; 288621Sbill case 'l': 289621Sbill if (argp[2]) 290621Sbill ldargs[ldargx++] = argp; 291621Sbill continue; 292621Sbill case 'c': 293621Sbill case 'g': 294621Sbill case 'w': 295621Sbill case 'p': 296621Sbill case 'S': 297621Sbill case 'T': 298621Sbill case 'O': 299621Sbill case 'C': 300621Sbill case 'b': 301621Sbill case 's': 302621Sbill case 'z': 303621Sbill continue; 304621Sbill default: 305621Sbill ldargs[ldargx++] = argp; 306621Sbill continue; 307621Sbill } 308621Sbill } 309621Sbill ldargs[ldargx++] = lpc; 310621Sbill if (gflag) 311621Sbill ldargs[ldargx++] = "-lg"; 312*816Sbill ldargs[ldargx++] = "-lm"; 313621Sbill ldargs[ldargx++] = "-lc"; 314621Sbill ldargs[ldargx] = 0; 315621Sbill if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 316621Sbill unlink(onepso); 317621Sbill done(); 318621Sbill } 319621Sbill 320621Sbill dosys(cmd, argv, in, out) 321621Sbill char *cmd, **argv, *in, *out; 322621Sbill { 323621Sbill union wait status; 324621Sbill int pid; 325621Sbill 326621Sbill if (debug) { 327621Sbill int i; 328621Sbill printf("%s:", cmd); 329621Sbill for (i = 0; argv[i]; i++) 330621Sbill printf(" %s", argv[i]); 331621Sbill if (in) 332621Sbill printf(" <%s", in); 333621Sbill if (out) 334621Sbill printf(" >%s", out); 335621Sbill printf("\n"); 336621Sbill } 337621Sbill pid = vfork(); 338621Sbill if (pid < 0) { 339621Sbill fprintf(stderr, "pc: No more processes\n"); 340621Sbill done(); 341621Sbill } 342621Sbill if (pid == 0) { 343621Sbill if (in) { 344621Sbill close(0); 345621Sbill if (open(in, 0) != 0) { 346621Sbill perror(in); 347621Sbill exit(1); 348621Sbill } 349621Sbill } 350621Sbill if (out) { 351621Sbill close(1); 352621Sbill unlink(out); 353621Sbill if (creat(out, 0666) != 1) { 354621Sbill perror(out); 355621Sbill exit(1); 356621Sbill } 357621Sbill } 358621Sbill signal(SIGINT, SIG_DFL); 359621Sbill execv(cmd, argv); 360621Sbill perror(cmd); 361621Sbill exit(1); 362621Sbill } 363621Sbill while (wait(&status) != pid) 364621Sbill ; 365621Sbill if (WIFSIGNALED(status)) { 366621Sbill if (status.w_termsig != SIGINT) 367621Sbill fprintf(stderr, "Fatal error in %s\n", cmd); 368621Sbill errs = 100; 369621Sbill done(); 370621Sbill /*NOTREACHED*/ 371621Sbill } 372621Sbill if (status.w_retcode) { 373621Sbill errs = 1; 374621Sbill remove(); 375621Sbill } 376621Sbill return (status.w_retcode); 377621Sbill } 378621Sbill 379621Sbill done() 380621Sbill { 381621Sbill 382621Sbill remove(); 383621Sbill exit(errs); 384621Sbill } 385621Sbill 386621Sbill remove() 387621Sbill { 388621Sbill 389621Sbill if (tfile[0]) 390621Sbill unlink(tfile[0]); 391621Sbill if (tfile[1]) 392621Sbill unlink(tfile[1]); 393621Sbill } 394621Sbill 395621Sbill onintr() 396621Sbill { 397621Sbill 398621Sbill errs = 1; 399621Sbill done(); 400621Sbill } 401621Sbill 402621Sbill getsuf(cp) 403621Sbill char *cp; 404621Sbill { 405621Sbill 406621Sbill if (*cp == 0) 407621Sbill return; 408621Sbill while (cp[1]) 409621Sbill cp++; 410621Sbill if (cp[-1] != '.') 411621Sbill return (0); 412621Sbill return (*cp); 413621Sbill } 414621Sbill 415621Sbill char * 416654Sbill setsuf(as, ch) 417654Sbill char *as; 418621Sbill { 419654Sbill register char *s, *s1; 420621Sbill 421654Sbill s = s1 = savestr(as); 422654Sbill while (*s) 423654Sbill if (*s++ == '/') 424654Sbill s1 = s; 425654Sbill s[-1] = ch; 426654Sbill return (s1); 427621Sbill } 428621Sbill 429621Sbill #define NSAVETAB 512 430621Sbill char *savetab; 431621Sbill int saveleft; 432621Sbill 433621Sbill char * 434621Sbill savestr(cp) 435621Sbill register char *cp; 436621Sbill { 437621Sbill register int len; 438621Sbill 439621Sbill len = strlen(cp) + 1; 440621Sbill if (len > saveleft) { 441621Sbill saveleft = NSAVETAB; 442621Sbill if (len > saveleft) 443621Sbill saveleft = len; 444621Sbill savetab = (char *)malloc(saveleft); 445621Sbill if (savetab == 0) { 446621Sbill fprintf(stderr, "ran out of memory (savestr)\n"); 447621Sbill exit(1); 448621Sbill } 449621Sbill } 450621Sbill strncpy(savetab, cp, len); 451621Sbill cp = savetab; 452621Sbill savetab += len; 453621Sbill return (cp); 454621Sbill } 455621Sbill 456621Sbill suffix(cp) 457621Sbill char *cp; 458621Sbill { 459621Sbill 460621Sbill if (cp[0] == 0 || cp[1] == 0) 461621Sbill return (0); 462621Sbill while (cp[1]) 463621Sbill cp++; 464621Sbill if (cp[-1] == '.') 465621Sbill return (*cp); 466621Sbill return (0); 467621Sbill } 468