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