1 static char sccsid[] = "@(#)pc.c 3.22 06/01/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 tmpdir = argv[i]; 159 tflag = 1; 160 continue; 161 case 'O': 162 Oflag = 1; 163 continue; 164 case 'S': 165 Sflag = 1; 166 continue; 167 case 'J': 168 Jflag = 1; 169 continue; 170 case 'T': 171 switch (argp[2]) { 172 173 case '0': 174 pc0 = "/usr/src/ucb/pascal/pc0/a.out"; 175 if (argp[3] != '\0') { 176 pc0 = &argp[3]; 177 } 178 continue; 179 case '1': 180 pc1 = "/usr/src/lib/pcc/fort"; 181 if (argp[3] != '\0') { 182 pc1 = &argp[3]; 183 } 184 continue; 185 case '2': 186 pc2 = "/usr/src/ucb/pascal/utilities/pc2"; 187 if (argp[3] != '\0') { 188 pc2 = &argp[3]; 189 } 190 continue; 191 case '3': 192 pc3 = "/usr/src/ucb/pascal/utilities/pc3"; 193 if (argp[3] != '\0') { 194 pc3 = &argp[3]; 195 } 196 continue; 197 case 'l': 198 Tlflag = 1; 199 lpc = "/usr/src/usr.lib/libpc/libpc"; 200 if (argp[3] != '\0') { 201 lpc = &argp[3]; 202 } 203 continue; 204 } 205 continue; 206 case 'c': 207 cflag = 1; 208 continue; 209 case 'l': 210 if (argp[2]) 211 continue; 212 /* fall into ... */ 213 case 'b': 214 case 's': 215 case 'z': 216 case 'C': 217 pc0args[pc0argx++] = argp; 218 continue; 219 case 'w': 220 wflag = 1; 221 pc0args[pc0argx++] = argp; 222 continue; 223 case 'g': 224 gflag = 1; 225 pc0args[pc0argx++] = argp; 226 continue; 227 case 'p': 228 if (argp[2] == 'g') 229 crt0 = gcrt0; 230 else 231 crt0 = mcrt0; 232 if (!Tlflag) 233 lpc = "-lpc_p"; 234 pflag = 1; 235 continue; 236 } 237 } 238 if (gflag && Oflag) { 239 fprintf(stderr, "pc: warning: -g overrides -O\n"); 240 Oflag = 0; 241 } 242 sprintf(tmp0, "%s/%s", tmpdir, "p0XXXXXX"); 243 tname[0] = mktemp(tmp0); 244 sprintf(tmp1, "%s/%s", tmpdir, "p1XXXXXX"); 245 tname[1] = mktemp(tmp1); 246 savargx = pc0argx; 247 for (i = 0; i < argc; i++) { 248 argp = argv[i]; 249 if (argp[0] == '-') 250 continue; 251 if (suffix(argp) == 's') { 252 asargx = 1; 253 if (Jflag) 254 asargs[asargx++] = "-J"; 255 # ifdef vax 256 if (tflag) { 257 asargs[asargx++] = "-t"; 258 asargs[asargx++] = tmpdir; 259 } 260 # endif vax 261 asargs[asargx++] = argp; 262 asargs[asargx++] = "-o"; 263 tfile[1] = setsuf(argp, 'o'); 264 asargs[asargx++] = tfile[1]; 265 asargs[asargx] = 0; 266 if (dosys(as, asargs, 0, 0)) 267 continue; 268 tfile[1] = 0; 269 continue; 270 } 271 if (suffix(argp) != 'p') 272 continue; 273 tfile[0] = tname[0]; 274 pc0args[2] = tfile[0]; 275 pc0argx = savargx; 276 if (pflag) 277 pc0args[pc0argx++] = "-p"; 278 pc0args[pc0argx++] = argp; 279 pc0args[pc0argx] = 0; 280 if (dosys(pc0, pc0args, 0, 0)) 281 continue; 282 pc1args[1] = tfile[0]; 283 tfile[1] = tname[1]; 284 if (dosys(pc1, pc1args, 0, tfile[1])) 285 continue; 286 unlink(tfile[0]); 287 tfile[0] = tname[0]; 288 if (Oflag) { 289 if (dosys(c2, c2args, tfile[1], tfile[0])) 290 continue; 291 unlink(tfile[1]); 292 tfile[1] = tfile[0]; 293 tfile[0] = tname[1]; 294 } 295 if (Sflag) 296 tfile[0] = setsuf(argp, 's'); 297 if (dosys(pc2, pc2args, tfile[1], tfile[0])) 298 continue; 299 unlink(tfile[1]); 300 tfile[1] = 0; 301 if (Sflag) { 302 tfile[0] = 0; 303 continue; 304 } 305 asargx = 1; 306 if (Jflag) 307 asargs[asargx++] = "-J"; 308 # ifdef vax 309 if (tflag) { 310 asargs[asargx++] = "-t"; 311 asargs[asargx++] = tmpdir; 312 } 313 # endif vax 314 asargs[asargx++] = tfile[0]; 315 asargs[asargx++] = "-o"; 316 tfile[1] = setsuf(argp, 'o'); 317 asargs[asargx++] = tfile[1]; 318 asargs[asargx] = 0; 319 if (dosys(as, asargs, 0, 0)) 320 continue; 321 tfile[1] = 0; 322 remove(); 323 } 324 if (errs || cflag || Sflag) 325 done(); 326 /* char *pc3args[NARGS] = { "pc3", 0 }; */ 327 pc3args[0] = "pc3"; 328 if (wflag) 329 pc3args[pc3argx++] = "-w"; 330 pc3args[pc3argx++] = "/usr/lib/pcexterns.o"; 331 for (i = 0; i < argc; i++) { 332 argp = argv[i]; 333 if (!strcmp(argp, "-o")) 334 i++; 335 if (argp[0] == '-') 336 continue; 337 switch (getsuf(argp)) { 338 339 case 'o': 340 pc3args[pc3argx++] = argp; 341 nxo++; 342 continue; 343 case 's': 344 case 'p': 345 onepso = pc3args[pc3argx++] = 346 savestr(setsuf(argp, 'o')); 347 np++; 348 continue; 349 } 350 } 351 pc3args[pc3argx] = 0; 352 if (dosys(pc3, pc3args, 0, 0) > 1) 353 done(); 354 errs = 0; 355 /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 356 ldargs[0] = "ld"; 357 ldargs[1] = "-X"; 358 ldargs[2] = crt0; 359 for (i = 0; i < argc; i++) { 360 argp = argv[i]; 361 if (argp[0] != '-') { 362 switch (getsuf(argp)) { 363 364 case 'p': 365 case 's': 366 ldargs[ldargx] = savestr(setsuf(argp, 'o')); 367 break; 368 default: 369 ldargs[ldargx] = argp; 370 break; 371 } 372 if (getsuf(ldargs[ldargx]) == 'o') 373 for (j = 0; j < ldargx; j++) 374 if (!strcmp(ldargs[j], ldargs[ldargx])) 375 goto duplicate; 376 ldargx++; 377 duplicate: 378 continue; 379 } 380 switch (argp[1]) { 381 382 case 'i': 383 while (i+1 < argc && argv[i+1][0] != '-' && 384 getsuf(argv[i+1]) != 'p') 385 i++; 386 continue; 387 case 'd': 388 if (argp[2] == 0) 389 continue; 390 ldargs[ldargx++] = argp; 391 continue; 392 case 'o': 393 ldargs[ldargx++] = argp; 394 i++; 395 ldargs[ldargx++] = argv[i]; 396 continue; 397 case 'l': 398 if (argp[2]) 399 ldargs[ldargx++] = argp; 400 continue; 401 case 't': 402 i++; 403 continue; 404 case 'c': 405 case 'g': 406 case 'w': 407 case 'p': 408 case 'S': 409 case 'J': 410 case 'T': 411 case 'O': 412 case 'C': 413 case 'b': 414 case 's': 415 case 'z': 416 continue; 417 default: 418 ldargs[ldargx++] = argp; 419 continue; 420 } 421 } 422 ldargs[ldargx++] = lpc; 423 if (gflag) 424 ldargs[ldargx++] = "-lg"; 425 if (pflag) { 426 ldargs[ldargx++] = "-lm_p"; 427 ldargs[ldargx++] = "-lc_p"; 428 } else { 429 ldargs[ldargx++] = "-lm"; 430 ldargs[ldargx++] = "-lc"; 431 } 432 ldargs[ldargx] = 0; 433 if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 434 unlink(onepso); 435 done(); 436 } 437 438 dosys(cmd, argv, in, out) 439 char *cmd, **argv, *in, *out; 440 { 441 union wait status; 442 int pid; 443 444 if (debug) { 445 int i; 446 printf("%s:", cmd); 447 for (i = 0; argv[i]; i++) 448 printf(" %s", argv[i]); 449 if (in) 450 printf(" <%s", in); 451 if (out) 452 printf(" >%s", out); 453 printf("\n"); 454 } 455 pid = vfork(); 456 if (pid < 0) { 457 fprintf(stderr, "pc: No more processes\n"); 458 done(); 459 } 460 if (pid == 0) { 461 if (in) { 462 close(0); 463 if (open(in, 0) != 0) { 464 perror(in); 465 exit(1); 466 } 467 } 468 if (out) { 469 close(1); 470 unlink(out); 471 if (creat(out, 0666) != 1) { 472 perror(out); 473 exit(1); 474 } 475 } 476 signal(SIGINT, SIG_DFL); 477 execv(cmd, argv); 478 perror(cmd); 479 exit(1); 480 } 481 while (wait(&status) != pid) 482 ; 483 if (WIFSIGNALED(status)) { 484 if (status.w_termsig != SIGINT) { 485 fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 486 if (status.w_coredump) 487 fprintf(stderr, " (core dumped)"); 488 fprintf(stderr, "\n"); 489 } 490 errs = 100; 491 done(); 492 /*NOTREACHED*/ 493 } 494 if (status.w_retcode) { 495 errs = 1; 496 remove(); 497 } 498 return (status.w_retcode); 499 } 500 501 done() 502 { 503 504 remove(); 505 exit(errs); 506 } 507 508 remove() 509 { 510 511 if (tfile[0]) 512 unlink(tfile[0]); 513 if (tfile[1]) 514 unlink(tfile[1]); 515 } 516 517 onintr() 518 { 519 520 errs = 1; 521 done(); 522 } 523 524 getsuf(cp) 525 char *cp; 526 { 527 528 if (*cp == 0) 529 return; 530 while (cp[1]) 531 cp++; 532 if (cp[-1] != '.') 533 return (0); 534 return (*cp); 535 } 536 537 char * 538 setsuf(as, ch) 539 char *as; 540 { 541 register char *s, *s1; 542 543 s = s1 = savestr(as); 544 while (*s) 545 if (*s++ == '/') 546 s1 = s; 547 s[-1] = ch; 548 return (s1); 549 } 550 551 #define NSAVETAB 512 552 char *savetab; 553 int saveleft; 554 555 char * 556 savestr(cp) 557 register char *cp; 558 { 559 register int len; 560 561 len = strlen(cp) + 1; 562 if (len > saveleft) { 563 saveleft = NSAVETAB; 564 if (len > saveleft) 565 saveleft = len; 566 savetab = (char *)malloc(saveleft); 567 if (savetab == 0) { 568 fprintf(stderr, "ran out of memory (savestr)\n"); 569 exit(1); 570 } 571 } 572 strncpy(savetab, cp, len); 573 cp = savetab; 574 savetab += len; 575 return (cp); 576 } 577 578 suffix(cp) 579 char *cp; 580 { 581 582 if (cp[0] == 0 || cp[1] == 0) 583 return (0); 584 while (cp[1]) 585 cp++; 586 if (cp[-1] == '.') 587 return (*cp); 588 return (0); 589 } 590