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