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