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