1 static char sccsid[] = "@(#)pc.c 3.19 02/01/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 errs = 0; 330 /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 331 ldargs[0] = "ld"; 332 ldargs[1] = "-X"; 333 ldargs[2] = crt0; 334 for (i = 0; i < argc; i++) { 335 argp = argv[i]; 336 if (argp[0] != '-') { 337 switch (getsuf(argp)) { 338 339 case 'p': 340 case 's': 341 ldargs[ldargx] = savestr(setsuf(argp, 'o')); 342 break; 343 default: 344 ldargs[ldargx] = argp; 345 break; 346 } 347 if (getsuf(ldargs[ldargx]) == 'o') 348 for (j = 0; j < ldargx; j++) 349 if (!strcmp(ldargs[j], ldargs[ldargx])) 350 goto duplicate; 351 ldargx++; 352 duplicate: 353 continue; 354 } 355 switch (argp[1]) { 356 357 case 'i': 358 while (i+1 < argc && argv[i+1][0] != '-' && 359 getsuf(argv[i+1]) != 'p') 360 i++; 361 continue; 362 case 'd': 363 if (argp[2] == 0) 364 continue; 365 ldargs[ldargx++] = argp; 366 continue; 367 case 'o': 368 ldargs[ldargx++] = argp; 369 i++; 370 ldargs[ldargx++] = argv[i]; 371 continue; 372 case 'l': 373 if (argp[2]) 374 ldargs[ldargx++] = argp; 375 continue; 376 case 'c': 377 case 'g': 378 case 'w': 379 case 'p': 380 case 'S': 381 case 'J': 382 case 'T': 383 case 'O': 384 case 'C': 385 case 'b': 386 case 's': 387 case 'z': 388 continue; 389 default: 390 ldargs[ldargx++] = argp; 391 continue; 392 } 393 } 394 ldargs[ldargx++] = lpc; 395 if (gflag) 396 ldargs[ldargx++] = "-lg"; 397 if (pflag) { 398 ldargs[ldargx++] = "-lm_p"; 399 ldargs[ldargx++] = "-lc_p"; 400 } else { 401 #ifndef sun 402 ldargs[ldargx++] = "-lm"; 403 ldargs[ldargx++] = "-lc"; 404 #else 405 ldargs[ldargx++] = "-lMm"; 406 ldargs[ldargx++] = "-lMc"; 407 #endif 408 } 409 ldargs[ldargx] = 0; 410 if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 411 unlink(onepso); 412 done(); 413 } 414 415 dosys(cmd, argv, in, out) 416 char *cmd, **argv, *in, *out; 417 { 418 union wait status; 419 int pid; 420 421 if (debug) { 422 int i; 423 printf("%s:", cmd); 424 for (i = 0; argv[i]; i++) 425 printf(" %s", argv[i]); 426 if (in) 427 printf(" <%s", in); 428 if (out) 429 printf(" >%s", out); 430 printf("\n"); 431 } 432 pid = vfork(); 433 if (pid < 0) { 434 fprintf(stderr, "pc: No more processes\n"); 435 done(); 436 } 437 if (pid == 0) { 438 if (in) { 439 close(0); 440 if (open(in, 0) != 0) { 441 perror(in); 442 exit(1); 443 } 444 } 445 if (out) { 446 close(1); 447 unlink(out); 448 if (creat(out, 0666) != 1) { 449 perror(out); 450 exit(1); 451 } 452 } 453 signal(SIGINT, SIG_DFL); 454 execv(cmd, argv); 455 perror(cmd); 456 exit(1); 457 } 458 while (wait(&status) != pid) 459 ; 460 if (WIFSIGNALED(status)) { 461 if (status.w_termsig != SIGINT) { 462 fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 463 if (status.w_coredump) 464 fprintf(stderr, " (core dumped)"); 465 fprintf(stderr, "\n"); 466 } 467 errs = 100; 468 done(); 469 /*NOTREACHED*/ 470 } 471 if (status.w_retcode) { 472 errs = 1; 473 remove(); 474 } 475 return (status.w_retcode); 476 } 477 478 done() 479 { 480 481 remove(); 482 exit(errs); 483 } 484 485 remove() 486 { 487 488 if (tfile[0]) 489 unlink(tfile[0]); 490 if (tfile[1]) 491 unlink(tfile[1]); 492 } 493 494 onintr() 495 { 496 497 errs = 1; 498 done(); 499 } 500 501 getsuf(cp) 502 char *cp; 503 { 504 505 if (*cp == 0) 506 return; 507 while (cp[1]) 508 cp++; 509 if (cp[-1] != '.') 510 return (0); 511 return (*cp); 512 } 513 514 char * 515 setsuf(as, ch) 516 char *as; 517 { 518 register char *s, *s1; 519 520 s = s1 = savestr(as); 521 while (*s) 522 if (*s++ == '/') 523 s1 = s; 524 s[-1] = ch; 525 return (s1); 526 } 527 528 #define NSAVETAB 512 529 char *savetab; 530 int saveleft; 531 532 char * 533 savestr(cp) 534 register char *cp; 535 { 536 register int len; 537 538 len = strlen(cp) + 1; 539 if (len > saveleft) { 540 saveleft = NSAVETAB; 541 if (len > saveleft) 542 saveleft = len; 543 savetab = (char *)malloc(saveleft); 544 if (savetab == 0) { 545 fprintf(stderr, "ran out of memory (savestr)\n"); 546 exit(1); 547 } 548 } 549 strncpy(savetab, cp, len); 550 cp = savetab; 551 savetab += len; 552 return (cp); 553 } 554 555 suffix(cp) 556 char *cp; 557 { 558 559 if (cp[0] == 0 || cp[1] == 0) 560 return (0); 561 while (cp[1]) 562 cp++; 563 if (cp[-1] == '.') 564 return (*cp); 565 return (0); 566 } 567