1 static char sccsid[] = "@(#)pc.c 3.23 06/06/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 pc0args[pc0argx++] = argp; 287 pc0args[pc0argx] = 0; 288 if (dosys(pc0, pc0args, 0, 0)) 289 continue; 290 pc1args[1] = tfile[0]; 291 tfile[1] = tname[1]; 292 if (dosys(pc1, pc1args, 0, tfile[1])) 293 continue; 294 unlink(tfile[0]); 295 tfile[0] = tname[0]; 296 if (Oflag) { 297 if (dosys(c2, c2args, tfile[1], tfile[0])) 298 continue; 299 unlink(tfile[1]); 300 tfile[1] = tfile[0]; 301 tfile[0] = tname[1]; 302 } 303 if (Sflag) 304 tfile[0] = setsuf(argp, 's'); 305 if (dosys(pc2, pc2args, tfile[1], tfile[0])) 306 continue; 307 unlink(tfile[1]); 308 tfile[1] = 0; 309 if (Sflag) { 310 tfile[0] = 0; 311 continue; 312 } 313 asargx = 1; 314 if (Jflag) 315 asargs[asargx++] = "-J"; 316 # ifdef vax 317 if (tflag) { 318 asargs[asargx++] = "-t"; 319 asargs[asargx++] = tmpdir; 320 } 321 # endif vax 322 asargs[asargx++] = tfile[0]; 323 asargs[asargx++] = "-o"; 324 tfile[1] = setsuf(argp, 'o'); 325 asargs[asargx++] = tfile[1]; 326 asargs[asargx] = 0; 327 if (dosys(as, asargs, 0, 0)) 328 continue; 329 tfile[1] = 0; 330 remove(); 331 } 332 if (errs || cflag || Sflag) 333 done(); 334 /* char *pc3args[NARGS] = { "pc3", 0 }; */ 335 pc3args[0] = "pc3"; 336 if (wflag) 337 pc3args[pc3argx++] = "-w"; 338 pc3args[pc3argx++] = "/usr/lib/pcexterns.o"; 339 for (i = 0; i < argc; i++) { 340 argp = argv[i]; 341 if (!strcmp(argp, "-o")) 342 i++; 343 if (argp[0] == '-') 344 continue; 345 switch (getsuf(argp)) { 346 347 case 'o': 348 pc3args[pc3argx++] = argp; 349 nxo++; 350 continue; 351 case 's': 352 case 'p': 353 onepso = pc3args[pc3argx++] = 354 savestr(setsuf(argp, 'o')); 355 np++; 356 continue; 357 } 358 } 359 pc3args[pc3argx] = 0; 360 if (dosys(pc3, pc3args, 0, 0) > 1) 361 done(); 362 errs = 0; 363 /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 364 ldargs[0] = "ld"; 365 ldargs[1] = "-X"; 366 ldargs[2] = crt0; 367 for (i = 0; i < argc; i++) { 368 argp = argv[i]; 369 if (argp[0] != '-') { 370 switch (getsuf(argp)) { 371 372 case 'p': 373 case 's': 374 ldargs[ldargx] = savestr(setsuf(argp, 'o')); 375 break; 376 default: 377 ldargs[ldargx] = argp; 378 break; 379 } 380 if (getsuf(ldargs[ldargx]) == 'o') 381 for (j = 0; j < ldargx; j++) 382 if (!strcmp(ldargs[j], ldargs[ldargx])) 383 goto duplicate; 384 ldargx++; 385 duplicate: 386 continue; 387 } 388 switch (argp[1]) { 389 390 case 'i': 391 while (i+1 < argc && argv[i+1][0] != '-' && 392 getsuf(argv[i+1]) != 'p') 393 i++; 394 continue; 395 case 'd': 396 if (argp[2] == 0) 397 continue; 398 ldargs[ldargx++] = argp; 399 continue; 400 case 'o': 401 ldargs[ldargx++] = argp; 402 i++; 403 ldargs[ldargx++] = argv[i]; 404 continue; 405 case 'l': 406 if (argp[2]) 407 ldargs[ldargx++] = argp; 408 continue; 409 case 't': 410 i++; 411 continue; 412 case 'c': 413 case 'g': 414 case 'w': 415 case 'p': 416 case 'S': 417 case 'J': 418 case 'T': 419 case 'O': 420 case 'C': 421 case 'b': 422 case 's': 423 case 'z': 424 continue; 425 default: 426 ldargs[ldargx++] = argp; 427 continue; 428 } 429 } 430 ldargs[ldargx++] = lpc; 431 if (gflag) 432 ldargs[ldargx++] = "-lg"; 433 if (pflag) { 434 ldargs[ldargx++] = "-lm_p"; 435 ldargs[ldargx++] = "-lc_p"; 436 } else { 437 ldargs[ldargx++] = "-lm"; 438 ldargs[ldargx++] = "-lc"; 439 } 440 ldargs[ldargx] = 0; 441 if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 442 unlink(onepso); 443 done(); 444 } 445 446 dosys(cmd, argv, in, out) 447 char *cmd, **argv, *in, *out; 448 { 449 union wait status; 450 int pid; 451 452 if (debug) { 453 int i; 454 printf("%s:", cmd); 455 for (i = 0; argv[i]; i++) 456 printf(" %s", argv[i]); 457 if (in) 458 printf(" <%s", in); 459 if (out) 460 printf(" >%s", out); 461 printf("\n"); 462 } 463 pid = vfork(); 464 if (pid < 0) { 465 fprintf(stderr, "pc: No more processes\n"); 466 done(); 467 } 468 if (pid == 0) { 469 if (in) { 470 close(0); 471 if (open(in, 0) != 0) { 472 perror(in); 473 exit(1); 474 } 475 } 476 if (out) { 477 close(1); 478 unlink(out); 479 if (creat(out, 0666) != 1) { 480 perror(out); 481 exit(1); 482 } 483 } 484 signal(SIGINT, SIG_DFL); 485 execv(cmd, argv); 486 perror(cmd); 487 exit(1); 488 } 489 while (wait(&status) != pid) 490 ; 491 if (WIFSIGNALED(status)) { 492 if (status.w_termsig != SIGINT) { 493 fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 494 if (status.w_coredump) 495 fprintf(stderr, " (core dumped)"); 496 fprintf(stderr, "\n"); 497 } 498 errs = 100; 499 done(); 500 /*NOTREACHED*/ 501 } 502 if (status.w_retcode) { 503 errs = 1; 504 remove(); 505 } 506 return (status.w_retcode); 507 } 508 509 done() 510 { 511 512 remove(); 513 exit(errs); 514 } 515 516 remove() 517 { 518 519 if (tfile[0]) 520 unlink(tfile[0]); 521 if (tfile[1]) 522 unlink(tfile[1]); 523 } 524 525 onintr() 526 { 527 528 errs = 1; 529 done(); 530 } 531 532 getsuf(cp) 533 char *cp; 534 { 535 536 if (*cp == 0) 537 return; 538 while (cp[1]) 539 cp++; 540 if (cp[-1] != '.') 541 return (0); 542 return (*cp); 543 } 544 545 char * 546 setsuf(as, ch) 547 char *as; 548 { 549 register char *s, *s1; 550 551 s = s1 = savestr(as); 552 while (*s) 553 if (*s++ == '/') 554 s1 = s; 555 s[-1] = ch; 556 return (s1); 557 } 558 559 #define NSAVETAB 512 560 char *savetab; 561 int saveleft; 562 563 char * 564 savestr(cp) 565 register char *cp; 566 { 567 register int len; 568 569 len = strlen(cp) + 1; 570 if (len > saveleft) { 571 saveleft = NSAVETAB; 572 if (len > saveleft) 573 saveleft = len; 574 savetab = (char *)malloc(saveleft); 575 if (savetab == 0) { 576 fprintf(stderr, "ran out of memory (savestr)\n"); 577 exit(1); 578 } 579 } 580 strncpy(savetab, cp, len); 581 cp = savetab; 582 savetab += len; 583 return (cp); 584 } 585 586 suffix(cp) 587 char *cp; 588 { 589 590 if (cp[0] == 0 || cp[1] == 0) 591 return (0); 592 while (cp[1]) 593 cp++; 594 if (cp[-1] == '.') 595 return (*cp); 596 return (0); 597 } 598