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