1 #include <u.h> 2 #include <libc.h> 3 4 5 typedef struct Objtype { 6 char *name; 7 char *cc; 8 char *ld; 9 char *o; 10 char *oname; 11 } Objtype; 12 13 Objtype objtype[] = { 14 {"68020", "2c", "2l", "2", "2.out"}, 15 {"arm", "5c", "5l", "5", "5.out"}, 16 {"amd64", "6c", "6l", "6", "6.out"}, 17 {"alpha", "7c", "7l", "7", "7.out"}, 18 {"386", "8c", "8l", "8", "8.out"}, 19 {"sparc", "kc", "kl", "k", "k.out"}, 20 {"mips", "vc", "vl", "v", "v.out"}, 21 {"power", "qc", "ql", "q", "q.out"}, 22 }; 23 24 enum { 25 Nobjs = (sizeof objtype)/(sizeof objtype[0]), 26 Maxlist = 500, 27 }; 28 29 typedef struct List { 30 char *strings[Maxlist]; 31 int n; 32 } List; 33 34 List srcs, objs, cpp, cc, ld, ldargs; 35 int cflag, vflag, Eflag, Pflag; 36 char *allos = "2478kqv"; 37 38 void append(List *, char *); 39 char *changeext(char *, char *); 40 void doexec(char *, List *); 41 void dopipe(char *, List *, char *, List *); 42 void fatal(char *); 43 Objtype *findoty(void); 44 void printlist(List *); 45 46 void 47 main(int argc, char *argv[]) 48 { 49 Objtype *ot; 50 char *s, *suf, *ccpath; 51 char *oname; 52 int i, cppn, ccn, oflag; 53 54 oflag = 0; 55 ot = findoty(); 56 oname = ot->oname; 57 append(&cpp, "cpp"); 58 append(&cpp, "-D__STDC__=1"); /* ANSI says so */ 59 append(&cpp, "-N"); /* turn off standard includes */ 60 append(&cc, ot->cc); 61 append(&ld, ot->ld); 62 while(argc > 0) { 63 ARGBEGIN { 64 case '+': 65 append(&cpp, smprint("-%c", ARGC())); 66 break; 67 case 'c': 68 cflag = 1; 69 break; 70 case 'l': 71 append(&objs, smprint("/%s/lib/ape/lib%s.a", ot->name, ARGF())); 72 break; 73 case 'o': 74 oflag = 1; 75 oname = ARGF(); 76 if(!oname) 77 fatal("no -o argument"); 78 break; 79 case 'w': 80 case 'B': 81 case 'F': 82 case 'N': 83 case 'S': 84 case 'T': 85 case 'V': 86 append(&cc, smprint("-%c", ARGC())); 87 break; 88 case 's': 89 append(&cc, smprint("-s%s", ARGF())); 90 break; 91 case 'D': 92 case 'I': 93 case 'U': 94 append(&cpp, smprint("-%c%s", ARGC(), ARGF())); 95 break; 96 case 'v': 97 vflag = 1; 98 append(&ldargs, "-v"); 99 break; 100 case 'P': 101 Pflag = 1; 102 cflag = 1; 103 break; 104 case 'E': 105 Eflag = 1; 106 cflag = 1; 107 break; 108 case 'p': 109 append(&ldargs, "-p"); 110 break; 111 case 'a': 112 /* hacky look inside ARGBEGIN insides, to see if we have -aa */ 113 if(*_args == 'a') { 114 append(&cc, "-aa"); 115 _args++; 116 } else 117 append(&cc, "-a"); 118 cflag = 1; 119 break; 120 default: 121 fprint(2, "pcc: flag -%c ignored\n", ARGC()); 122 break; 123 } ARGEND 124 if(argc > 0) { 125 s = argv[0]; 126 suf = utfrrune(s, '.'); 127 if(suf) { 128 suf++; 129 if(strcmp(suf, "c") == 0) { 130 append(&srcs, s); 131 append(&objs, changeext(s, ot->o)); 132 } else if(strcmp(suf, ot->o) == 0 || 133 strcmp(suf, "a") == 0 || 134 (suf[0] == 'a' && strcmp(suf+1, ot->o) == 0)) { 135 append(&objs, s); 136 } else if(utfrune(allos, suf[0]) != 0) { 137 fprint(2, "pcc: argument %s ignored: wrong architecture\n", 138 s); 139 } 140 } 141 } 142 } 143 if(objs.n == 0) 144 fatal("no files to compile or load"); 145 ccpath = smprint("/bin/%s", ot->cc); 146 append(&cpp, smprint("-I/%s/include/ape", ot->name)); 147 append(&cpp, "-I/sys/include/ape"); 148 cppn = cpp.n; 149 ccn = cc.n; 150 for(i = 0; i < srcs.n; i++) { 151 append(&cpp, srcs.strings[i]); 152 if(Pflag) 153 append(&cpp, changeext(objs.strings[i], "i")); 154 if(Eflag || Pflag) 155 doexec("/bin/cpp", &cpp); 156 else { 157 append(&cc, "-o"); 158 if(oflag && cflag) 159 append(&cc, oname); 160 else 161 append(&cc, changeext(srcs.strings[i], ot->o)); 162 dopipe("/bin/cpp", &cpp, ccpath, &cc); 163 } 164 cpp.n = cppn; 165 cc.n = ccn; 166 } 167 if(!cflag) { 168 append(&ld, "-o"); 169 append(&ld, oname); 170 for(i = 0; i < ldargs.n; i++) 171 append(&ld, ldargs.strings[i]); 172 for(i = 0; i < objs.n; i++) 173 append(&ld, objs.strings[i]); 174 append(&ld, smprint("/%s/lib/ape/libap.a", ot->name)); 175 doexec(smprint("/bin/%s", ot->ld), &ld); 176 if(objs.n == 1){ 177 /* prevent removal of a library */ 178 if(strstr(objs.strings[0], ".a") == 0) 179 remove(objs.strings[0]); 180 } 181 } 182 183 exits(0); 184 } 185 186 void 187 append(List *l, char *s) 188 { 189 if(l->n >= Maxlist-1) 190 fatal("too many arguments"); 191 l->strings[l->n++] = s; 192 l->strings[l->n] = 0; 193 } 194 195 void 196 doexec(char *c, List *a) 197 { 198 Waitmsg *w; 199 200 if(vflag) { 201 printlist(a); 202 fprint(2, "\n"); 203 } 204 switch(fork()) { 205 case -1: 206 fatal("fork failed"); 207 case 0: 208 exec(c, a->strings); 209 fatal("exec failed"); 210 } 211 w = wait(); 212 if(w == nil) 213 fatal("wait failed"); 214 if(w->msg[0]) 215 fatal(smprint("%s: %s", a->strings[0], w->msg)); 216 free(w); 217 } 218 219 void 220 dopipe(char *c1, List *a1, char *c2, List *a2) 221 { 222 Waitmsg *w; 223 int pid1, got; 224 int fd[2]; 225 226 if(vflag) { 227 printlist(a1); 228 fprint(2, " | "); 229 printlist(a2); 230 fprint(2, "\n"); 231 } 232 if(pipe(fd) < 0) 233 fatal("pipe failed"); 234 switch((pid1 = fork())) { 235 case -1: 236 fatal("fork failed"); 237 case 0: 238 dup(fd[0], 0); 239 close(fd[0]); 240 close(fd[1]); 241 exec(c2, a2->strings); 242 fatal("exec failed"); 243 } 244 switch(fork()) { 245 case -1: 246 fatal("fork failed"); 247 case 0: 248 close(0); 249 dup(fd[1], 1); 250 close(fd[0]); 251 close(fd[1]); 252 exec(c1, a1->strings); 253 fatal("exec failed"); 254 } 255 close(fd[0]); 256 close(fd[1]); 257 for(got = 0; got < 2; got++) { 258 w = wait(); 259 if(w == nil) 260 fatal("wait failed"); 261 if(w->msg[0]) 262 fatal(smprint("%s: %s", 263 (w->pid == pid1) ? a1->strings[0] : a2->strings[0], w->msg)); 264 free(w); 265 } 266 } 267 268 Objtype * 269 findoty(void) 270 { 271 char *o; 272 Objtype *oty; 273 274 o = getenv("objtype"); 275 if(!o) 276 fatal("no $objtype in environment"); 277 for(oty = objtype; oty < &objtype[Nobjs]; oty++) 278 if(strcmp(o, oty->name) == 0) 279 return oty; 280 fatal("unknown $objtype"); 281 return 0; /* shut compiler up */ 282 } 283 284 void 285 fatal(char *msg) 286 { 287 fprint(2, "pcc: %s\n", msg); 288 exits(msg); 289 } 290 291 /* src ends in .something; return copy of basename with .ext added */ 292 char * 293 changeext(char *src, char *ext) 294 { 295 char *b, *e, *ans; 296 297 b = utfrrune(src, '/'); 298 if(b) 299 b++; 300 else 301 b = src; 302 e = utfrrune(src, '.'); 303 if(!e) 304 return 0; 305 *e = 0; 306 ans = smprint("%s.%s", b, ext); 307 *e = '.'; 308 return ans; 309 } 310 311 void 312 printlist(List *l) 313 { 314 int i; 315 316 for(i = 0; i < l->n; i++) { 317 fprint(2, "%s", l->strings[i]); 318 if(i < l->n - 1) 319 fprint(2, " "); 320 } 321 } 322