xref: /plan9/sys/src/cmd/mk/recipe.c (revision d1da931c1953c14f6f98c26297030a0b55cb02f6)
1 #include	"mk.h"
2 
3 int
dorecipe(Node * node)4 dorecipe(Node *node)
5 {
6 	int did = 0;
7 	char buf[BIGBLOCK], cwd[256];
8 	Arc *a, *aa;
9 	Node *n;
10 	Rule *r = 0;
11 	Symtab *s;
12 	Word head, ahead, lp, ln, *w, *ww, *aw;
13 
14 	aa = 0;
15 	/*
16 		pick up the rule
17 	*/
18 	for(a = node->prereqs; a; a = a->next)
19 		if(*a->r->recipe)
20 			r = (aa = a)->r;
21 	/*
22 		no recipe? go to buggery!
23 	*/
24 	if(r == 0){
25 		if(!(node->flags&VIRTUAL) && !(node->flags&NORECIPE)){
26 			if(getwd(cwd, sizeof cwd))
27 				fprint(2, "mk: no recipe to make '%s' in directory %s\n", node->name, cwd);
28 			else
29 				fprint(2, "mk: no recipe to make '%s'\n", node->name);
30 			Exit();
31 		}
32 		if(strchr(node->name, '(') && node->time == 0)
33 			MADESET(node, MADE);
34 		else
35 			update(0, node);
36 		if(tflag){
37 			if(!(node->flags&VIRTUAL))
38 				touch(node->name);
39 			else if(explain)
40 				Bprint(&bout, "no touch of virtual '%s'\n", node->name);
41 		}
42 		return(did);
43 	}
44 	/*
45 		build the node list
46 	*/
47 	node->next = 0;
48 	head.next = 0;
49 	ww = &head;
50 	ahead.next = 0;
51 	aw = &ahead;
52 	if(r->attr&REGEXP){
53 		ww->next = newword(node->name);
54 		aw->next = newword(node->name);
55 	} else {
56 		for(w = r->alltargets; w; w = w->next){
57 			if(r->attr&META)
58 				subst(aa->stem, w->s, buf, sizeof(buf));
59 			else
60 				strecpy(buf, buf + sizeof buf - 1, w->s);
61 			aw->next = newword(buf);
62 			aw = aw->next;
63 			if((s = symlook(buf, S_NODE, 0)) == 0)
64 				continue;	/* not a node we are interested in */
65 			n = s->u.ptr;
66 			if(aflag == 0 && n->time) {
67 				for(a = n->prereqs; a; a = a->next)
68 					if(a->n && outofdate(n, a, 0))
69 						break;
70 				if(a == 0)
71 					continue;
72 			}
73 			ww->next = newword(buf);
74 			ww = ww->next;
75 			if(n == node) continue;
76 			n->next = node->next;
77 			node->next = n;
78 		}
79 	}
80 	for(n = node; n; n = n->next)
81 		if((n->flags&READY) == 0)
82 			return(did);
83 	/*
84 		gather the params for the job
85 	*/
86 	lp.next = ln.next = 0;
87 	for(n = node; n; n = n->next){
88 		for(a = n->prereqs; a; a = a->next){
89 			if(a->n){
90 				addw(&lp, a->n->name);
91 				if(outofdate(n, a, 0)){
92 					addw(&ln, a->n->name);
93 					if(explain)
94 						fprint(1, "%s(%ld) < %s(%ld)\n",
95 							n->name, n->time, a->n->name, a->n->time);
96 				}
97 			} else {
98 				if(explain)
99 					fprint(1, "%s has no prerequisites\n",
100 							n->name);
101 			}
102 		}
103 		MADESET(n, BEINGMADE);
104 	}
105 /*	print("lt=%s ln=%s lp=%s\n",wtos(head.next, ' '),wtos(ln.next, ' '),wtos(lp.next, ' '));/**/
106 	run(newjob(r, node, aa->stem, aa->match, lp.next, ln.next, head.next, ahead.next));
107 	return(1);
108 }
109 
110 void
addw(Word * w,char * s)111 addw(Word *w, char *s)
112 {
113 	Word *lw;
114 
115 	for(lw = w; w = w->next; lw = w){
116 		if(strcmp(s, w->s) == 0)
117 			return;
118 	}
119 	lw->next = newword(s);
120 }
121