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