1#include <signal.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5
6#include "make.h"
7
8#define TABSIZ 128
9#define FORCE 1
10#define NOFORCE 0
11
12static Target *htab[TABSIZ], *deftarget;
13
14void
15dumprules(void)
16{
17 int i;
18 Target **pp, **q, *p;
19
20 for (pp = htab; pp < &htab[TABSIZ]; ++pp) {
21 for (p = *pp; p; p = p->next) {
22 if (!p->defined)
23 continue;
24 printf("%s:", p->name);
25 for (q = p->deps; q && *q; ++q)
26 printf(" %s", (*q)->name);
27 putchar('\n');
28 for (i = 0; i < p->nactions; i++)
29 printf("\t%s\n", p->actions[i].line);
30 putchar('\n');
31 }
32 }
33}
34
35static Target *
36lookup(char *name)
37{
38 Target *tp;
39 int h = hash(name) & (TABSIZ-1);
40
41 for (tp = htab[h]; tp && strcmp(tp->name, name); tp = tp->next)
42 ;
43
44 if (tp)
45 return tp;
46
47 tp = emalloc(sizeof(*tp));
48 tp->name = estrdup(name);
49 tp->target = tp->name;
50 tp->req = NULL;
51 tp->ndeps = 0;
52 tp->deps = NULL;
53 tp->actions = NULL;
54 tp->nactions = 0;
55 tp->next = htab[h];
56 tp->defined = 0;
57 htab[h] = tp;
58
59 return tp;
60}
61
62static void
63cleanup(Target *tp)
64{
65 int sig, precious;
66 Target *p, **q;
67
68 sig = stop;
69 printf("make: signal %d arrived\n", sig);
70
71 precious = 0;
72 p = lookup(".PRECIOUS");
73 for (q = p->deps; q && *q; q++) {
74 if (strcmp((*q)->name, tp->name) == 0) {
75 precious = 1;
76 break;
77 }
78 }
79
80 if (!precious && !nflag && !qflag && !is_dir(tp->name)) {
81 printf("make: trying to remove target %s\n", tp->name);
82 remove(tp->name);
83 }
84
85 signal(sig, SIG_DFL);
86 raise(sig);
87}
88
89static int
90depends(char *target, char *dep)
91{
92 Target **p, *tp = lookup(target);
93
94 for (p = tp->deps; p && *p; ++p) {
95 if (strcmp((*p)->name, dep) == 0)
96 return 1;
97 }
98
99 return 0;
100}
101
102void
103addtarget(char *target, int ndeps)
104{
105 Target *tp = lookup(target);
106
107 tp->defined = 1;
108 if (!deftarget && target[0] != '.') {
109 deftarget = tp;
110 return;
111 }
112
113 if (strcmp(target, ".SUFFIXES") == 0 && ndeps == 0) {
114 free(tp->deps);
115 tp->deps = NULL;
116 tp->ndeps = 0;
117 return;
118 }
119
120 if (strcmp(target, ".DEFAULT") == 0) {
121 if (ndeps > 0)
122 error("DEFAULT rule with prerequisites");
123 return;
124 }
125
126 if (strcmp(target, ".SILENT") == 0 && ndeps == 0) {
127 sflag = 1;
128 return;
129 }
130
131 if (strcmp(target, ".IGNORE") == 0 && ndeps == 0) {
132 iflag = 1;
133 return;
134 }
135}
136
137void
138adddep(char *target, char *dep)
139{
140 size_t siz;
141 Target **p, *tp = lookup(target);
142
143 if (depends(dep, target)) {
144 warning("circular dependency %s <- %s dropped", target, dep);
145 return;
146 }
147
148 for (p = tp->deps; p && *p; ++p) {
149 if (strcmp((*p)->name, dep) == 0)
150 return;
151 }
152
153 tp->ndeps++;
154 siz = (tp->ndeps + 1) * sizeof(Target *);
155 tp->deps = erealloc(tp->deps, siz);
156 tp->deps[tp->ndeps-1] = lookup(dep);
157 tp->deps[tp->ndeps] = NULL;
158
159 debug("adding dependency %s <- %s", target, dep);
160}
161
162static void
163freeaction(struct action *act)
164{
165 free(act->line);
166 freeloc(&act->loc);
167}
168
169void
170addrule(char *target, struct action *acts, int n)
171{
172 int i;
173 struct action *v;
174 Target *tp = lookup(target);
175
176 debug("adding actions for target %s", target);
177
178 if (tp->actions) {
179 debug("overring actions of target %s", target);
180 for (i = 0; i < tp->nactions; i++)
181 freeaction(&tp->actions[i]);
182 free(tp->actions);
183 }
184
185 v = emalloc(n * sizeof(*v));
186 for (i = 0; i < n; i++) {
187 v[i].line = estrdup(acts[i].line);
188 v[i].loc.lineno = acts[i].loc.lineno;
189 v[i].loc.fname = estrdup(acts[i].loc.fname);
190 }
191
192 tp->nactions = n;
193 tp->actions = v;
194}
195
196static int
197execline(Target *tp, char *line, int ignore, int silence)
198{
199 char *s, *t;
200 int r, at, plus, minus, l;
201
202 (void)tp;
203
204 debug("executing '%s'", line);
205
206 at = plus = minus = 0;
207 for (s = line; ; s++) {
208 switch (*s) {
209 case '@':
210 at = 1;
211 break;
212 case '-':
213 minus = 1;
214 break;
215 case '+':
216 plus = 1;
217 break;
218 default:
219 goto out_loop;
220 }
221 }
222
223out_loop:
224 /* unescape $$ */
225 for (l = strlen(s)+1, t = s; *t; --l, ++t) {
226 if (t[0] == '$' && t[1] == '$') {
227 memmove(t+1, t+2, l-2);
228 l--;
229 }
230 }
231
232 if (tflag && !plus)
233 return 0;
234
235 if (sflag || silence || (qflag && !plus))
236 at = 1;
237 if (nflag)
238 at = 0;
239 if (!at) {
240 puts(s);
241 fflush(stdout);
242 }
243
244 if ((nflag || qflag) && !plus) {
245 if (qflag)
246 exitstatus = 1;
247 return 0;
248 }
249
250 if (minus || iflag || ignore)
251 ignore = 1;
252
253 r = launch(s, ignore);
254 if (ignore)
255 return 0;
256
257 return r;
258}
259
260static int
261touch(char *name, int ignore, int silence)
262{
263 char *cmd;
264 int r, n;
265
266 n = snprintf(NULL, 0, "touch %s", name) + 1;
267 cmd = emalloc(n);
268 snprintf(cmd, n, "touch %s", name);
269
270 if (!sflag && !silence)
271 puts(cmd);
272
273 r = system(cmd);
274 free(cmd);
275
276 if (ignore || iflag)
277 return 0;
278
279 return r;
280}
281
282static int
283touchdeps(Target *tp, int ignore, int silent)
284{
285 int r;
286 Target **p;
287
288 if (tp->req) {
289 r = touch(tp->req, silent, ignore);
290 if (r)
291 return r;
292 }
293
294 for (p = tp->deps; p && *p; ++p) {
295 r = touch((*p)->name, silent, ignore);
296 if (r)
297 return r;
298 }
299
300 return 0;
301}
302
303static int
304run(Target *tp)
305{
306 int r, i, ignore, silent;
307 char *s;
308 Target *p, **q;
309
310 silent = 0;
311 p = lookup(".SILENT");
312 for (q = p->deps; q && *q; ++q) {
313 if (strcmp((*q)->name, tp->name) == 0) {
314 debug("target %s error silent by .SILENT", tp->name);
315 silent = 1;
316 }
317 }
318
319 ignore = 0;
320 p = lookup(".IGNORE");
321 for (q = p->deps; q && *q; ++q) {
322 if (strcmp((*q)->name, tp->name) == 0) {
323 debug("target %s error ignored by .IGNORE", tp->name);
324 ignore = 1;
325 }
326 }
327
328 if (tflag) {
329 r = touchdeps(tp, ignore, silent);
330 if (r)
331 return r;
332 }
333
334 for (i = 0; i < tp->nactions; i++) {
335 struct action *p;
336
337 if (stop)
338 cleanup(tp);
339
340 p = &tp->actions[i];
341 debug("executing action '%s'", p->line);
342 s = expandstring(p->line, tp, &p->loc);
343 r = execline(tp, s, ignore, silent);
344 free(s);
345
346 if (r)
347 return r;
348 }
349
350 if (tflag) {
351 r = touch(tp->target, ignore, silent);
352 if (r)
353 return r;
354 }
355
356 return 0;
357}
358
359static int
360enabled(char *suffix)
361{
362 Target **p, *tp = lookup(".SUFFIXES");
363
364 for (p = tp->deps; p && *p; ++p) {
365 if (strcmp(suffix, (*p)->name) == 0)
366 return 1;
367 }
368
369 return 0;
370}
371
372static Target *
373inference(Target *tp, int force)
374{
375 time_t t;
376 int tolen, r;
377 char *to, *from;
378 Target *q, **p, *suffixes;
379 char buf[FILENAME_MAX], fname[FILENAME_MAX];
380
381 debug("searching an inference rule for %s", tp->name);
382
383 to = strrchr(tp->name, '.');
384 if (to && !enabled(to))
385 return NULL;
386 tolen = to ? (int)(to - tp->name) : (int)strlen(tp->name);
387
388 if (!to)
389 to = "";
390
391 suffixes = lookup(".SUFFIXES");
392 for (p = suffixes->deps; p && *p; ++p) {
393 from = (*p)->name;
394 debug("trying suffix %s", from);
395
396 r = snprintf(buf,
397 sizeof(buf),
398 "%s%s",
399 from, to);
400
401 if (r < 0 || (size_t)r >= sizeof(buf))
402 error("suffixes too long %s %s", from, to);
403
404 q = lookup(buf);
405 if (!q->actions)
406 continue;
407
408 r = snprintf(fname,
409 sizeof(fname),
410 "%*.*s%s",
411 tolen, tolen, tp->name, from);
412
413 if (r < 0 || (size_t)r >= sizeof(fname)) {
414 error("prerequisite name too long %s %s",
415 tp->name, from);
416 }
417
418 debug("\tsearching prerequisite %s", fname);
419
420 t = stamp(fname);
421 if (t == -1) {
422 debug("\tprerequisite %s not found", fname);
423 continue;
424 }
425
426 if (!force && t <= tp->stamp) {
427 debug("\tdiscarded because is newer");
428 debug("\t%s: %s", tp->name, ctime(&tp->stamp));
429 debug("\t%s: %s", fname, ctime(&t));
430 continue;
431 }
432
433 free(q->req);
434 q->req = estrdup(fname);
435 q->deps = tp->deps;
436 q->target = tp->name;
437 q->stamp = tp->stamp;
438
439 debug("using inference rule %s with %s", q->name, fname);
440 return q;
441 }
442
443 return NULL;
444}
445
446static int
447update(Target *tp)
448{
449 Target *p;
450
451 debug("%s needs to be updated", tp->name);
452
453 if (tp->actions) {
454 debug("using target rule to build %s", tp->name);
455 return run(tp);
456 }
457
458 if ((p = inference(tp, FORCE)) != NULL) {
459 debug("using inference rule %s", p->name);
460 return run(p);
461 }
462
463 p = lookup(".DEFAULT");
464 if (p->defined) {
465 debug("using default rule");
466 return run(p);
467 }
468
469 debug("not rule found to update %s", tp->name);
470
471 if (!tp->defined)
472 error("don't know how to make %s", tp->name);
473
474 return 0;
475}
476
477static int
478rebuild(Target *tp, int *buildp)
479{
480 Target **p, *q;
481 int r, need, build, err, def;
482
483 debug("checking rebuild of %s", tp->name);
484
485 tp->stamp = stamp(tp->name);
486
487 def = err = need = 0;
488 for (p = tp->deps; p && *p; ++p) {
489 if (stop)
490 cleanup(tp);
491
492 q = *p;
493 debug("checking dependency %s", q->name);
494
495 if (strcmp(q->name, tp->name) == 0 && q->actions)
496 def = 1;
497
498 build = 0;
499 if (rebuild(q, &build) != 0) {
500 err = 1;
501 continue;
502 }
503
504 if (build) {
505 debug("rebuild of %s forces rebuild of %s",
506 q->name, tp->name);
507 need = 1;
508 } else if (q->stamp > tp->stamp) {
509 debug("dependency %s is newer than %s",
510 q->name, tp->name);
511 need = 1;
512 }
513 }
514
515 if (tp->stamp == -1) {
516 need = 1;
517 } else if (!def) {
518 debug("no action found for %s, looking a inference rule",
519 tp->name);
520 if (inference(tp, NOFORCE))
521 need = 1;
522 }
523
524 if (err) {
525 warning("target %s not remade because of errors", tp->name);
526 return 1;
527 } else if (need) {
528 *buildp = 1;
529
530 debug("target %s needs updating", tp->name);
531 r = update(tp);
532 if (r == 0)
533 return 0;
534
535 if (stop)
536 cleanup(tp);
537
538 exitstatus = 1;
539
540 if (!kflag)
541 error("target %s: error %d", tp->name, r);
542 else
543 warning("target %s: error %d", tp->name, r);
544 return r;
545 }
546
547 return 0;
548}
549
550int
551build(char *name)
552{
553 int build;
554
555 if (!name) {
556 if (!deftarget) {
557 printf("make: no target to make\n");
558 return 0;
559 }
560 name = deftarget->name;
561 }
562
563 debug("checking target %s", name);
564
565 build = 0;
566 return rebuild(lookup(name), &build);
567}