1 #include "mk.h" 2 3 #define MKFILE "mkfile" 4 5 static char *version = "@(#)mk general release 4 (plan 9)"; 6 int debug; 7 Rule *rules, *metarules; 8 int nproclimit; 9 int nflag = 0; 10 int tflag = 0; 11 int iflag = 0; 12 int kflag = 0; 13 int aflag = 0; 14 int uflag = 0; 15 char *explain = 0; 16 Word *target1; 17 int nreps = 1; 18 Job *jobs; 19 char shell[] = SHELL; 20 char shellname[] = SHELL; 21 Biobuf stdout; 22 Rule *patrule; 23 void badusage(void); 24 #ifdef PROF 25 short buf[10000]; 26 #endif PROF 27 28 void 29 main(int argc, char **argv) 30 { 31 Word *w; 32 char *s; 33 char *files[256], **f = files, **ff; 34 int sflag = 0; 35 int i; 36 int tfd = -1; 37 Biobuf tb; 38 Bufblock *buf; 39 Bufblock *whatif; 40 static char temp[] = "/tmp/mkargXXXXXX"; 41 42 /* 43 * start with a copy of the current environment variables 44 * instead of sharing them 45 */ 46 rfork(RFENVG); 47 48 Binit(&stdout, 1, OWRITE); 49 buf = newbuf(); 50 whatif = 0; 51 USED(argc); 52 for(argv++; *argv && (**argv == '-'); argv++) 53 { 54 bufcpy(buf, argv[0], strlen(argv[0])); 55 insert(buf, ' '); 56 switch(argv[0][1]) 57 { 58 case 'a': 59 aflag = 1; 60 break; 61 case 'd': 62 if(*(s = &argv[0][2])) 63 while(*s) switch(*s++) 64 { 65 case 'p': debug |= D_PARSE; break; 66 case 'g': debug |= D_GRAPH; break; 67 case 'e': debug |= D_EXEC; break; 68 } 69 else 70 debug = 0xFFFF; 71 break; 72 case 'e': 73 explain = &argv[0][2]; 74 break; 75 case 'f': 76 if(*++argv == 0) 77 badusage(); 78 *f++ = *argv; 79 bufcpy(buf, argv[0], strlen(argv[0])); 80 insert(buf, ' '); 81 break; 82 case 'i': 83 iflag = 1; 84 break; 85 case 'k': 86 kflag = 1; 87 break; 88 case 'n': 89 nflag = 1; 90 break; 91 case 's': 92 sflag = 1; 93 break; 94 case 't': 95 tflag = 1; 96 break; 97 case 'u': 98 uflag = 1; 99 break; 100 case 'w': 101 if(whatif == 0) 102 whatif = newbuf(); 103 else 104 insert(whatif, ' '); 105 if(argv[0][2]) 106 bufcpy(whatif, &argv[0][2], strlen(&argv[0][2])); 107 else { 108 if(*++argv == 0) 109 badusage(); 110 bufcpy(whatif, &argv[0][0], strlen(&argv[0][0])); 111 } 112 break; 113 default: 114 badusage(); 115 } 116 } 117 #ifdef PROF 118 { 119 extern etext(); 120 monitor(main, etext, buf, sizeof buf, 300); 121 } 122 #endif PROF 123 124 if(aflag) 125 iflag = 1; 126 usage(); 127 for(i = strlen(shell)-1; i >= 0; i--) 128 if(shell[i] == '/') 129 break; 130 strcpy(shellname, shell+i+1); 131 syminit(); 132 initenv(); 133 usage(); 134 135 /* 136 assignment args become null strings 137 */ 138 for(i = 0; argv[i]; i++) if(utfrune(argv[i], '=')){ 139 bufcpy(buf, argv[i], strlen(argv[i])); 140 insert(buf, ' '); 141 if(tfd < 0){ 142 mktemp(temp); 143 close(create(temp, OWRITE, 0600)); 144 if((tfd = open(temp, 2)) < 0){ 145 perror(temp); 146 Exit(); 147 } 148 Binit(&tb, tfd, OWRITE); 149 } 150 Bprint(&tb, "%s\n", argv[i]); 151 *argv[i] = 0; 152 } 153 if(tfd >= 0){ 154 Bflush(&tb); 155 LSEEK(tfd, 0L, 0); 156 parse("command line args", tfd, 1, 1); 157 remove(temp); 158 } 159 160 if (buf->current != buf->start) { 161 buf->current--; 162 insert(buf, 0); 163 } 164 symlook("MKFLAGS", S_VAR, (char *) stow(buf->start)); 165 buf->current = buf->start; 166 for(i = 0; argv[i]; i++){ 167 if(*argv[i] == 0) continue; 168 if(i) 169 insert(buf, ' '); 170 bufcpy(buf, argv[i], strlen(argv[i])); 171 } 172 insert(buf, 0); 173 symlook("MKARGS", S_VAR, (char *) stow(buf->start)); 174 freebuf(buf); 175 176 if(f == files){ 177 if(access(MKFILE, 4) == 0) 178 parse(MKFILE, open(MKFILE, 0), 0, 1); 179 } else 180 for(ff = files; ff < f; ff++) 181 parse(*ff, open(*ff, 0), 0, 1); 182 if(DEBUG(D_PARSE)){ 183 dumpw("default targets", target1); 184 dumpr("rules", rules); 185 dumpr("metarules", metarules); 186 dumpv("variables"); 187 } 188 if(whatif){ 189 insert(whatif, 0); 190 timeinit(whatif->start); 191 freebuf(whatif); 192 } 193 execinit(); 194 /* skip assignment args */ 195 while(*argv && (**argv == 0)) 196 argv++; 197 198 atnotify(notifyf, 1); 199 if(*argv == 0){ 200 if(target1) 201 for(w = target1; w; w = w->next) 202 mk(w->s); 203 else { 204 fprint(2, "mk: nothing to mk\n"); 205 Exit(); 206 } 207 } else { 208 if(sflag){ 209 for(; *argv; argv++) 210 if(**argv) 211 mk(*argv); 212 } else { 213 Word *head, *tail, *t; 214 215 /* fake a new rule with all the args as prereqs */ 216 tail = 0; 217 t = 0; 218 for(; *argv; argv++) 219 if(**argv){ 220 if(tail == 0) 221 tail = t = newword(*argv); 222 else { 223 t->next = newword(*argv); 224 t = t->next; 225 } 226 } 227 if(tail->next == 0) 228 mk(tail->s); 229 else { 230 head = newword("command line arguments"); 231 addrules(head, tail, strdup(""), VIR, inline, 1, (char *)0); 232 mk(head->s); 233 } 234 } 235 } 236 if(uflag) 237 prusage(); 238 exits(0); 239 } 240 241 void 242 badusage(void) 243 { 244 245 fprint(2, "Usage: mk [-f file] [-n] [-a] [-e] [-t] [-k] [-i] [-d[egp]] [targets ...]\n"); 246 Exit(); 247 } 248 249 char * 250 Malloc(int n) 251 { 252 register char *s; 253 254 s = malloc(n); 255 if(!s) { 256 fprint(2, "mk: cannot alloc %d bytes\n", n); 257 Exit(); 258 } 259 return(s); 260 } 261 262 char * 263 Realloc(char *s, int n) 264 { 265 s = realloc(s, n); 266 if(!s) { 267 fprint(2, "mk: cannot alloc %d bytes\n", n); 268 Exit(); 269 } 270 return(s); 271 } 272 273 void 274 Exit(void) 275 { 276 while(wait(0) >= 0) 277 ; 278 exits("error"); 279 } 280 281 /* 282 char * 283 strndup(char *s, unsigned n) 284 { 285 register char *goo; 286 287 goo = Malloc(n); 288 memmove(goo, s, (COUNT)n); 289 return(goo); 290 } 291 */ 292 293 void 294 assert(char *s, int n) 295 { 296 if(!n){ 297 fprint(2, "mk: Assertion ``%s'' failed.\n", s); 298 Exit(); 299 } 300 } 301 302 void 303 regerror(char *s) 304 { 305 if(patrule) 306 fprint(2, "mk: %s:%d: regular expression error; %s\n", 307 patrule->file, patrule->line, s); 308 else 309 fprint(2, "mk: %s:%d: regular expression error; %s\n", 310 infile, inline, s); 311 Exit(); 312 } 313