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