xref: /plan9/sys/src/cmd/mk/main.c (revision 7bd483b0b97911f3ba6c830c06efdc49c6cf0263)
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
main(int argc,char ** argv)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
badusage(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 *
Malloc(int n)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 *
Realloc(void * s,int n)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
regerror(char * s)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