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