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 nproclimit; 93e12c5d1SDavid du Colombier int nflag = 0; 103e12c5d1SDavid du Colombier int tflag = 0; 113e12c5d1SDavid du Colombier int iflag = 0; 123e12c5d1SDavid du Colombier int kflag = 0; 133e12c5d1SDavid du Colombier int aflag = 0; 14*219b2ee8SDavid du Colombier int uflag = 0; 153e12c5d1SDavid du Colombier char *explain = 0; 163e12c5d1SDavid du Colombier Word *target1; 173e12c5d1SDavid du Colombier int nreps = 1; 183e12c5d1SDavid du Colombier Job *jobs; 193e12c5d1SDavid du Colombier char shell[] = SHELL; 203e12c5d1SDavid du Colombier char shellname[] = SHELL; 213e12c5d1SDavid du Colombier Biobuf stdout; 223e12c5d1SDavid du Colombier Rule *patrule; 23*219b2ee8SDavid du Colombier void badusage(void); 243e12c5d1SDavid du Colombier #ifdef PROF 253e12c5d1SDavid du Colombier short buf[10000]; 263e12c5d1SDavid du Colombier #endif PROF 273e12c5d1SDavid du Colombier 283e12c5d1SDavid du Colombier void 293e12c5d1SDavid du Colombier main(int argc, char **argv) 303e12c5d1SDavid du Colombier { 313e12c5d1SDavid du Colombier Word *w; 323e12c5d1SDavid du Colombier char *s; 333e12c5d1SDavid du Colombier char *files[256], **f = files, **ff; 343e12c5d1SDavid du Colombier int sflag = 0; 353e12c5d1SDavid du Colombier int i; 363e12c5d1SDavid du Colombier int tfd = -1; 373e12c5d1SDavid du Colombier Biobuf tb; 383e12c5d1SDavid du Colombier Bufblock *buf; 39*219b2ee8SDavid du Colombier Bufblock *whatif; 403e12c5d1SDavid du Colombier static char temp[] = "/tmp/mkargXXXXXX"; 413e12c5d1SDavid du Colombier 423e12c5d1SDavid du Colombier /* 433e12c5d1SDavid du Colombier * start with a copy of the current environment variables 443e12c5d1SDavid du Colombier * instead of sharing them 453e12c5d1SDavid du Colombier */ 463e12c5d1SDavid du Colombier rfork(RFENVG); 473e12c5d1SDavid du Colombier 483e12c5d1SDavid du Colombier Binit(&stdout, 1, OWRITE); 493e12c5d1SDavid du Colombier buf = newbuf(); 50*219b2ee8SDavid du Colombier whatif = 0; 513e12c5d1SDavid du Colombier USED(argc); 523e12c5d1SDavid du Colombier for(argv++; *argv && (**argv == '-'); argv++) 533e12c5d1SDavid du Colombier { 543e12c5d1SDavid du Colombier bufcpy(buf, argv[0], strlen(argv[0])); 553e12c5d1SDavid du Colombier insert(buf, ' '); 563e12c5d1SDavid du Colombier switch(argv[0][1]) 573e12c5d1SDavid du Colombier { 583e12c5d1SDavid du Colombier case 'a': 593e12c5d1SDavid du Colombier aflag = 1; 603e12c5d1SDavid du Colombier break; 613e12c5d1SDavid du Colombier case 'd': 623e12c5d1SDavid du Colombier if(*(s = &argv[0][2])) 633e12c5d1SDavid du Colombier while(*s) switch(*s++) 643e12c5d1SDavid du Colombier { 653e12c5d1SDavid du Colombier case 'p': debug |= D_PARSE; break; 663e12c5d1SDavid du Colombier case 'g': debug |= D_GRAPH; break; 673e12c5d1SDavid du Colombier case 'e': debug |= D_EXEC; break; 683e12c5d1SDavid du Colombier } 693e12c5d1SDavid du Colombier else 703e12c5d1SDavid du Colombier debug = 0xFFFF; 713e12c5d1SDavid du Colombier break; 723e12c5d1SDavid du Colombier case 'e': 733e12c5d1SDavid du Colombier explain = &argv[0][2]; 743e12c5d1SDavid du Colombier break; 753e12c5d1SDavid du Colombier case 'f': 763e12c5d1SDavid du Colombier if(*++argv == 0) 77*219b2ee8SDavid du Colombier badusage(); 783e12c5d1SDavid du Colombier *f++ = *argv; 793e12c5d1SDavid du Colombier bufcpy(buf, argv[0], strlen(argv[0])); 803e12c5d1SDavid du Colombier insert(buf, ' '); 813e12c5d1SDavid du Colombier break; 823e12c5d1SDavid du Colombier case 'i': 833e12c5d1SDavid du Colombier iflag = 1; 843e12c5d1SDavid du Colombier break; 853e12c5d1SDavid du Colombier case 'k': 863e12c5d1SDavid du Colombier kflag = 1; 873e12c5d1SDavid du Colombier break; 883e12c5d1SDavid du Colombier case 'n': 893e12c5d1SDavid du Colombier nflag = 1; 903e12c5d1SDavid du Colombier break; 913e12c5d1SDavid du Colombier case 's': 923e12c5d1SDavid du Colombier sflag = 1; 933e12c5d1SDavid du Colombier break; 943e12c5d1SDavid du Colombier case 't': 953e12c5d1SDavid du Colombier tflag = 1; 963e12c5d1SDavid du Colombier break; 97*219b2ee8SDavid du Colombier case 'u': 98*219b2ee8SDavid du Colombier uflag = 1; 99*219b2ee8SDavid du Colombier break; 1003e12c5d1SDavid du Colombier case 'w': 101*219b2ee8SDavid du Colombier if(whatif == 0) 102*219b2ee8SDavid du Colombier whatif = newbuf(); 103*219b2ee8SDavid du Colombier else 104*219b2ee8SDavid du Colombier insert(whatif, ' '); 1053e12c5d1SDavid du Colombier if(argv[0][2]) 106*219b2ee8SDavid du Colombier bufcpy(whatif, &argv[0][2], strlen(&argv[0][2])); 1073e12c5d1SDavid du Colombier else { 1083e12c5d1SDavid du Colombier if(*++argv == 0) 109*219b2ee8SDavid du Colombier badusage(); 110*219b2ee8SDavid du Colombier bufcpy(whatif, &argv[0][0], strlen(&argv[0][0])); 1113e12c5d1SDavid du Colombier } 1123e12c5d1SDavid du Colombier break; 1133e12c5d1SDavid du Colombier default: 114*219b2ee8SDavid du Colombier badusage(); 1153e12c5d1SDavid du Colombier } 1163e12c5d1SDavid du Colombier } 1173e12c5d1SDavid du Colombier #ifdef PROF 1183e12c5d1SDavid du Colombier { 1193e12c5d1SDavid du Colombier extern etext(); 1203e12c5d1SDavid du Colombier monitor(main, etext, buf, sizeof buf, 300); 1213e12c5d1SDavid du Colombier } 1223e12c5d1SDavid du Colombier #endif PROF 1233e12c5d1SDavid du Colombier 1243e12c5d1SDavid du Colombier if(aflag) 1253e12c5d1SDavid du Colombier iflag = 1; 126*219b2ee8SDavid du Colombier usage(); 1273e12c5d1SDavid du Colombier for(i = strlen(shell)-1; i >= 0; i--) 1283e12c5d1SDavid du Colombier if(shell[i] == '/') 1293e12c5d1SDavid du Colombier break; 1303e12c5d1SDavid du Colombier strcpy(shellname, shell+i+1); 1313e12c5d1SDavid du Colombier syminit(); 1323e12c5d1SDavid du Colombier initenv(); 133*219b2ee8SDavid du Colombier usage(); 1343e12c5d1SDavid du Colombier 1353e12c5d1SDavid du Colombier /* 1363e12c5d1SDavid du Colombier assignment args become null strings 1373e12c5d1SDavid du Colombier */ 1383e12c5d1SDavid du Colombier for(i = 0; argv[i]; i++) if(utfrune(argv[i], '=')){ 1393e12c5d1SDavid du Colombier bufcpy(buf, argv[i], strlen(argv[i])); 1403e12c5d1SDavid du Colombier insert(buf, ' '); 1413e12c5d1SDavid du Colombier if(tfd < 0){ 1423e12c5d1SDavid du Colombier mktemp(temp); 143*219b2ee8SDavid du Colombier close(create(temp, OWRITE, 0600)); 1443e12c5d1SDavid du Colombier if((tfd = open(temp, 2)) < 0){ 1453e12c5d1SDavid du Colombier perror(temp); 1463e12c5d1SDavid du Colombier Exit(); 1473e12c5d1SDavid du Colombier } 1483e12c5d1SDavid du Colombier Binit(&tb, tfd, OWRITE); 1493e12c5d1SDavid du Colombier } 1503e12c5d1SDavid du Colombier Bprint(&tb, "%s\n", argv[i]); 1513e12c5d1SDavid du Colombier *argv[i] = 0; 1523e12c5d1SDavid du Colombier } 1533e12c5d1SDavid du Colombier if(tfd >= 0){ 1543e12c5d1SDavid du Colombier Bflush(&tb); 1553e12c5d1SDavid du Colombier LSEEK(tfd, 0L, 0); 1563e12c5d1SDavid du Colombier parse("command line args", tfd, 1, 1); 157*219b2ee8SDavid du Colombier remove(temp); 1583e12c5d1SDavid du Colombier } 1593e12c5d1SDavid du Colombier 1603e12c5d1SDavid du Colombier if (buf->current != buf->start) { 1613e12c5d1SDavid du Colombier buf->current--; 1623e12c5d1SDavid du Colombier insert(buf, 0); 1633e12c5d1SDavid du Colombier } 1643e12c5d1SDavid du Colombier symlook("MKFLAGS", S_VAR, (char *) stow(buf->start)); 1653e12c5d1SDavid du Colombier buf->current = buf->start; 1663e12c5d1SDavid du Colombier for(i = 0; argv[i]; i++){ 1673e12c5d1SDavid du Colombier if(*argv[i] == 0) continue; 1683e12c5d1SDavid du Colombier if(i) 1693e12c5d1SDavid du Colombier insert(buf, ' '); 1703e12c5d1SDavid du Colombier bufcpy(buf, argv[i], strlen(argv[i])); 1713e12c5d1SDavid du Colombier } 1723e12c5d1SDavid du Colombier insert(buf, 0); 1733e12c5d1SDavid du Colombier symlook("MKARGS", S_VAR, (char *) stow(buf->start)); 1743e12c5d1SDavid du Colombier freebuf(buf); 1753e12c5d1SDavid du Colombier 1763e12c5d1SDavid du Colombier if(f == files){ 1773e12c5d1SDavid du Colombier if(access(MKFILE, 4) == 0) 1783e12c5d1SDavid du Colombier parse(MKFILE, open(MKFILE, 0), 0, 1); 1793e12c5d1SDavid du Colombier } else 1803e12c5d1SDavid du Colombier for(ff = files; ff < f; ff++) 1813e12c5d1SDavid du Colombier parse(*ff, open(*ff, 0), 0, 1); 1823e12c5d1SDavid du Colombier if(DEBUG(D_PARSE)){ 1833e12c5d1SDavid du Colombier dumpw("default targets", target1); 1843e12c5d1SDavid du Colombier dumpr("rules", rules); 1853e12c5d1SDavid du Colombier dumpr("metarules", metarules); 1863e12c5d1SDavid du Colombier dumpv("variables"); 1873e12c5d1SDavid du Colombier } 188*219b2ee8SDavid du Colombier if(whatif){ 189*219b2ee8SDavid du Colombier insert(whatif, 0); 190*219b2ee8SDavid du Colombier timeinit(whatif->start); 191*219b2ee8SDavid du Colombier freebuf(whatif); 192*219b2ee8SDavid du Colombier } 1933e12c5d1SDavid du Colombier execinit(); 1943e12c5d1SDavid du Colombier /* skip assignment args */ 1953e12c5d1SDavid du Colombier while(*argv && (**argv == 0)) 1963e12c5d1SDavid du Colombier argv++; 197*219b2ee8SDavid du Colombier 198*219b2ee8SDavid du Colombier atnotify(notifyf, 1); 1993e12c5d1SDavid du Colombier if(*argv == 0){ 2003e12c5d1SDavid du Colombier if(target1) 2013e12c5d1SDavid du Colombier for(w = target1; w; w = w->next) 2023e12c5d1SDavid du Colombier mk(w->s); 2033e12c5d1SDavid du Colombier else { 2043e12c5d1SDavid du Colombier fprint(2, "mk: nothing to mk\n"); 2053e12c5d1SDavid du Colombier Exit(); 2063e12c5d1SDavid du Colombier } 2073e12c5d1SDavid du Colombier } else { 2083e12c5d1SDavid du Colombier if(sflag){ 2093e12c5d1SDavid du Colombier for(; *argv; argv++) 2103e12c5d1SDavid du Colombier if(**argv) 2113e12c5d1SDavid du Colombier mk(*argv); 2123e12c5d1SDavid du Colombier } else { 2133e12c5d1SDavid du Colombier Word *head, *tail, *t; 2143e12c5d1SDavid du Colombier 2153e12c5d1SDavid du Colombier /* fake a new rule with all the args as prereqs */ 2163e12c5d1SDavid du Colombier tail = 0; 217*219b2ee8SDavid du Colombier t = 0; 2183e12c5d1SDavid du Colombier for(; *argv; argv++) 2193e12c5d1SDavid du Colombier if(**argv){ 2203e12c5d1SDavid du Colombier if(tail == 0) 2213e12c5d1SDavid du Colombier tail = t = newword(*argv); 2223e12c5d1SDavid du Colombier else { 2233e12c5d1SDavid du Colombier t->next = newword(*argv); 2243e12c5d1SDavid du Colombier t = t->next; 2253e12c5d1SDavid du Colombier } 2263e12c5d1SDavid du Colombier } 2273e12c5d1SDavid du Colombier if(tail->next == 0) 2283e12c5d1SDavid du Colombier mk(tail->s); 2293e12c5d1SDavid du Colombier else { 2303e12c5d1SDavid du Colombier head = newword("command line arguments"); 2313e12c5d1SDavid du Colombier addrules(head, tail, strdup(""), VIR, inline, 1, (char *)0); 2323e12c5d1SDavid du Colombier mk(head->s); 2333e12c5d1SDavid du Colombier } 2343e12c5d1SDavid du Colombier } 2353e12c5d1SDavid du Colombier } 236*219b2ee8SDavid du Colombier if(uflag) 237*219b2ee8SDavid du Colombier prusage(); 2383e12c5d1SDavid du Colombier exits(0); 2393e12c5d1SDavid du Colombier } 2403e12c5d1SDavid du Colombier 2413e12c5d1SDavid du Colombier void 242*219b2ee8SDavid du Colombier badusage(void) 2433e12c5d1SDavid du Colombier { 2443e12c5d1SDavid du Colombier 2453e12c5d1SDavid du Colombier fprint(2, "Usage: mk [-f file] [-n] [-a] [-e] [-t] [-k] [-i] [-d[egp]] [targets ...]\n"); 2463e12c5d1SDavid du Colombier Exit(); 2473e12c5d1SDavid du Colombier } 2483e12c5d1SDavid du Colombier 2493e12c5d1SDavid du Colombier char * 2503e12c5d1SDavid du Colombier Malloc(int n) 2513e12c5d1SDavid du Colombier { 2523e12c5d1SDavid du Colombier register char *s; 2533e12c5d1SDavid du Colombier 254*219b2ee8SDavid du Colombier s = malloc(n); 255*219b2ee8SDavid du Colombier if(!s) { 2563e12c5d1SDavid du Colombier fprint(2, "mk: cannot alloc %d bytes\n", n); 2573e12c5d1SDavid du Colombier Exit(); 258*219b2ee8SDavid du Colombier } 259*219b2ee8SDavid du Colombier return(s); 2603e12c5d1SDavid du Colombier } 2613e12c5d1SDavid du Colombier 2623e12c5d1SDavid du Colombier char * 2633e12c5d1SDavid du Colombier Realloc(char *s, int n) 2643e12c5d1SDavid du Colombier { 265*219b2ee8SDavid du Colombier s = realloc(s, n); 266*219b2ee8SDavid du Colombier if(!s) { 2673e12c5d1SDavid du Colombier fprint(2, "mk: cannot alloc %d bytes\n", n); 2683e12c5d1SDavid du Colombier Exit(); 269*219b2ee8SDavid du Colombier } 270*219b2ee8SDavid du Colombier return(s); 2713e12c5d1SDavid du Colombier } 2723e12c5d1SDavid du Colombier 2733e12c5d1SDavid du Colombier void 2743e12c5d1SDavid du Colombier Exit(void) 2753e12c5d1SDavid du Colombier { 2763e12c5d1SDavid du Colombier while(wait(0) >= 0) 2773e12c5d1SDavid du Colombier ; 2783e12c5d1SDavid du Colombier exits("error"); 2793e12c5d1SDavid du Colombier } 2803e12c5d1SDavid du Colombier 2813e12c5d1SDavid du Colombier /* 2823e12c5d1SDavid du Colombier char * 2833e12c5d1SDavid du Colombier strndup(char *s, unsigned n) 2843e12c5d1SDavid du Colombier { 2853e12c5d1SDavid du Colombier register char *goo; 2863e12c5d1SDavid du Colombier 2873e12c5d1SDavid du Colombier goo = Malloc(n); 2883e12c5d1SDavid du Colombier memmove(goo, s, (COUNT)n); 2893e12c5d1SDavid du Colombier return(goo); 2903e12c5d1SDavid du Colombier } 2913e12c5d1SDavid du Colombier */ 2923e12c5d1SDavid du Colombier 2933e12c5d1SDavid du Colombier void 2943e12c5d1SDavid du Colombier assert(char *s, int n) 2953e12c5d1SDavid du Colombier { 2963e12c5d1SDavid du Colombier if(!n){ 2973e12c5d1SDavid du Colombier fprint(2, "mk: Assertion ``%s'' failed.\n", s); 2983e12c5d1SDavid du Colombier Exit(); 2993e12c5d1SDavid du Colombier } 3003e12c5d1SDavid du Colombier } 3013e12c5d1SDavid du Colombier 3023e12c5d1SDavid du Colombier void 3033e12c5d1SDavid du Colombier regerror(char *s) 3043e12c5d1SDavid du Colombier { 3053e12c5d1SDavid du Colombier if(patrule) 3063e12c5d1SDavid du Colombier fprint(2, "mk: %s:%d: regular expression error; %s\n", 3073e12c5d1SDavid du Colombier patrule->file, patrule->line, s); 3083e12c5d1SDavid du Colombier else 3093e12c5d1SDavid du Colombier fprint(2, "mk: %s:%d: regular expression error; %s\n", 3103e12c5d1SDavid du Colombier infile, inline, s); 3113e12c5d1SDavid du Colombier Exit(); 3123e12c5d1SDavid du Colombier } 313