1 static char sccsid[] = "@(#)pc.c 3.7 10/06/80"; 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 continue; 124 case '1': 125 pc1 = "/usr/src/cmd/pcc/pc1"; 126 continue; 127 case '2': 128 pc2 = "/usr/src/cmd/pc2/a.out"; 129 continue; 130 case '3': 131 pc3 = "/usr/src/cmd/pc3/a.out"; 132 continue; 133 case 'l': 134 lpc = "/usr/src/lib/libpc/pclib"; 135 continue; 136 } 137 continue; 138 case 'c': 139 cflag = 1; 140 continue; 141 case 'l': 142 if (argp[2]) 143 continue; 144 /* fall into ... */ 145 case 'b': 146 case 'g': 147 case 's': 148 case 'w': 149 case 'z': 150 case 'C': 151 pc0args[pc0argx++] = argp; 152 if (argp[1] == 'g') 153 gflag = 1; 154 continue; 155 case 't': 156 fprintf(stderr, "pc: -t is default; -C for checking\n"); 157 continue; 158 case 'p': 159 crt0 = mcrt0; 160 pflag++; 161 continue; 162 } 163 } 164 if (gflag && Oflag) { 165 fprintf(stderr, "pc: warning: -g overrides -O\n"); 166 Oflag = 0; 167 } 168 tname[0] = mktemp("/tmp/p0XXXXXX"); 169 tname[1] = mktemp("/tmp/p1XXXXXX"); 170 savargx = pc0argx; 171 for (i = 0; i < argc; i++) { 172 argp = argv[i]; 173 if (argp[0] == '-') 174 continue; 175 if (suffix(argp) == 's') { 176 asargx = 1; 177 if (Jflag) 178 asargs[asargx++] = "-J"; 179 asargs[asargx++] = argp; 180 asargs[asargx++] = "-o"; 181 tfile[1] = setsuf(argp, 'o'); 182 asargs[asargx++] = tfile[1]; 183 asargs[asargx] = 0; 184 if (dosys(as, asargs, 0, 0)) 185 continue; 186 tfile[1] = 0; 187 continue; 188 } 189 if (suffix(argp) != 'p') 190 continue; 191 tfile[0] = tname[0]; 192 pc0args[2] = tfile[0]; 193 pc0argx = savargx; 194 if (pflag) 195 pc0args[pc0argx++] = "-p"; 196 pc0args[pc0argx++] = argp; 197 pc0args[pc0argx] = 0; 198 if (dosys(pc0, pc0args, 0, 0)) 199 continue; 200 pc1args[1] = tfile[0]; 201 tfile[1] = tname[1]; 202 if (dosys(pc1, pc1args, 0, tfile[1])) 203 continue; 204 unlink(tfile[0]); 205 if (Sflag && !Oflag) 206 tfile[0] = setsuf(argp, 's'); 207 else 208 tfile[0] = tname[0]; 209 if (dosys(pc2, pc2args, tfile[1], tfile[0])) 210 continue; 211 unlink(tfile[1]); 212 tfile[1] = 0; 213 if (Oflag) { 214 if (Sflag) 215 tfile[1] = setsuf(argp, 's'); 216 else 217 tfile[1] = tname[1]; 218 if (dosys(c2, c2args, tfile[0], tfile[1])) 219 continue; 220 unlink(tfile[0]); 221 tfile[0] = tfile[1]; 222 tfile[1] = 0; 223 } 224 if (Sflag) { 225 tfile[0] = 0; 226 continue; 227 } 228 asargx = 1; 229 if (Jflag) 230 asargs[asargx++] = "-J"; 231 asargs[asargx++] = tfile[0]; 232 asargs[asargx++] = "-o"; 233 tfile[1] = setsuf(argp, 'o'); 234 asargs[asargx++] = tfile[1]; 235 asargs[asargx] = 0; 236 if (dosys(as, asargs, 0, 0)) 237 continue; 238 tfile[1] = 0; 239 remove(); 240 } 241 if (errs || cflag || Sflag) 242 done(); 243 /* char *pc3args[NARGS] = { "pc3", 0 }; */ 244 pc3args[0] = "pc3"; 245 for (i = 0; i < argc; i++) { 246 argp = argv[i]; 247 if (!strcmp(argp, "-o")) 248 i++; 249 if (argp[0] == '-') 250 continue; 251 switch (getsuf(argp)) { 252 253 case 'o': 254 pc3args[pc3argx++] = argp; 255 nxo++; 256 continue; 257 case 's': 258 case 'p': 259 onepso = pc3args[pc3argx++] = 260 savestr(setsuf(argp, 'o')); 261 np++; 262 continue; 263 } 264 } 265 pc3args[pc3argx] = 0; 266 if (dosys(pc3, pc3args, 0, 0)) 267 done(); 268 /* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */ 269 ldargs[0] = "ld"; 270 ldargs[1] = "-X"; 271 ldargs[2] = crt0; 272 for (i = 0; i < argc; i++) { 273 argp = argv[i]; 274 if (argp[0] != '-') { 275 switch (getsuf(argp)) { 276 277 case 'p': 278 case 's': 279 ldargs[ldargx] = savestr(setsuf(argp, 'o')); 280 break; 281 default: 282 ldargs[ldargx] = argp; 283 break; 284 } 285 if (getsuf(ldargs[ldargx]) == 'o') 286 for (j = 0; j < ldargx; j++) 287 if (!strcmp(ldargs[j], ldargs[ldargx])) 288 goto duplicate; 289 ldargx++; 290 duplicate: 291 continue; 292 } 293 switch (argp[1]) { 294 295 case 'i': 296 while (i+1 < argc && argv[i+1][0] != '-' && 297 getsuf(argv[i+1]) != 'p') 298 i++; 299 continue; 300 case 'd': 301 if (argp[2] == 0) 302 continue; 303 ldargs[ldargx++] = argp; 304 continue; 305 case 'o': 306 ldargs[ldargx++] = argp; 307 i++; 308 ldargs[ldargx++] = argv[i]; 309 continue; 310 case 'l': 311 if (argp[2]) 312 ldargs[ldargx++] = argp; 313 continue; 314 case 'c': 315 case 'g': 316 case 'w': 317 case 'p': 318 case 'S': 319 case 'J': 320 case 'T': 321 case 'O': 322 case 'C': 323 case 'b': 324 case 's': 325 case 'z': 326 continue; 327 default: 328 ldargs[ldargx++] = argp; 329 continue; 330 } 331 } 332 ldargs[ldargx++] = lpc; 333 if (gflag) 334 ldargs[ldargx++] = "-lg"; 335 ldargs[ldargx++] = "-lm"; 336 ldargs[ldargx++] = "-lc"; 337 ldargs[ldargx] = 0; 338 if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0) 339 unlink(onepso); 340 done(); 341 } 342 343 dosys(cmd, argv, in, out) 344 char *cmd, **argv, *in, *out; 345 { 346 union wait status; 347 int pid; 348 349 if (debug) { 350 int i; 351 printf("%s:", cmd); 352 for (i = 0; argv[i]; i++) 353 printf(" %s", argv[i]); 354 if (in) 355 printf(" <%s", in); 356 if (out) 357 printf(" >%s", out); 358 printf("\n"); 359 } 360 pid = vfork(); 361 if (pid < 0) { 362 fprintf(stderr, "pc: No more processes\n"); 363 done(); 364 } 365 if (pid == 0) { 366 if (in) { 367 close(0); 368 if (open(in, 0) != 0) { 369 perror(in); 370 exit(1); 371 } 372 } 373 if (out) { 374 close(1); 375 unlink(out); 376 if (creat(out, 0666) != 1) { 377 perror(out); 378 exit(1); 379 } 380 } 381 signal(SIGINT, SIG_DFL); 382 execv(cmd, argv); 383 perror(cmd); 384 exit(1); 385 } 386 while (wait(&status) != pid) 387 ; 388 if (WIFSIGNALED(status)) { 389 if (status.w_termsig != SIGINT) 390 fprintf(stderr, "Fatal error in %s\n", cmd); 391 errs = 100; 392 done(); 393 /*NOTREACHED*/ 394 } 395 if (status.w_retcode) { 396 errs = 1; 397 remove(); 398 } 399 return (status.w_retcode); 400 } 401 402 done() 403 { 404 405 remove(); 406 exit(errs); 407 } 408 409 remove() 410 { 411 412 if (tfile[0]) 413 unlink(tfile[0]); 414 if (tfile[1]) 415 unlink(tfile[1]); 416 } 417 418 onintr() 419 { 420 421 errs = 1; 422 done(); 423 } 424 425 getsuf(cp) 426 char *cp; 427 { 428 429 if (*cp == 0) 430 return; 431 while (cp[1]) 432 cp++; 433 if (cp[-1] != '.') 434 return (0); 435 return (*cp); 436 } 437 438 char * 439 setsuf(as, ch) 440 char *as; 441 { 442 register char *s, *s1; 443 444 s = s1 = savestr(as); 445 while (*s) 446 if (*s++ == '/') 447 s1 = s; 448 s[-1] = ch; 449 return (s1); 450 } 451 452 #define NSAVETAB 512 453 char *savetab; 454 int saveleft; 455 456 char * 457 savestr(cp) 458 register char *cp; 459 { 460 register int len; 461 462 len = strlen(cp) + 1; 463 if (len > saveleft) { 464 saveleft = NSAVETAB; 465 if (len > saveleft) 466 saveleft = len; 467 savetab = (char *)malloc(saveleft); 468 if (savetab == 0) { 469 fprintf(stderr, "ran out of memory (savestr)\n"); 470 exit(1); 471 } 472 } 473 strncpy(savetab, cp, len); 474 cp = savetab; 475 savetab += len; 476 return (cp); 477 } 478 479 suffix(cp) 480 char *cp; 481 { 482 483 if (cp[0] == 0 || cp[1] == 0) 484 return (0); 485 while (cp[1]) 486 cp++; 487 if (cp[-1] == '.') 488 return (*cp); 489 return (0); 490 } 491