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®EXP)) 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®EXP){ 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