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