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