1 static char sccsid[] = "@(#)pc.c 3.21 04/18/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/pascal/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/utilities/pc2"; 173 if (argp[3] != '\0') { 174 pc2 = &argp[3]; 175 } 176 continue; 177 case '3': 178 pc3 = "/usr/src/ucb/pascal/utilities/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 ldargs[ldargx++] = "-lm"; 402 ldargs[ldargx++] = "-lc"; 403 } 404 ldargs[ldargx] = 0; 405 if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 406 unlink(onepso); 407 done(); 408 } 409 410 dosys(cmd, argv, in, out) 411 char *cmd, **argv, *in, *out; 412 { 413 union wait status; 414 int pid; 415 416 if (debug) { 417 int i; 418 printf("%s:", cmd); 419 for (i = 0; argv[i]; i++) 420 printf(" %s", argv[i]); 421 if (in) 422 printf(" <%s", in); 423 if (out) 424 printf(" >%s", out); 425 printf("\n"); 426 } 427 pid = vfork(); 428 if (pid < 0) { 429 fprintf(stderr, "pc: No more processes\n"); 430 done(); 431 } 432 if (pid == 0) { 433 if (in) { 434 close(0); 435 if (open(in, 0) != 0) { 436 perror(in); 437 exit(1); 438 } 439 } 440 if (out) { 441 close(1); 442 unlink(out); 443 if (creat(out, 0666) != 1) { 444 perror(out); 445 exit(1); 446 } 447 } 448 signal(SIGINT, SIG_DFL); 449 execv(cmd, argv); 450 perror(cmd); 451 exit(1); 452 } 453 while (wait(&status) != pid) 454 ; 455 if (WIFSIGNALED(status)) { 456 if (status.w_termsig != SIGINT) { 457 fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]); 458 if (status.w_coredump) 459 fprintf(stderr, " (core dumped)"); 460 fprintf(stderr, "\n"); 461 } 462 errs = 100; 463 done(); 464 /*NOTREACHED*/ 465 } 466 if (status.w_retcode) { 467 errs = 1; 468 remove(); 469 } 470 return (status.w_retcode); 471 } 472 473 done() 474 { 475 476 remove(); 477 exit(errs); 478 } 479 480 remove() 481 { 482 483 if (tfile[0]) 484 unlink(tfile[0]); 485 if (tfile[1]) 486 unlink(tfile[1]); 487 } 488 489 onintr() 490 { 491 492 errs = 1; 493 done(); 494 } 495 496 getsuf(cp) 497 char *cp; 498 { 499 500 if (*cp == 0) 501 return; 502 while (cp[1]) 503 cp++; 504 if (cp[-1] != '.') 505 return (0); 506 return (*cp); 507 } 508 509 char * 510 setsuf(as, ch) 511 char *as; 512 { 513 register char *s, *s1; 514 515 s = s1 = savestr(as); 516 while (*s) 517 if (*s++ == '/') 518 s1 = s; 519 s[-1] = ch; 520 return (s1); 521 } 522 523 #define NSAVETAB 512 524 char *savetab; 525 int saveleft; 526 527 char * 528 savestr(cp) 529 register char *cp; 530 { 531 register int len; 532 533 len = strlen(cp) + 1; 534 if (len > saveleft) { 535 saveleft = NSAVETAB; 536 if (len > saveleft) 537 saveleft = len; 538 savetab = (char *)malloc(saveleft); 539 if (savetab == 0) { 540 fprintf(stderr, "ran out of memory (savestr)\n"); 541 exit(1); 542 } 543 } 544 strncpy(savetab, cp, len); 545 cp = savetab; 546 savetab += len; 547 return (cp); 548 } 549 550 suffix(cp) 551 char *cp; 552 { 553 554 if (cp[0] == 0 || cp[1] == 0) 555 return (0); 556 while (cp[1]) 557 cp++; 558 if (cp[-1] == '.') 559 return (*cp); 560 return (0); 561 } 562