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