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