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