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