xref: /plan9/sys/src/cmd/mk/rule.c (revision 254fe3d33c382063ab759e3351c8169ee4bc264e)
13e12c5d1SDavid du Colombier #include	"mk.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier static Rule *lr, *lmr;
43e12c5d1SDavid du Colombier static rcmp(Rule *r, char *target, Word *tail);
53e12c5d1SDavid du Colombier static int nrules = 0;
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier void
addrule(char * head,Word * tail,char * body,Word * ahead,int attr,int hline,char * prog)87dd7cddfSDavid du Colombier addrule(char *head, Word *tail, char *body, Word *ahead, int attr, int hline, char *prog)
93e12c5d1SDavid du Colombier {
103e12c5d1SDavid du Colombier 	Rule *r;
113e12c5d1SDavid du Colombier 	Rule *rr;
123e12c5d1SDavid du Colombier 	Symtab *sym;
133e12c5d1SDavid du Colombier 	int reuse;
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier 	r = 0;
167dd7cddfSDavid du Colombier 	reuse = 0;
177dd7cddfSDavid du Colombier 	if(sym = symlook(head, S_TARGET, 0)){
184de34a7eSDavid du Colombier 		for(r = sym->u.ptr; r; r = r->chain)
197dd7cddfSDavid du Colombier 			if(rcmp(r, head, tail) == 0){
207dd7cddfSDavid du Colombier 				reuse = 1;
217dd7cddfSDavid du Colombier 				break;
227dd7cddfSDavid du Colombier 			}
237dd7cddfSDavid du Colombier 	}
243e12c5d1SDavid du Colombier 	if(r == 0)
253e12c5d1SDavid du Colombier 		r = (Rule *)Malloc(sizeof(Rule));
263e12c5d1SDavid du Colombier 	r->target = head;
273e12c5d1SDavid du Colombier 	r->tail = tail;
283e12c5d1SDavid du Colombier 	r->recipe = body;
293e12c5d1SDavid du Colombier 	r->line = hline;
303e12c5d1SDavid du Colombier 	r->file = infile;
313e12c5d1SDavid du Colombier 	r->attr = attr;
323e12c5d1SDavid du Colombier 	r->alltargets = ahead;
333e12c5d1SDavid du Colombier 	r->prog = prog;
343e12c5d1SDavid du Colombier 	r->rule = nrules++;
357dd7cddfSDavid du Colombier 
363e12c5d1SDavid du Colombier 	if(!reuse){
374de34a7eSDavid du Colombier 		rr = symlook(head, S_TARGET, r)->u.ptr;
383e12c5d1SDavid du Colombier 		if(rr != r){
393e12c5d1SDavid du Colombier 			r->chain = rr->chain;
403e12c5d1SDavid du Colombier 			rr->chain = r;
413e12c5d1SDavid du Colombier 		} else
423e12c5d1SDavid du Colombier 			r->chain = 0;
433e12c5d1SDavid du Colombier 	}
447dd7cddfSDavid du Colombier 	if(!reuse)
453e12c5d1SDavid du Colombier 		r->next = 0;
467dd7cddfSDavid du Colombier 	if((attr&REGEXP) || charin(head, "%&")){
473e12c5d1SDavid du Colombier 		r->attr |= META;
483e12c5d1SDavid du Colombier 		if(reuse)
493e12c5d1SDavid du Colombier 			return;
507dd7cddfSDavid du Colombier 		if(attr&REGEXP){
513e12c5d1SDavid du Colombier 			patrule = r;
523e12c5d1SDavid du Colombier 			r->pat = regcomp(head);
533e12c5d1SDavid du Colombier 		}
543e12c5d1SDavid du Colombier 		if(metarules == 0)
553e12c5d1SDavid du Colombier 			metarules = lmr = r;
563e12c5d1SDavid du Colombier 		else {
573e12c5d1SDavid du Colombier 			lmr->next = r;
583e12c5d1SDavid du Colombier 			lmr = r;
593e12c5d1SDavid du Colombier 		}
607dd7cddfSDavid du Colombier 	} else {
617dd7cddfSDavid du Colombier 		if(reuse)
627dd7cddfSDavid du Colombier 			return;
637dd7cddfSDavid du Colombier 		r->pat = 0;
647dd7cddfSDavid du Colombier 		if(rules == 0)
657dd7cddfSDavid du Colombier 			rules = lr = r;
667dd7cddfSDavid du Colombier 		else {
677dd7cddfSDavid du Colombier 			lr->next = r;
687dd7cddfSDavid du Colombier 			lr = r;
697dd7cddfSDavid du Colombier 		}
707dd7cddfSDavid du Colombier 	}
713e12c5d1SDavid du Colombier }
723e12c5d1SDavid du Colombier 
733e12c5d1SDavid du Colombier void
dumpr(char * s,Rule * r)743e12c5d1SDavid du Colombier dumpr(char *s, Rule *r)
753e12c5d1SDavid du Colombier {
767dd7cddfSDavid du Colombier 	Bprint(&bout, "%s: start=%p\n", s, r);
773e12c5d1SDavid du Colombier 	for(; r; r = r->next){
78*254fe3d3SDavid du Colombier 		Bprint(&bout, "\tRule %p: %s:%d attr=%x next=%p chain=%p alltarget='%s'",
797dd7cddfSDavid du Colombier 			r, r->file, r->line, r->attr, r->next, r->chain, wtos(r->alltargets, ' '));
803e12c5d1SDavid du Colombier 		if(r->prog)
817dd7cddfSDavid du Colombier 			Bprint(&bout, " prog='%s'", r->prog);
827dd7cddfSDavid du Colombier 		Bprint(&bout, "\n\ttarget=%s: %s\n", r->target, wtos(r->tail,' '));
837dd7cddfSDavid du Colombier 		Bprint(&bout, "\trecipe@%p='%s'\n", r->recipe, r->recipe);
843e12c5d1SDavid du Colombier 	}
853e12c5d1SDavid du Colombier }
863e12c5d1SDavid du Colombier 
873e12c5d1SDavid du Colombier static int
rcmp(Rule * r,char * target,Word * tail)883e12c5d1SDavid du Colombier rcmp(Rule *r, char *target, Word *tail)
893e12c5d1SDavid du Colombier {
903e12c5d1SDavid du Colombier 	Word *w;
913e12c5d1SDavid du Colombier 
923e12c5d1SDavid du Colombier 	if(strcmp(r->target, target))
937dd7cddfSDavid du Colombier 		return 1;
943e12c5d1SDavid du Colombier 	for(w = r->tail; w && tail; w = w->next, tail = tail->next)
953e12c5d1SDavid du Colombier 		if(strcmp(w->s, tail->s))
967dd7cddfSDavid du Colombier 			return 1;
973e12c5d1SDavid du Colombier 	return(w || tail);
983e12c5d1SDavid du Colombier }
993e12c5d1SDavid du Colombier 
1003e12c5d1SDavid du Colombier char *
rulecnt(void)1013e12c5d1SDavid du Colombier rulecnt(void)
1023e12c5d1SDavid du Colombier {
1033e12c5d1SDavid du Colombier 	char *s;
1043e12c5d1SDavid du Colombier 
1053e12c5d1SDavid du Colombier 	s = Malloc(nrules);
1063e12c5d1SDavid du Colombier 	memset(s, 0, nrules);
1073e12c5d1SDavid du Colombier 	return(s);
1083e12c5d1SDavid du Colombier }
109