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