1 static char sccsid[] = "@(#)pc.c 3.15 07/29/82"; 2 3 #include <stdio.h> 4 #include <signal.h> 5 #include <wait.h> 6 7 /* 8 * Pc - front end for Pascal compiler. 9 */ 10 char *pc0 = "/usr/lib/pc0"; 11 char *pc1 = "/lib/f1"; 12 char *pc2 = "/usr/lib/pc2"; 13 char *c2 = "/lib/c2"; 14 char *pc3 = "/usr/lib/pc3"; 15 char *ld = "/bin/ld"; 16 char *as = "/bin/as"; 17 char *lpc = "-lpc"; 18 char *crt0 = "/lib/crt0.o"; 19 char *mcrt0 = "/lib/mcrt0.o"; 20 char *gcrt0 = "/usr/lib/gcrt0.o"; 21 22 char *mktemp(); 23 char *tname[2]; 24 char *tfile[2]; 25 26 char *setsuf(), *savestr(); 27 28 int Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag, wflag; 29 int debug; 30 31 #define NARGS 512 32 int ldargx = 3; 33 int pc0argx = 3; 34 char *pc0args[NARGS] = { "pc0", "-o", "XXX" }; 35 char *pc1args[3] = { "pc1", 0, }; 36 char *pc2args[2] = { "pc2", 0 }; 37 char *c2args[4] = { "c2", 0, 0, 0 }; 38 int pc3argx = 1; 39 #define pc3args pc0args 40 #define ldargs pc0args 41 /* char *pc3args[NARGS] = { "pc3", 0 }; */ 42 /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 43 int asargx; 44 char *asargs[6] = { "as", 0, }; 45 46 /* 47 * If the number of .p arguments (np) is 1, and the number of .o arguments 48 * (nxo) is 0, and we successfully create an ``a.out'', then we remove 49 * the one .ps .o file (onepso). 50 */ 51 int np, nxo; 52 char *onepso; 53 int errs; 54 55 int onintr(); 56 57 main(argc, argv) 58 int argc; 59 char **argv; 60 { 61 register char *argp; 62 register int i; 63 int savargx; 64 char *t, c; 65 int j; 66 67 argc--, argv++; 68 if (argc == 0) { 69 execl("/bin/cat", "cat", "/usr/lib/how_pc"); 70 exit(1); 71 } 72 if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 73 signal(SIGINT, onintr); 74 signal(SIGTERM, onintr); 75 } 76 for (i = 0; i < argc; i++) { 77 argp = argv[i]; 78 if (argp[0] != '-') 79 continue; 80 switch (argp[1]) { 81 82 case 'd': 83 if (argp[2] == 0) 84 debug++; 85 continue; 86 case 'i': 87 pc0args[pc0argx++] = "-i"; 88 while (i+1 < argc && argv[i+1][0] != '-' && 89 getsuf(argv[i+1]) != 'p') { 90 pc0args[pc0argx++] = argv[i+1]; 91 i++; 92 } 93 if (i+1 == argc) { 94 fprintf(stderr, "pc: bad -i construction\n"); 95 exit(1); 96 } 97 continue; 98 case 'o': 99 i++; 100 if (i == argc) { 101 fprintf(stderr, "pc: -o must specify file\n"); 102 exit(1); 103 } 104 c = getsuf(argv[i]); 105 if (c == 'o' || c == 'p' || c == 'c') { 106 fprintf(stderr, "pc: -o would overwrite %s\n", 107 argv[i]); 108 exit(1); 109 } 110 continue; 111 case 'O': 112 Oflag = 1; 113 continue; 114 case 'S': 115 Sflag = 1; 116 continue; 117 case 'J': 118 Jflag = 1; 119 continue; 120 case 'T': 121 switch (argp[2]) { 122 123 case '0': 124 pc0 = "/usr/src/cmd/pc0/a.out"; 125 if (argp[3] != '\0') { 126 pc0 = &argp[3]; 127 } 128 continue; 129 case '1': 130 pc1 = "/usr/src/cmd/pcc/pc1"; 131 if (argp[3] != '\0') { 132 pc1 = &argp[3]; 133 } 134 continue; 135 case '2': 136 pc2 = "/usr/src/cmd/pascal/pc2"; 137 if (argp[3] != '\0') { 138 pc2 = &argp[3]; 139 } 140 continue; 141 case '3': 142 pc3 = "/usr/src/cmd/pascal/pc3"; 143 if (argp[3] != '\0') { 144 pc3 = &argp[3]; 145 } 146 continue; 147 case 'l': 148 Tlflag = 1; 149 lpc = "/usr/src/lib/libpc/libpc"; 150 if (argp[3] != '\0') { 151 lpc = &argp[3]; 152 } 153 continue; 154 } 155 continue; 156 case 'c': 157 cflag = 1; 158 continue; 159 case 'l': 160 if (argp[2]) 161 continue; 162 /* fall into ... */ 163 case 'b': 164 case 's': 165 case 'z': 166 case 'C': 167 pc0args[pc0argx++] = argp; 168 continue; 169 case 'w': 170 wflag = 1; 171 pc0args[pc0argx++] = argp; 172 continue; 173 case 'g': 174 gflag = 1; 175 pc0args[pc0argx++] = argp; 176 continue; 177 case 't': 178 fprintf(stderr, "pc: -t is default; -C for checking\n"); 179 continue; 180 case 'p': 181 if (argp[2] == 'g') 182 crt0 = gcrt0; 183 else 184 crt0 = mcrt0; 185 if (!Tlflag) 186 lpc = "-lpc_p"; 187 pflag = 1; 188 continue; 189 } 190 } 191 if (gflag && Oflag) { 192 fprintf(stderr, "pc: warning: -g overrides -O\n"); 193 Oflag = 0; 194 } 195 tname[0] = mktemp("/tmp/p0XXXXXX"); 196 tname[1] = mktemp("/tmp/p1XXXXXX"); 197 savargx = pc0argx; 198 for (i = 0; i < argc; i++) { 199 argp = argv[i]; 200 if (argp[0] == '-') 201 continue; 202 if (suffix(argp) == 's') { 203 asargx = 1; 204 if (Jflag) 205 asargs[asargx++] = "-J"; 206 asargs[asargx++] = argp; 207 asargs[asargx++] = "-o"; 208 tfile[1] = setsuf(argp, 'o'); 209 asargs[asargx++] = tfile[1]; 210 asargs[asargx] = 0; 211 if (dosys(as, asargs, 0, 0)) 212 continue; 213 tfile[1] = 0; 214 continue; 215 } 216 if (suffix(argp) != 'p') 217 continue; 218 tfile[0] = tname[0]; 219 pc0args[2] = tfile[0]; 220 pc0argx = savargx; 221 if (pflag) 222 pc0args[pc0argx++] = "-p"; 223 pc0args[pc0argx++] = argp; 224 pc0args[pc0argx] = 0; 225 if (dosys(pc0, pc0args, 0, 0)) 226 continue; 227 pc1args[1] = tfile[0]; 228 tfile[1] = tname[1]; 229 if (dosys(pc1, pc1args, 0, tfile[1])) 230 continue; 231 unlink(tfile[0]); 232 tfile[0] = tname[0]; 233 if (Oflag) { 234 if (dosys(c2, c2args, tfile[1], tfile[0])) 235 continue; 236 unlink(tfile[1]); 237 tfile[1] = tfile[0]; 238 tfile[0] = tname[1]; 239 } 240 if (Sflag) 241 tfile[0] = setsuf(argp, 's'); 242 if (dosys(pc2, pc2args, tfile[1], tfile[0])) 243 continue; 244 unlink(tfile[1]); 245 tfile[1] = 0; 246 if (Sflag) { 247 tfile[0] = 0; 248 continue; 249 } 250 asargx = 1; 251 if (Jflag) 252 asargs[asargx++] = "-J"; 253 asargs[asargx++] = tfile[0]; 254 asargs[asargx++] = "-o"; 255 tfile[1] = setsuf(argp, 'o'); 256 asargs[asargx++] = tfile[1]; 257 asargs[asargx] = 0; 258 if (dosys(as, asargs, 0, 0)) 259 continue; 260 tfile[1] = 0; 261 remove(); 262 } 263 if (errs || cflag || Sflag) 264 done(); 265 /* char *pc3args[NARGS] = { "pc3", 0 }; */ 266 pc3args[0] = "pc3"; 267 if (wflag) 268 pc3args[pc3argx++] = "-w"; 269 pc3args[pc3argx++] = "/usr/lib/pcexterns.o"; 270 for (i = 0; i < argc; i++) { 271 argp = argv[i]; 272 if (!strcmp(argp, "-o")) 273 i++; 274 if (argp[0] == '-') 275 continue; 276 switch (getsuf(argp)) { 277 278 case 'o': 279 pc3args[pc3argx++] = argp; 280 nxo++; 281 continue; 282 case 's': 283 case 'p': 284 onepso = pc3args[pc3argx++] = 285 savestr(setsuf(argp, 'o')); 286 np++; 287 continue; 288 } 289 } 290 pc3args[pc3argx] = 0; 291 if (dosys(pc3, pc3args, 0, 0) > 1) 292 done(); 293 /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 294 ldargs[0] = "ld"; 295 ldargs[1] = "-X"; 296 ldargs[2] = crt0; 297 for (i = 0; i < argc; i++) { 298 argp = argv[i]; 299 if (argp[0] != '-') { 300 switch (getsuf(argp)) { 301 302 case 'p': 303 case 's': 304 ldargs[ldargx] = savestr(setsuf(argp, 'o')); 305 break; 306 default: 307 ldargs[ldargx] = argp; 308 break; 309 } 310 if (getsuf(ldargs[ldargx]) == 'o') 311 for (j = 0; j < ldargx; j++) 312 if (!strcmp(ldargs[j], ldargs[ldargx])) 313 goto duplicate; 314 ldargx++; 315 duplicate: 316 continue; 317 } 318 switch (argp[1]) { 319 320 case 'i': 321 while (i+1 < argc && argv[i+1][0] != '-' && 322 getsuf(argv[i+1]) != 'p') 323 i++; 324 continue; 325 case 'd': 326 if (argp[2] == 0) 327 continue; 328 ldargs[ldargx++] = argp; 329 continue; 330 case 'o': 331 ldargs[ldargx++] = argp; 332 i++; 333 ldargs[ldargx++] = argv[i]; 334 continue; 335 case 'l': 336 if (argp[2]) 337 ldargs[ldargx++] = argp; 338 continue; 339 case 'c': 340 case 'g': 341 case 'w': 342 case 'p': 343 case 'S': 344 case 'J': 345 case 'T': 346 case 'O': 347 case 'C': 348 case 'b': 349 case 's': 350 case 'z': 351 continue; 352 default: 353 ldargs[ldargx++] = argp; 354 continue; 355 } 356 } 357 ldargs[ldargx++] = lpc; 358 if (gflag) 359 ldargs[ldargx++] = "-lg"; 360 if (pflag) { 361 ldargs[ldargx++] = "-lm_p"; 362 ldargs[ldargx++] = "-lc_p"; 363 } else { 364 ldargs[ldargx++] = "-lm"; 365 ldargs[ldargx++] = "-lc"; 366 } 367 ldargs[ldargx] = 0; 368 if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 369 unlink(onepso); 370 done(); 371 } 372 373 dosys(cmd, argv, in, out) 374 char *cmd, **argv, *in, *out; 375 { 376 union wait status; 377 int pid; 378 379 if (debug) { 380 int i; 381 printf("%s:", cmd); 382 for (i = 0; argv[i]; i++) 383 printf(" %s", argv[i]); 384 if (in) 385 printf(" <%s", in); 386 if (out) 387 printf(" >%s", out); 388 printf("\n"); 389 } 390 pid = vfork(); 391 if (pid < 0) { 392 fprintf(stderr, "pc: No more processes\n"); 393 done(); 394 } 395 if (pid == 0) { 396 if (in) { 397 close(0); 398 if (open(in, 0) != 0) { 399 perror(in); 400 exit(1); 401 } 402 } 403 if (out) { 404 close(1); 405 unlink(out); 406 if (creat(out, 0666) != 1) { 407 perror(out); 408 exit(1); 409 } 410 } 411 signal(SIGINT, SIG_DFL); 412 execv(cmd, argv); 413 perror(cmd); 414 exit(1); 415 } 416 while (wait(&status) != pid) 417 ; 418 if (WIFSIGNALED(status)) { 419 if (status.w_termsig != SIGINT) 420 fprintf(stderr, "Fatal error in %s\n", cmd); 421 errs = 100; 422 done(); 423 /*NOTREACHED*/ 424 } 425 if (status.w_retcode) { 426 errs = 1; 427 remove(); 428 } 429 return (status.w_retcode); 430 } 431 432 done() 433 { 434 435 remove(); 436 exit(errs); 437 } 438 439 remove() 440 { 441 442 if (tfile[0]) 443 unlink(tfile[0]); 444 if (tfile[1]) 445 unlink(tfile[1]); 446 } 447 448 onintr() 449 { 450 451 errs = 1; 452 done(); 453 } 454 455 getsuf(cp) 456 char *cp; 457 { 458 459 if (*cp == 0) 460 return; 461 while (cp[1]) 462 cp++; 463 if (cp[-1] != '.') 464 return (0); 465 return (*cp); 466 } 467 468 char * 469 setsuf(as, ch) 470 char *as; 471 { 472 register char *s, *s1; 473 474 s = s1 = savestr(as); 475 while (*s) 476 if (*s++ == '/') 477 s1 = s; 478 s[-1] = ch; 479 return (s1); 480 } 481 482 #define NSAVETAB 512 483 char *savetab; 484 int saveleft; 485 486 char * 487 savestr(cp) 488 register char *cp; 489 { 490 register int len; 491 492 len = strlen(cp) + 1; 493 if (len > saveleft) { 494 saveleft = NSAVETAB; 495 if (len > saveleft) 496 saveleft = len; 497 savetab = (char *)malloc(saveleft); 498 if (savetab == 0) { 499 fprintf(stderr, "ran out of memory (savestr)\n"); 500 exit(1); 501 } 502 } 503 strncpy(savetab, cp, len); 504 cp = savetab; 505 savetab += len; 506 return (cp); 507 } 508 509 suffix(cp) 510 char *cp; 511 { 512 513 if (cp[0] == 0 || cp[1] == 0) 514 return (0); 515 while (cp[1]) 516 cp++; 517 if (cp[-1] == '.') 518 return (*cp); 519 return (0); 520 } 521