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 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
badusage(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 *
Malloc(int n)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 *
Realloc(void * s,int n)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
assert(char * s,int n)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
regerror(char * s)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