13e12c5d1SDavid du Colombier #include "mk.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier #define MKFILE "mkfile" 43e12c5d1SDavid du Colombier 53e12c5d1SDavid du Colombier static char *version = "@(#)mk general release 4 (plan 9)"; 63e12c5d1SDavid du Colombier int debug; 73e12c5d1SDavid du Colombier Rule *rules, *metarules; 83e12c5d1SDavid du Colombier int nflag = 0; 93e12c5d1SDavid du Colombier int tflag = 0; 103e12c5d1SDavid du Colombier int iflag = 0; 113e12c5d1SDavid du Colombier int kflag = 0; 123e12c5d1SDavid du Colombier int aflag = 0; 13219b2ee8SDavid du Colombier int uflag = 0; 143e12c5d1SDavid du Colombier char *explain = 0; 153e12c5d1SDavid du Colombier Word *target1; 163e12c5d1SDavid du Colombier int nreps = 1; 173e12c5d1SDavid du Colombier Job *jobs; 18*7dd7cddfSDavid du Colombier Biobuf bout; 193e12c5d1SDavid du Colombier Rule *patrule; 20219b2ee8SDavid du Colombier void badusage(void); 213e12c5d1SDavid du Colombier #ifdef PROF 223e12c5d1SDavid du Colombier short buf[10000]; 23*7dd7cddfSDavid du Colombier #endif 243e12c5d1SDavid du Colombier 253e12c5d1SDavid du Colombier void 263e12c5d1SDavid du Colombier main(int argc, char **argv) 273e12c5d1SDavid du Colombier { 283e12c5d1SDavid du Colombier Word *w; 29*7dd7cddfSDavid du Colombier char *s, *temp; 303e12c5d1SDavid du Colombier char *files[256], **f = files, **ff; 313e12c5d1SDavid du Colombier int sflag = 0; 323e12c5d1SDavid du Colombier int i; 333e12c5d1SDavid du Colombier int tfd = -1; 343e12c5d1SDavid du Colombier Biobuf tb; 353e12c5d1SDavid du Colombier Bufblock *buf; 36219b2ee8SDavid du Colombier Bufblock *whatif; 373e12c5d1SDavid du Colombier 383e12c5d1SDavid du Colombier /* 393e12c5d1SDavid du Colombier * start with a copy of the current environment variables 403e12c5d1SDavid du Colombier * instead of sharing them 413e12c5d1SDavid du Colombier */ 423e12c5d1SDavid du Colombier 43*7dd7cddfSDavid du Colombier Binit(&bout, 1, OWRITE); 443e12c5d1SDavid du Colombier buf = newbuf(); 45219b2ee8SDavid du Colombier whatif = 0; 463e12c5d1SDavid du Colombier USED(argc); 473e12c5d1SDavid du Colombier for(argv++; *argv && (**argv == '-'); argv++) 483e12c5d1SDavid du Colombier { 493e12c5d1SDavid du Colombier bufcpy(buf, argv[0], strlen(argv[0])); 503e12c5d1SDavid du Colombier insert(buf, ' '); 513e12c5d1SDavid du Colombier switch(argv[0][1]) 523e12c5d1SDavid du Colombier { 533e12c5d1SDavid du Colombier case 'a': 543e12c5d1SDavid du Colombier aflag = 1; 553e12c5d1SDavid du Colombier break; 563e12c5d1SDavid du Colombier case 'd': 573e12c5d1SDavid du Colombier if(*(s = &argv[0][2])) 583e12c5d1SDavid du Colombier while(*s) switch(*s++) 593e12c5d1SDavid du Colombier { 603e12c5d1SDavid du Colombier case 'p': debug |= D_PARSE; break; 613e12c5d1SDavid du Colombier case 'g': debug |= D_GRAPH; break; 623e12c5d1SDavid du Colombier case 'e': debug |= D_EXEC; break; 633e12c5d1SDavid du Colombier } 643e12c5d1SDavid du Colombier else 653e12c5d1SDavid du Colombier debug = 0xFFFF; 663e12c5d1SDavid du Colombier break; 673e12c5d1SDavid du Colombier case 'e': 683e12c5d1SDavid du Colombier explain = &argv[0][2]; 693e12c5d1SDavid du Colombier break; 703e12c5d1SDavid du Colombier case 'f': 713e12c5d1SDavid du Colombier if(*++argv == 0) 72219b2ee8SDavid du Colombier badusage(); 733e12c5d1SDavid du Colombier *f++ = *argv; 743e12c5d1SDavid du Colombier bufcpy(buf, argv[0], strlen(argv[0])); 753e12c5d1SDavid du Colombier insert(buf, ' '); 763e12c5d1SDavid du Colombier break; 773e12c5d1SDavid du Colombier case 'i': 783e12c5d1SDavid du Colombier iflag = 1; 793e12c5d1SDavid du Colombier break; 803e12c5d1SDavid du Colombier case 'k': 813e12c5d1SDavid du Colombier kflag = 1; 823e12c5d1SDavid du Colombier break; 833e12c5d1SDavid du Colombier case 'n': 843e12c5d1SDavid du Colombier nflag = 1; 853e12c5d1SDavid du Colombier break; 863e12c5d1SDavid du Colombier case 's': 873e12c5d1SDavid du Colombier sflag = 1; 883e12c5d1SDavid du Colombier break; 893e12c5d1SDavid du Colombier case 't': 903e12c5d1SDavid du Colombier tflag = 1; 913e12c5d1SDavid du Colombier break; 92219b2ee8SDavid du Colombier case 'u': 93219b2ee8SDavid du Colombier uflag = 1; 94219b2ee8SDavid du Colombier break; 953e12c5d1SDavid du Colombier case 'w': 96219b2ee8SDavid du Colombier if(whatif == 0) 97219b2ee8SDavid du Colombier whatif = newbuf(); 98219b2ee8SDavid du Colombier else 99219b2ee8SDavid du Colombier insert(whatif, ' '); 1003e12c5d1SDavid du Colombier if(argv[0][2]) 101219b2ee8SDavid du Colombier bufcpy(whatif, &argv[0][2], strlen(&argv[0][2])); 1023e12c5d1SDavid du Colombier else { 1033e12c5d1SDavid du Colombier if(*++argv == 0) 104219b2ee8SDavid du Colombier badusage(); 105219b2ee8SDavid du Colombier bufcpy(whatif, &argv[0][0], strlen(&argv[0][0])); 1063e12c5d1SDavid du Colombier } 1073e12c5d1SDavid du Colombier break; 1083e12c5d1SDavid du Colombier default: 109219b2ee8SDavid du Colombier badusage(); 1103e12c5d1SDavid du Colombier } 1113e12c5d1SDavid du Colombier } 1123e12c5d1SDavid du Colombier #ifdef PROF 1133e12c5d1SDavid du Colombier { 1143e12c5d1SDavid du Colombier extern etext(); 1153e12c5d1SDavid du Colombier monitor(main, etext, buf, sizeof buf, 300); 1163e12c5d1SDavid du Colombier } 117*7dd7cddfSDavid du Colombier #endif 1183e12c5d1SDavid du Colombier 1193e12c5d1SDavid du Colombier if(aflag) 1203e12c5d1SDavid du Colombier iflag = 1; 121219b2ee8SDavid du Colombier usage(); 1223e12c5d1SDavid du Colombier syminit(); 1233e12c5d1SDavid du Colombier initenv(); 124219b2ee8SDavid du Colombier usage(); 1253e12c5d1SDavid du Colombier 1263e12c5d1SDavid du Colombier /* 1273e12c5d1SDavid du Colombier assignment args become null strings 1283e12c5d1SDavid du Colombier */ 129*7dd7cddfSDavid du Colombier temp = 0; 1303e12c5d1SDavid du Colombier for(i = 0; argv[i]; i++) if(utfrune(argv[i], '=')){ 1313e12c5d1SDavid du Colombier bufcpy(buf, argv[i], strlen(argv[i])); 1323e12c5d1SDavid du Colombier insert(buf, ' '); 1333e12c5d1SDavid du Colombier if(tfd < 0){ 134*7dd7cddfSDavid du Colombier temp = maketmp(); 135*7dd7cddfSDavid du Colombier if(temp == 0) { 136*7dd7cddfSDavid du Colombier perror("temp file"); 137*7dd7cddfSDavid du Colombier Exit(); 138*7dd7cddfSDavid du Colombier } 139219b2ee8SDavid du Colombier close(create(temp, OWRITE, 0600)); 1403e12c5d1SDavid du Colombier if((tfd = open(temp, 2)) < 0){ 1413e12c5d1SDavid du Colombier perror(temp); 1423e12c5d1SDavid du Colombier Exit(); 1433e12c5d1SDavid du Colombier } 1443e12c5d1SDavid du Colombier Binit(&tb, tfd, OWRITE); 1453e12c5d1SDavid du Colombier } 1463e12c5d1SDavid du Colombier Bprint(&tb, "%s\n", argv[i]); 1473e12c5d1SDavid du Colombier *argv[i] = 0; 1483e12c5d1SDavid du Colombier } 1493e12c5d1SDavid du Colombier if(tfd >= 0){ 1503e12c5d1SDavid du Colombier Bflush(&tb); 1513e12c5d1SDavid du Colombier LSEEK(tfd, 0L, 0); 152*7dd7cddfSDavid du Colombier parse("command line args", tfd, 1); 153219b2ee8SDavid du Colombier remove(temp); 1543e12c5d1SDavid du Colombier } 1553e12c5d1SDavid du Colombier 1563e12c5d1SDavid du Colombier if (buf->current != buf->start) { 1573e12c5d1SDavid du Colombier buf->current--; 1583e12c5d1SDavid du Colombier insert(buf, 0); 1593e12c5d1SDavid du Colombier } 160*7dd7cddfSDavid du Colombier symlook("MKFLAGS", S_VAR, (void *) stow(buf->start)); 1613e12c5d1SDavid du Colombier buf->current = buf->start; 1623e12c5d1SDavid du Colombier for(i = 0; argv[i]; i++){ 1633e12c5d1SDavid du Colombier if(*argv[i] == 0) continue; 1643e12c5d1SDavid du Colombier if(i) 1653e12c5d1SDavid du Colombier insert(buf, ' '); 1663e12c5d1SDavid du Colombier bufcpy(buf, argv[i], strlen(argv[i])); 1673e12c5d1SDavid du Colombier } 1683e12c5d1SDavid du Colombier insert(buf, 0); 169*7dd7cddfSDavid du Colombier symlook("MKARGS", S_VAR, (void *) stow(buf->start)); 1703e12c5d1SDavid du Colombier freebuf(buf); 1713e12c5d1SDavid du Colombier 1723e12c5d1SDavid du Colombier if(f == files){ 1733e12c5d1SDavid du Colombier if(access(MKFILE, 4) == 0) 174*7dd7cddfSDavid du Colombier parse(MKFILE, open(MKFILE, 0), 0); 1753e12c5d1SDavid du Colombier } else 1763e12c5d1SDavid du Colombier for(ff = files; ff < f; ff++) 177*7dd7cddfSDavid du Colombier parse(*ff, open(*ff, 0), 0); 1783e12c5d1SDavid du Colombier if(DEBUG(D_PARSE)){ 1793e12c5d1SDavid du Colombier dumpw("default targets", target1); 1803e12c5d1SDavid du Colombier dumpr("rules", rules); 1813e12c5d1SDavid du Colombier dumpr("metarules", metarules); 1823e12c5d1SDavid du Colombier dumpv("variables"); 1833e12c5d1SDavid du Colombier } 184219b2ee8SDavid du Colombier if(whatif){ 185219b2ee8SDavid du Colombier insert(whatif, 0); 186219b2ee8SDavid du Colombier timeinit(whatif->start); 187219b2ee8SDavid du Colombier freebuf(whatif); 188219b2ee8SDavid du Colombier } 1893e12c5d1SDavid du Colombier execinit(); 1903e12c5d1SDavid du Colombier /* skip assignment args */ 1913e12c5d1SDavid du Colombier while(*argv && (**argv == 0)) 1923e12c5d1SDavid du Colombier argv++; 193219b2ee8SDavid du Colombier 194*7dd7cddfSDavid du Colombier catchnotes(); 1953e12c5d1SDavid du Colombier if(*argv == 0){ 1963e12c5d1SDavid du Colombier if(target1) 1973e12c5d1SDavid du Colombier for(w = target1; w; w = w->next) 1983e12c5d1SDavid du Colombier mk(w->s); 1993e12c5d1SDavid du Colombier else { 2003e12c5d1SDavid du Colombier fprint(2, "mk: nothing to mk\n"); 2013e12c5d1SDavid du Colombier Exit(); 2023e12c5d1SDavid du Colombier } 2033e12c5d1SDavid du Colombier } else { 2043e12c5d1SDavid du Colombier if(sflag){ 2053e12c5d1SDavid du Colombier for(; *argv; argv++) 2063e12c5d1SDavid du Colombier if(**argv) 2073e12c5d1SDavid du Colombier mk(*argv); 2083e12c5d1SDavid du Colombier } else { 2093e12c5d1SDavid du Colombier Word *head, *tail, *t; 2103e12c5d1SDavid du Colombier 2113e12c5d1SDavid du Colombier /* fake a new rule with all the args as prereqs */ 2123e12c5d1SDavid du Colombier tail = 0; 213219b2ee8SDavid du Colombier t = 0; 2143e12c5d1SDavid du Colombier for(; *argv; argv++) 2153e12c5d1SDavid du Colombier if(**argv){ 2163e12c5d1SDavid du Colombier if(tail == 0) 2173e12c5d1SDavid du Colombier tail = t = newword(*argv); 2183e12c5d1SDavid du Colombier else { 2193e12c5d1SDavid du Colombier t->next = newword(*argv); 2203e12c5d1SDavid du Colombier t = t->next; 2213e12c5d1SDavid du Colombier } 2223e12c5d1SDavid du Colombier } 2233e12c5d1SDavid du Colombier if(tail->next == 0) 2243e12c5d1SDavid du Colombier mk(tail->s); 2253e12c5d1SDavid du Colombier else { 2263e12c5d1SDavid du Colombier head = newword("command line arguments"); 227*7dd7cddfSDavid du Colombier addrules(head, tail, strdup(""), VIR, mkinline, 0); 2283e12c5d1SDavid du Colombier mk(head->s); 2293e12c5d1SDavid du Colombier } 2303e12c5d1SDavid du Colombier } 2313e12c5d1SDavid du Colombier } 232219b2ee8SDavid du Colombier if(uflag) 233219b2ee8SDavid du Colombier prusage(); 2343e12c5d1SDavid du Colombier exits(0); 2353e12c5d1SDavid du Colombier } 2363e12c5d1SDavid du Colombier 2373e12c5d1SDavid du Colombier void 238219b2ee8SDavid du Colombier badusage(void) 2393e12c5d1SDavid du Colombier { 2403e12c5d1SDavid du Colombier 2413e12c5d1SDavid du Colombier fprint(2, "Usage: mk [-f file] [-n] [-a] [-e] [-t] [-k] [-i] [-d[egp]] [targets ...]\n"); 2423e12c5d1SDavid du Colombier Exit(); 2433e12c5d1SDavid du Colombier } 2443e12c5d1SDavid du Colombier 245*7dd7cddfSDavid du Colombier void * 2463e12c5d1SDavid du Colombier Malloc(int n) 2473e12c5d1SDavid du Colombier { 248*7dd7cddfSDavid du Colombier register void *s; 2493e12c5d1SDavid du Colombier 250219b2ee8SDavid du Colombier s = malloc(n); 251219b2ee8SDavid du Colombier if(!s) { 2523e12c5d1SDavid du Colombier fprint(2, "mk: cannot alloc %d bytes\n", n); 2533e12c5d1SDavid du Colombier Exit(); 254219b2ee8SDavid du Colombier } 255219b2ee8SDavid du Colombier return(s); 2563e12c5d1SDavid du Colombier } 2573e12c5d1SDavid du Colombier 258*7dd7cddfSDavid du Colombier void * 259*7dd7cddfSDavid du Colombier Realloc(void *s, int n) 2603e12c5d1SDavid du Colombier { 261*7dd7cddfSDavid du Colombier if(s) 262219b2ee8SDavid du Colombier s = realloc(s, n); 263*7dd7cddfSDavid du Colombier else 264*7dd7cddfSDavid du Colombier s = malloc(n); 265219b2ee8SDavid du Colombier if(!s) { 2663e12c5d1SDavid du Colombier fprint(2, "mk: cannot alloc %d bytes\n", n); 2673e12c5d1SDavid du Colombier Exit(); 268219b2ee8SDavid du Colombier } 269219b2ee8SDavid du Colombier return(s); 2703e12c5d1SDavid du Colombier } 2713e12c5d1SDavid du Colombier 2723e12c5d1SDavid du Colombier void 2733e12c5d1SDavid du Colombier regerror(char *s) 2743e12c5d1SDavid du Colombier { 2753e12c5d1SDavid du Colombier if(patrule) 2763e12c5d1SDavid du Colombier fprint(2, "mk: %s:%d: regular expression error; %s\n", 2773e12c5d1SDavid du Colombier patrule->file, patrule->line, s); 2783e12c5d1SDavid du Colombier else 2793e12c5d1SDavid du Colombier fprint(2, "mk: %s:%d: regular expression error; %s\n", 280*7dd7cddfSDavid du Colombier infile, mkinline, s); 2813e12c5d1SDavid du Colombier Exit(); 2823e12c5d1SDavid du Colombier } 283