xref: /inferno-os/utils/mk/rule.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1 #include	"mk.h"
2 
3 static Rule *lr, *lmr;
4 static int rcmp(Rule *r, char *target, Word *tail);
5 static int nrules = 0;
6 
7 void
addrule(char * head,Word * tail,char * body,Word * ahead,int attr,int hline,char * prog)8 addrule(char *head, Word *tail, char *body, Word *ahead, int attr, int hline, char *prog)
9 {
10 	Rule *r;
11 	Rule *rr;
12 	Symtab *sym;
13 	int reuse;
14 
15 	r = 0;
16 	reuse = 0;
17 	if(sym = symlook(head, S_TARGET, 0)){
18 		for(r = (Rule *)sym->value; r; r = r->chain)
19 			if(rcmp(r, head, tail) == 0){
20 				reuse = 1;
21 				break;
22 			}
23 	}
24 	if(r == 0)
25 		r = (Rule *)Malloc(sizeof(Rule));
26 	r->target = head;
27 	r->tail = tail;
28 	r->recipe = body;
29 	r->line = hline;
30 	r->file = infile;
31 	r->attr = attr;
32 	r->alltargets = ahead;
33 	r->prog = prog;
34 	r->rule = nrules++;
35 	if(!reuse){
36 		rr = (Rule *)symlook(head, S_TARGET, (void *)r)->value;
37 		if(rr != r){
38 			r->chain = rr->chain;
39 			rr->chain = r;
40 		} else
41 			r->chain = 0;
42 	}
43 	if(!reuse)
44 		r->next = 0;
45 	if((attr&REGEXP) || charin(head, "%&")){
46 		r->attr |= META;
47 		if(reuse)
48 			return;
49 		if(attr&REGEXP){
50 			patrule = r;
51 			r->pat = regcomp(head);
52 		}
53 		if(metarules == 0)
54 			metarules = lmr = r;
55 		else {
56 			lmr->next = r;
57 			lmr = r;
58 		}
59 	} else {
60 		if(reuse)
61 			return;
62 		r->pat = 0;
63 		if(rules == 0)
64 			rules = lr = r;
65 		else {
66 			lr->next = r;
67 			lr = r;
68 		}
69 	}
70 }
71 
72 void
dumpr(char * s,Rule * r)73 dumpr(char *s, Rule *r)
74 {
75 	Bprint(&bout, "%s: start=%ld\n", s, r);
76 	for(; r; r = r->next){
77 		Bprint(&bout, "\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(&bout, " prog='%s'", r->prog);
81 		Bprint(&bout, "\n\ttarget=%s: %s\n", r->target, wtos(r->tail, ' '));
82 		Bprint(&bout, "\trecipe@%ld='%s'\n", r->recipe, r->recipe);
83 	}
84 }
85 
86 static int
rcmp(Rule * r,char * target,Word * tail)87 rcmp(Rule *r, char *target, Word *tail)
88 {
89 	Word *w;
90 
91 	if(strcmp(r->target, target))
92 		return 1;
93 	for(w = r->tail; w && tail; w = w->next, tail = tail->next)
94 		if(strcmp(w->s, tail->s))
95 			return 1;
96 	return(w || tail);
97 }
98 
99 char *
rulecnt(void)100 rulecnt(void)
101 {
102 	char *s;
103 
104 	s = Malloc(nrules);
105 	memset(s, 0, nrules);
106 	return(s);
107 }
108