1 static char sccsid[] = "@(#)cc.c 4.15 10/22/87"; 2 /* 3 * cc - front end for C compiler 4 */ 5 #include <sys/param.h> 6 #include <stdio.h> 7 #include <ctype.h> 8 #include <signal.h> 9 #include <sys/dir.h> 10 11 char *cpp = "/lib/cpp"; 12 char *ccom = "/lib/ccom"; 13 char *sccom = "/lib/sccom"; 14 char *c2 = "/lib/c2"; 15 char *as = "/bin/as"; 16 char *ld = "/bin/ld"; 17 char *crt0 = "/lib/crt0.o"; 18 19 char tmp0[30]; /* big enough for /tmp/ctm%05.5d */ 20 char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5; 21 char *outfile; 22 char *savestr(), *strspl(), *setsuf(); 23 int idexit(); 24 char **av, **clist, **llist, **plist; 25 int cflag, eflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag; 26 int fflag, gflag, Gflag, Mflag, debug; 27 char *dflag; 28 int exfail; 29 char *chpass; 30 char *npassname; 31 32 int nc, nl, np, nxo, na; 33 34 #define cunlink(s) if (s) unlink(s) 35 36 main(argc, argv) 37 char **argv; 38 { 39 char *t; 40 char *assource; 41 int i, j, c; 42 43 /* ld currently adds upto 5 args; 10 is room to spare */ 44 av = (char **)calloc(argc+10, sizeof (char **)); 45 clist = (char **)calloc(argc, sizeof (char **)); 46 llist = (char **)calloc(argc, sizeof (char **)); 47 plist = (char **)calloc(argc, sizeof (char **)); 48 for (i = 1; i < argc; i++) { 49 if (*argv[i] == '-') switch (argv[i][1]) { 50 51 case 'S': 52 sflag++; 53 cflag++; 54 continue; 55 case 'o': 56 if (++i < argc) { 57 outfile = argv[i]; 58 switch (getsuf(outfile)) { 59 60 case 'c': 61 error("-o would overwrite %s", 62 outfile); 63 exit(8); 64 } 65 } 66 continue; 67 case 'R': 68 Rflag++; 69 continue; 70 case 'O': 71 oflag++; 72 continue; 73 case 'p': 74 proflag++; 75 crt0 = "/lib/mcrt0.o"; 76 if (argv[i][2] == 'g') 77 crt0 = "/usr/lib/gcrt0.o"; 78 continue; 79 case 'f': 80 fflag++; 81 continue; 82 case 'g': 83 if (argv[i][2] == 'o') { 84 Gflag++; /* old format for -go */ 85 } else { 86 gflag++; /* new format for -g */ 87 } 88 continue; 89 case 'w': 90 wflag++; 91 continue; 92 case 'E': 93 exflag++; 94 case 'P': 95 pflag++; 96 if (argv[i][1]=='P') 97 fprintf(stderr, 98 "cc: warning: -P option obsolete; you should use -E instead\n"); 99 plist[np++] = argv[i]; 100 case 'c': 101 cflag++; 102 continue; 103 case 'M': 104 exflag++; 105 pflag++; 106 Mflag++; 107 /* and fall through */ 108 case 'D': 109 case 'I': 110 case 'U': 111 case 'C': 112 plist[np++] = argv[i]; 113 continue; 114 case 'L': 115 llist[nl++] = argv[i]; 116 continue; 117 case 't': 118 if (chpass) 119 error("-t overwrites earlier option", 0); 120 chpass = argv[i]+2; 121 if (chpass[0]==0) 122 chpass = "012p"; 123 continue; 124 case 'B': 125 if (npassname) 126 error("-B overwrites earlier option", 0); 127 npassname = argv[i]+2; 128 if (npassname[0]==0) 129 npassname = "/usr/c/o"; 130 continue; 131 case 'd': 132 if (argv[i][2] == '\0') { 133 debug++; 134 continue; 135 } 136 dflag = argv[i]; 137 continue; 138 } 139 t = argv[i]; 140 c = getsuf(t); 141 if (c=='c' || c=='s' || exflag) { 142 clist[nc++] = t; 143 t = setsuf(t, 'o'); 144 } 145 if (nodup(llist, t)) { 146 llist[nl++] = t; 147 if (getsuf(t)=='o') 148 nxo++; 149 } 150 } 151 if (gflag || Gflag) { 152 if (oflag) 153 fprintf(stderr, "cc: warning: -g disables -O\n"); 154 oflag = 0; 155 } 156 if (npassname && chpass ==0) 157 chpass = "012p"; 158 if (chpass && npassname==0) 159 npassname = "/usr/new"; 160 if (chpass) 161 for (t=chpass; *t; t++) { 162 switch (*t) { 163 164 case '0': 165 if (fflag) 166 sccom = strspl(npassname, "sccom"); 167 else 168 ccom = strspl(npassname, "ccom"); 169 continue; 170 case '2': 171 c2 = strspl(npassname, "c2"); 172 continue; 173 case 'p': 174 cpp = strspl(npassname, "cpp"); 175 continue; 176 } 177 } 178 if (nc==0) 179 goto nocom; 180 if (signal(SIGINT, SIG_IGN) != SIG_IGN) 181 signal(SIGINT, idexit); 182 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 183 signal(SIGTERM, idexit); 184 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 185 signal(SIGHUP, idexit); 186 if (pflag==0) 187 (void)sprintf(tmp0, "/tmp/ctm%05.5d", getpid()); 188 tmp1 = strspl(tmp0, "1"); 189 tmp2 = strspl(tmp0, "2"); 190 tmp3 = strspl(tmp0, "3"); 191 if (pflag==0) 192 tmp4 = strspl(tmp0, "4"); 193 if (oflag) 194 tmp5 = strspl(tmp0, "5"); 195 for (i=0; i<nc; i++) { 196 if (nc > 1 && !Mflag) { 197 printf("%s:\n", clist[i]); 198 fflush(stdout); 199 } 200 if (!Mflag && getsuf(clist[i]) == 's') { 201 assource = clist[i]; 202 goto assemble; 203 } else 204 assource = tmp3; 205 if (pflag) 206 tmp4 = setsuf(clist[i], 'i'); 207 av[0] = "cpp"; av[1] = clist[i]; 208 na = 2; 209 if (!exflag) 210 av[na++] = tmp4; 211 for (j = 0; j < np; j++) 212 av[na++] = plist[j]; 213 av[na++] = 0; 214 if (callsys(cpp, av)) { 215 exfail++; 216 eflag++; 217 cflag++; 218 continue; 219 } 220 if (pflag) { 221 cflag++; 222 continue; 223 } 224 if (sflag) { 225 if (nc==1 && outfile) 226 tmp3 = outfile; 227 else 228 tmp3 = setsuf(clist[i], 's'); 229 assource = tmp3; 230 } 231 av[0] = fflag ? "sccom" : "ccom"; 232 av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3; 233 if (proflag) 234 av[na++] = "-XP"; 235 if (gflag) { 236 av[na++] = "-Xg"; 237 } else if (Gflag) { 238 av[na++] = "-XG"; 239 } 240 if (wflag) 241 av[na++] = "-w"; 242 av[na] = 0; 243 if (callsys(fflag ? sccom : ccom, av)) { 244 cflag++; 245 eflag++; 246 continue; 247 } 248 if (oflag) { 249 av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; 250 if (callsys(c2, av)) { 251 unlink(tmp3); 252 tmp3 = assource = tmp5; 253 } else 254 unlink(tmp5); 255 } 256 if (sflag) 257 continue; 258 assemble: 259 cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); 260 av[0] = "as"; av[1] = "-o"; 261 if (cflag && nc==1 && outfile) 262 av[2] = outfile; 263 else 264 av[2] = setsuf(clist[i], 'o'); 265 na = 3; 266 if (Rflag) 267 av[na++] = "-R"; 268 if (dflag) 269 av[na++] = dflag; 270 av[na++] = assource; 271 av[na] = 0; 272 if (callsys(as, av) > 1) { 273 cflag++; 274 eflag++; 275 continue; 276 } 277 } 278 nocom: 279 if (cflag==0 && nl!=0) { 280 i = 0; 281 av[0] = "ld"; av[1] = "-X"; av[2] = crt0; na = 3; 282 if (outfile) { 283 av[na++] = "-o"; 284 av[na++] = outfile; 285 } 286 while (i < nl) 287 av[na++] = llist[i++]; 288 if (gflag || Gflag) 289 av[na++] = "-lg"; 290 if (proflag) 291 av[na++] = "-lc_p"; 292 else 293 av[na++] = "-lc"; 294 av[na++] = 0; 295 eflag |= callsys(ld, av); 296 if (nc==1 && nxo==1 && eflag==0) 297 unlink(setsuf(clist[0], 'o')); 298 } 299 dexit(); 300 } 301 302 idexit() 303 { 304 305 eflag = 100; 306 dexit(); 307 } 308 309 dexit() 310 { 311 312 if (!pflag) { 313 cunlink(tmp1); 314 cunlink(tmp2); 315 if (sflag==0) 316 cunlink(tmp3); 317 cunlink(tmp4); 318 cunlink(tmp5); 319 } 320 exit(eflag); 321 } 322 323 error(s, x) 324 char *s, *x; 325 { 326 FILE *diag = exflag ? stderr : stdout; 327 328 fprintf(diag, "cc: "); 329 fprintf(diag, s, x); 330 putc('\n', diag); 331 exfail++; 332 cflag++; 333 eflag++; 334 } 335 336 getsuf(as) 337 char as[]; 338 { 339 register int c; 340 register char *s; 341 register int t; 342 343 s = as; 344 c = 0; 345 while (t = *s++) 346 if (t=='/') 347 c = 0; 348 else 349 c++; 350 s -= 3; 351 if (c <= MAXNAMLEN && c > 2 && *s++ == '.') 352 return (*s); 353 return (0); 354 } 355 356 char * 357 setsuf(as, ch) 358 char *as; 359 { 360 register char *s, *s1; 361 362 s = s1 = savestr(as); 363 while (*s) 364 if (*s++ == '/') 365 s1 = s; 366 s[-1] = ch; 367 return (s1); 368 } 369 370 callsys(f, v) 371 char *f, **v; 372 { 373 int t, status; 374 char **cpp; 375 376 if (debug) { 377 fprintf(stderr, "%s:", f); 378 for (cpp = v; *cpp != 0; cpp++) 379 fprintf(stderr, " %s", *cpp); 380 fprintf(stderr, "\n"); 381 } 382 t = vfork(); 383 if (t == -1) { 384 printf("No more processes\n"); 385 return (100); 386 } 387 if (t == 0) { 388 execv(f, v); 389 printf("Can't find %s\n", f); 390 fflush(stdout); 391 _exit(100); 392 } 393 while (t != wait(&status)) 394 ; 395 if ((t=(status&0377)) != 0 && t!=14) { 396 if (t!=2) { 397 printf("Fatal error in %s\n", f); 398 eflag = 8; 399 } 400 dexit(); 401 } 402 return ((status>>8) & 0377); 403 } 404 405 nodup(l, os) 406 char **l, *os; 407 { 408 register char *t, *s; 409 register int c; 410 411 s = os; 412 if (getsuf(s) != 'o') 413 return (1); 414 while (t = *l++) { 415 while (c = *s++) 416 if (c != *t++) 417 break; 418 if (*t==0 && c==0) 419 return (0); 420 s = os; 421 } 422 return (1); 423 } 424 425 #define NSAVETAB 1024 426 char *savetab; 427 int saveleft; 428 429 char * 430 savestr(cp) 431 register char *cp; 432 { 433 register int len; 434 435 len = strlen(cp) + 1; 436 if (len > saveleft) { 437 saveleft = NSAVETAB; 438 if (len > saveleft) 439 saveleft = len; 440 savetab = (char *)malloc(saveleft); 441 if (savetab == 0) { 442 fprintf(stderr, "ran out of memory (savestr)\n"); 443 exit(1); 444 } 445 } 446 strncpy(savetab, cp, len); 447 cp = savetab; 448 savetab += len; 449 saveleft -= len; 450 return (cp); 451 } 452 453 char * 454 strspl(left, right) 455 char *left, *right; 456 { 457 char buf[BUFSIZ]; 458 459 strcpy(buf, left); 460 strcat(buf, right); 461 return (savestr(buf)); 462 } 463