9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

rule.c (2110B)


      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
      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 = sym->u.ptr; 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->shellt = shellt;
     27 	r->shellcmd = shellcmd;
     28 	r->target = head;
     29 	r->tail = tail;
     30 	r->recipe = body;
     31 	r->line = hline;
     32 	r->file = infile;
     33 	r->attr = attr;
     34 	r->alltargets = ahead;
     35 	r->prog = prog;
     36 	r->rule = nrules++;
     37 	if(!reuse){
     38 		rr = symlook(head, S_TARGET, (void *)r)->u.ptr;
     39 		if(rr != r){
     40 			r->chain = rr->chain;
     41 			rr->chain = r;
     42 		} else
     43 			r->chain = 0;
     44 	}
     45 	if(!reuse)
     46 		r->next = 0;
     47 	if((attr&REGEXP) || shellt->charin(head, "%&")){
     48 		r->attr |= META;
     49 		if(reuse)
     50 			return;
     51 		if(attr&REGEXP){
     52 			patrule = r;
     53 			r->pat = regcomp(head);
     54 		}
     55 		if(metarules == 0)
     56 			metarules = lmr = r;
     57 		else {
     58 			lmr->next = r;
     59 			lmr = r;
     60 		}
     61 	} else {
     62 		if(reuse)
     63 			return;
     64 		r->pat = 0;
     65 		if(rules == 0)
     66 			rules = lr = r;
     67 		else {
     68 			lr->next = r;
     69 			lr = r;
     70 		}
     71 	}
     72 }
     73 
     74 void
     75 dumpr(char *s, Rule *r)
     76 {
     77 	if(r == nil)
     78 		return;
     79 	Bprint(&bout, "%s: start=%ld shelltype=%s shellcmd=%s\n", 
     80 		s, r, r->shellt->name, wtos(r->shellcmd, ' '));
     81 	for(; r; r = r->next){
     82 		Bprint(&bout, "\tRule %ld: %s[%d] attr=%x next=%ld chain=%ld alltarget='%s'",
     83 			r, r->file, r->line, r->attr, r->next, r->chain, wtos(r->alltargets, ' '));
     84 		if(r->prog)
     85 			Bprint(&bout, " prog='%s'", r->prog);
     86 		Bprint(&bout, "\n\ttarget=%s: %s\n", r->target, wtos(r->tail, ' '));
     87 		Bprint(&bout, "\trecipe@%ld='%s'\n", r->recipe, r->recipe);
     88 	}
     89 }
     90 
     91 static int
     92 rcmp(Rule *r, char *target, Word *tail)
     93 {
     94 	Word *w;
     95 
     96 	if(strcmp(r->target, target))
     97 		return 1;
     98 	for(w = r->tail; w && tail; w = w->next, tail = tail->next)
     99 		if(strcmp(w->s, tail->s))
    100 			return 1;
    101 	return(w || tail);
    102 }
    103 
    104 char *
    105 rulecnt(void)
    106 {
    107 	char *s;
    108 
    109 	s = Malloc(nrules);
    110 	memset(s, 0, nrules);
    111 	return(s);
    112 }