xref: /plan9/sys/src/cmd/mk/main.c (revision 7bd483b0b97911f3ba6c830c06efdc49c6cf0263)
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;
187dd7cddfSDavid 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];
237dd7cddfSDavid du Colombier #endif
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier void
main(int argc,char ** argv)263e12c5d1SDavid du Colombier main(int argc, char **argv)
273e12c5d1SDavid du Colombier {
283e12c5d1SDavid du Colombier 	Word *w;
297dd7cddfSDavid 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 
437dd7cddfSDavid 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 	}
1177dd7cddfSDavid 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 	*/
1297dd7cddfSDavid 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){
1347dd7cddfSDavid du Colombier 			temp = maketmp();
1357dd7cddfSDavid du Colombier 			if(temp == 0) {
1367dd7cddfSDavid du Colombier 				perror("temp file");
1377dd7cddfSDavid du Colombier 				Exit();
1387dd7cddfSDavid du Colombier 			}
139*7bd483b0SDavid du Colombier 			if((tfd = create(temp, ORDWR, 0600)) < 0){
1403e12c5d1SDavid du Colombier 				perror(temp);
1413e12c5d1SDavid du Colombier 				Exit();
1423e12c5d1SDavid du Colombier 			}
1433e12c5d1SDavid du Colombier 			Binit(&tb, tfd, OWRITE);
1443e12c5d1SDavid du Colombier 		}
1453e12c5d1SDavid du Colombier 		Bprint(&tb, "%s\n", argv[i]);
1463e12c5d1SDavid du Colombier 		*argv[i] = 0;
1473e12c5d1SDavid du Colombier 	}
1483e12c5d1SDavid du Colombier 	if(tfd >= 0){
1493e12c5d1SDavid du Colombier 		Bflush(&tb);
1503e12c5d1SDavid du Colombier 		LSEEK(tfd, 0L, 0);
1517dd7cddfSDavid du Colombier 		parse("command line args", tfd, 1);
152219b2ee8SDavid du Colombier 		remove(temp);
1533e12c5d1SDavid du Colombier 	}
1543e12c5d1SDavid du Colombier 
1553e12c5d1SDavid du Colombier 	if (buf->current != buf->start) {
1563e12c5d1SDavid du Colombier 		buf->current--;
1573e12c5d1SDavid du Colombier 		insert(buf, 0);
1583e12c5d1SDavid du Colombier 	}
1597dd7cddfSDavid du Colombier 	symlook("MKFLAGS", S_VAR, (void *) stow(buf->start));
1603e12c5d1SDavid du Colombier 	buf->current = buf->start;
1613e12c5d1SDavid du Colombier 	for(i = 0; argv[i]; i++){
1623e12c5d1SDavid du Colombier 		if(*argv[i] == 0) continue;
1633e12c5d1SDavid du Colombier 		if(i)
1643e12c5d1SDavid du Colombier 			insert(buf, ' ');
1653e12c5d1SDavid du Colombier 		bufcpy(buf, argv[i], strlen(argv[i]));
1663e12c5d1SDavid du Colombier 	}
1673e12c5d1SDavid du Colombier 	insert(buf, 0);
1687dd7cddfSDavid du Colombier 	symlook("MKARGS", S_VAR, (void *) stow(buf->start));
1693e12c5d1SDavid du Colombier 	freebuf(buf);
1703e12c5d1SDavid du Colombier 
1713e12c5d1SDavid du Colombier 	if(f == files){
1723e12c5d1SDavid du Colombier 		if(access(MKFILE, 4) == 0)
1737dd7cddfSDavid du Colombier 			parse(MKFILE, open(MKFILE, 0), 0);
1743e12c5d1SDavid du Colombier 	} else
1753e12c5d1SDavid du Colombier 		for(ff = files; ff < f; ff++)
1767dd7cddfSDavid du Colombier 			parse(*ff, open(*ff, 0), 0);
1773e12c5d1SDavid du Colombier 	if(DEBUG(D_PARSE)){
1783e12c5d1SDavid du Colombier 		dumpw("default targets", target1);
1793e12c5d1SDavid du Colombier 		dumpr("rules", rules);
1803e12c5d1SDavid du Colombier 		dumpr("metarules", metarules);
1813e12c5d1SDavid du Colombier 		dumpv("variables");
1823e12c5d1SDavid du Colombier 	}
183219b2ee8SDavid du Colombier 	if(whatif){
184219b2ee8SDavid du Colombier 		insert(whatif, 0);
185219b2ee8SDavid du Colombier 		timeinit(whatif->start);
186219b2ee8SDavid du Colombier 		freebuf(whatif);
187219b2ee8SDavid du Colombier 	}
1883e12c5d1SDavid du Colombier 	execinit();
1893e12c5d1SDavid du Colombier 	/* skip assignment args */
1903e12c5d1SDavid du Colombier 	while(*argv && (**argv == 0))
1913e12c5d1SDavid du Colombier 		argv++;
192219b2ee8SDavid du Colombier 
1937dd7cddfSDavid du Colombier 	catchnotes();
1943e12c5d1SDavid du Colombier 	if(*argv == 0){
1953e12c5d1SDavid du Colombier 		if(target1)
1963e12c5d1SDavid du Colombier 			for(w = target1; w; w = w->next)
1973e12c5d1SDavid du Colombier 				mk(w->s);
1983e12c5d1SDavid du Colombier 		else {
1993e12c5d1SDavid du Colombier 			fprint(2, "mk: nothing to mk\n");
2003e12c5d1SDavid du Colombier 			Exit();
2013e12c5d1SDavid du Colombier 		}
2023e12c5d1SDavid du Colombier 	} else {
2033e12c5d1SDavid du Colombier 		if(sflag){
2043e12c5d1SDavid du Colombier 			for(; *argv; argv++)
2053e12c5d1SDavid du Colombier 				if(**argv)
2063e12c5d1SDavid du Colombier 					mk(*argv);
2073e12c5d1SDavid du Colombier 		} else {
2083e12c5d1SDavid du Colombier 			Word *head, *tail, *t;
2093e12c5d1SDavid du Colombier 
2103e12c5d1SDavid du Colombier 			/* fake a new rule with all the args as prereqs */
2113e12c5d1SDavid du Colombier 			tail = 0;
212219b2ee8SDavid du Colombier 			t = 0;
2133e12c5d1SDavid du Colombier 			for(; *argv; argv++)
2143e12c5d1SDavid du Colombier 				if(**argv){
2153e12c5d1SDavid du Colombier 					if(tail == 0)
2163e12c5d1SDavid du Colombier 						tail = t = newword(*argv);
2173e12c5d1SDavid du Colombier 					else {
2183e12c5d1SDavid du Colombier 						t->next = newword(*argv);
2193e12c5d1SDavid du Colombier 						t = t->next;
2203e12c5d1SDavid du Colombier 					}
2213e12c5d1SDavid du Colombier 				}
2223e12c5d1SDavid du Colombier 			if(tail->next == 0)
2233e12c5d1SDavid du Colombier 				mk(tail->s);
2243e12c5d1SDavid du Colombier 			else {
2253e12c5d1SDavid du Colombier 				head = newword("command line arguments");
2267dd7cddfSDavid du Colombier 				addrules(head, tail, strdup(""), VIR, mkinline, 0);
2273e12c5d1SDavid du Colombier 				mk(head->s);
2283e12c5d1SDavid du Colombier 			}
2293e12c5d1SDavid du Colombier 		}
2303e12c5d1SDavid du Colombier 	}
231219b2ee8SDavid du Colombier 	if(uflag)
232219b2ee8SDavid du Colombier 		prusage();
2333e12c5d1SDavid du Colombier 	exits(0);
2343e12c5d1SDavid du Colombier }
2353e12c5d1SDavid du Colombier 
2363e12c5d1SDavid du Colombier void
badusage(void)237219b2ee8SDavid du Colombier badusage(void)
2383e12c5d1SDavid du Colombier {
2393e12c5d1SDavid du Colombier 
2403e12c5d1SDavid du Colombier 	fprint(2, "Usage: mk [-f file] [-n] [-a] [-e] [-t] [-k] [-i] [-d[egp]] [targets ...]\n");
2413e12c5d1SDavid du Colombier 	Exit();
2423e12c5d1SDavid du Colombier }
2433e12c5d1SDavid du Colombier 
2447dd7cddfSDavid du Colombier void *
Malloc(int n)2453e12c5d1SDavid du Colombier Malloc(int n)
2463e12c5d1SDavid du Colombier {
2477dd7cddfSDavid du Colombier 	register void *s;
2483e12c5d1SDavid du Colombier 
249219b2ee8SDavid du Colombier 	s = malloc(n);
250219b2ee8SDavid du Colombier 	if(!s) {
2513e12c5d1SDavid du Colombier 		fprint(2, "mk: cannot alloc %d bytes\n", n);
2523e12c5d1SDavid du Colombier 		Exit();
253219b2ee8SDavid du Colombier 	}
254219b2ee8SDavid du Colombier 	return(s);
2553e12c5d1SDavid du Colombier }
2563e12c5d1SDavid du Colombier 
2577dd7cddfSDavid du Colombier void *
Realloc(void * s,int n)2587dd7cddfSDavid du Colombier Realloc(void *s, int n)
2593e12c5d1SDavid du Colombier {
2607dd7cddfSDavid du Colombier 	if(s)
261219b2ee8SDavid du Colombier 		s = realloc(s, n);
2627dd7cddfSDavid du Colombier 	else
2637dd7cddfSDavid du Colombier 		s = malloc(n);
264219b2ee8SDavid du Colombier 	if(!s) {
2653e12c5d1SDavid du Colombier 		fprint(2, "mk: cannot alloc %d bytes\n", n);
2663e12c5d1SDavid du Colombier 		Exit();
267219b2ee8SDavid du Colombier 	}
268219b2ee8SDavid du Colombier 	return(s);
2693e12c5d1SDavid du Colombier }
2703e12c5d1SDavid du Colombier 
2713e12c5d1SDavid du Colombier void
regerror(char * s)2723e12c5d1SDavid du Colombier regerror(char *s)
2733e12c5d1SDavid du Colombier {
2743e12c5d1SDavid du Colombier 	if(patrule)
2753e12c5d1SDavid du Colombier 		fprint(2, "mk: %s:%d: regular expression error; %s\n",
2763e12c5d1SDavid du Colombier 			patrule->file, patrule->line, s);
2773e12c5d1SDavid du Colombier 	else
2783e12c5d1SDavid du Colombier 		fprint(2, "mk: %s:%d: regular expression error; %s\n",
2797dd7cddfSDavid du Colombier 			infile, mkinline, s);
2803e12c5d1SDavid du Colombier 	Exit();
2813e12c5d1SDavid du Colombier }
282