xref: /plan9-contrib/sys/src/cmd/mk/rule.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include	"mk.h"
2 
3 static Rule *lr, *lmr;
4 static rcmp(Rule *r, char *target, Word *tail);
5 static int nrules = 0;
6 
7 void
8 addrule(char *head, Word *tail, char *body, Word *ahead, int attr, int hline, int override, char *prog)
9 {
10 	Rule *r;
11 	Rule *rr;
12 	Symtab *sym;
13 	int reuse;
14 
15 	if(sym = symlook(head, S_TARGET, (char *)0)){
16 		for(r = (Rule *)sym->value; r; r = r->chain)
17 			if(rcmp(r, head, tail) == 0) break;
18 		if(r && !override)
19 			return;
20 	} else
21 		r = 0;
22 	reuse = r != 0;
23 	if(r == 0)
24 		r = (Rule *)Malloc(sizeof(Rule));
25 	r->target = head;
26 	r->tail = tail;
27 	r->recipe = body;
28 	r->line = hline;
29 	r->file = infile;
30 	r->attr = attr;
31 	r->alltargets = ahead;
32 	r->prog = prog;
33 	r->rule = nrules++;
34 	if(!reuse){
35 		rr = (Rule *)symlook(head, S_TARGET, (char *)r)->value;
36 		if(rr != r){
37 			r->chain = rr->chain;
38 			rr->chain = r;
39 		} else
40 			r->chain = 0;
41 	}
42 	if(utfrune(head, '%') || utfrune(head, '&') || (attr&REGEXP))
43 		goto meta;
44 	if(reuse)
45 		return;
46 	r->next = 0;
47 	r->pat = 0;
48 	if(rules == 0)
49 		rules = lr = r;
50 	else {
51 		lr->next = r;
52 		lr = r;
53 	}
54 	return;
55 meta:
56 	r->attr |= META;
57 	if(reuse)
58 		return;
59 	r->next = 0;
60 	if(r->attr&REGEXP){
61 		patrule = r;
62 		r->pat = regcomp(head);
63 	}
64 	if(metarules == 0)
65 		metarules = lmr = r;
66 	else {
67 		lmr->next = r;
68 		lmr = r;
69 	}
70 }
71 
72 void
73 dumpr(char *s, Rule *r)
74 {
75 	Bprint(&stdout, "%s: start=%ld\n", s, r);
76 	for(; r; r = r->next){
77 		Bprint(&stdout, "\tRule %ld: %s[%d] attr=%x next=%ld chain=%ld alltarget='%s'",
78 			r, r->file, r->line, r->attr, r->next, r->chain, wtos(r->alltargets));
79 		if(r->prog)
80 			Bprint(&stdout, " prog='%s'", r->prog);
81 		Bprint(&stdout, "\n\ttarget=%s: %s\n", r->target, wtos(r->tail));
82 		Bprint(&stdout, "\trecipe@%ld='%s'\n", r->recipe, r->recipe);
83 	}
84 }
85 
86 void
87 frule(Word *w)
88 {
89 	extern Word *target1;
90 	Word *ww;
91 	char *s;
92 
93 #define	ADD(s)	{if(target1==0)target1=ww=newword(s);else ww=ww->next=newword(s);}
94 
95 	for(ww = w; ww; ww = ww->next)
96 		if(utfrune(w->s, '%') || utfrune(w->s, '&'))
97 			return;	/* no metarule targets */
98 	while(w && w->s){
99 		if(s = utfrune(w->s, '+')){
100 			*s++ = 0;
101 			if(*w->s)
102 				ADD(w->s);
103 			if(*s)
104 				ADD(s);
105 			s[-1] = '+';
106 		} else
107 			ADD(w->s);
108 		w = w->next;
109 	}
110 }
111 
112 static int
113 rcmp(Rule *r, char *target, Word *tail)
114 {
115 	Word *w;
116 
117 	if(strcmp(r->target, target))
118 		return(1);
119 	for(w = r->tail; w && tail; w = w->next, tail = tail->next)
120 		if(strcmp(w->s, tail->s))
121 			return(1);
122 	return(w || tail);
123 }
124 
125 char *
126 rulecnt(void)
127 {
128 	char *s;
129 
130 	s = Malloc(nrules);
131 	memset(s, 0, nrules);
132 	return(s);
133 }
134