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