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 if((tfd = create(temp, ORDWR, 0600)) < 0){ 140 perror(temp); 141 Exit(); 142 } 143 Binit(&tb, tfd, OWRITE); 144 } 145 Bprint(&tb, "%s\n", argv[i]); 146 *argv[i] = 0; 147 } 148 if(tfd >= 0){ 149 Bflush(&tb); 150 LSEEK(tfd, 0L, 0); 151 parse("command line args", tfd, 1); 152 remove(temp); 153 } 154 155 if (buf->current != buf->start) { 156 buf->current--; 157 insert(buf, 0); 158 } 159 symlook("MKFLAGS", S_VAR, (void *) stow(buf->start)); 160 buf->current = buf->start; 161 for(i = 0; argv[i]; i++){ 162 if(*argv[i] == 0) continue; 163 if(i) 164 insert(buf, ' '); 165 bufcpy(buf, argv[i], strlen(argv[i])); 166 } 167 insert(buf, 0); 168 symlook("MKARGS", S_VAR, (void *) stow(buf->start)); 169 freebuf(buf); 170 171 if(f == files){ 172 if(access(MKFILE, 4) == 0) 173 parse(MKFILE, open(MKFILE, 0), 0); 174 } else 175 for(ff = files; ff < f; ff++) 176 parse(*ff, open(*ff, 0), 0); 177 if(DEBUG(D_PARSE)){ 178 dumpw("default targets", target1); 179 dumpr("rules", rules); 180 dumpr("metarules", metarules); 181 dumpv("variables"); 182 } 183 if(whatif){ 184 insert(whatif, 0); 185 timeinit(whatif->start); 186 freebuf(whatif); 187 } 188 execinit(); 189 /* skip assignment args */ 190 while(*argv && (**argv == 0)) 191 argv++; 192 193 catchnotes(); 194 if(*argv == 0){ 195 if(target1) 196 for(w = target1; w; w = w->next) 197 mk(w->s); 198 else { 199 fprint(2, "mk: nothing to mk\n"); 200 Exit(); 201 } 202 } else { 203 if(sflag){ 204 for(; *argv; argv++) 205 if(**argv) 206 mk(*argv); 207 } else { 208 Word *head, *tail, *t; 209 210 /* fake a new rule with all the args as prereqs */ 211 tail = 0; 212 t = 0; 213 for(; *argv; argv++) 214 if(**argv){ 215 if(tail == 0) 216 tail = t = newword(*argv); 217 else { 218 t->next = newword(*argv); 219 t = t->next; 220 } 221 } 222 if(tail->next == 0) 223 mk(tail->s); 224 else { 225 head = newword("command line arguments"); 226 addrules(head, tail, strdup(""), VIR, mkinline, 0); 227 mk(head->s); 228 } 229 } 230 } 231 if(uflag) 232 prusage(); 233 exits(0); 234 } 235 236 void 237 badusage(void) 238 { 239 240 fprint(2, "Usage: mk [-f file] [-n] [-a] [-e] [-t] [-k] [-i] [-d[egp]] [targets ...]\n"); 241 Exit(); 242 } 243 244 void * 245 Malloc(int n) 246 { 247 register void *s; 248 249 s = malloc(n); 250 if(!s) { 251 fprint(2, "mk: cannot alloc %d bytes\n", n); 252 Exit(); 253 } 254 return(s); 255 } 256 257 void * 258 Realloc(void *s, int n) 259 { 260 if(s) 261 s = realloc(s, n); 262 else 263 s = malloc(n); 264 if(!s) { 265 fprint(2, "mk: cannot alloc %d bytes\n", n); 266 Exit(); 267 } 268 return(s); 269 } 270 271 void 272 regerror(char *s) 273 { 274 if(patrule) 275 fprint(2, "mk: %s:%d: regular expression error; %s\n", 276 patrule->file, patrule->line, s); 277 else 278 fprint(2, "mk: %s:%d: regular expression error; %s\n", 279 infile, mkinline, s); 280 Exit(); 281 } 282