9base

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

recipe.c (2393B)


      1 #include	"mk.h"
      2 
      3 int
      4 dorecipe(Node *node)
      5 {
      6 	char buf[BIGBLOCK];
      7 	register Node *n;
      8 	Rule *r = 0;
      9 	Arc *a, *aa;
     10 	Word head, ahead, lp, ln, *w, *ww, *aw;
     11 	Symtab *s;
     12 	int did = 0;
     13 
     14 	aa = 0;
     15 	/*
     16 		pick up the rule
     17 	*/
     18 	for(a = node->prereqs; a; a = a->next)
     19 		if(*a->r->recipe)
     20 			r = (aa = a)->r;
     21 	/*
     22 		no recipe? go to buggery!
     23 	*/
     24 	if(r == 0){
     25 		if(!(node->flags&VIRTUAL) && !(node->flags&NORECIPE)){
     26 			fprint(2, "mk: no recipe to make '%s'\n", node->name);
     27 			Exit();
     28 		}
     29 		if(strchr(node->name, '(') && node->time == 0)
     30 			MADESET(node, MADE);
     31 		else
     32 			update(0, node);
     33 		if(tflag){
     34 			if(!(node->flags&VIRTUAL))
     35 				touch(node->name);
     36 			else if(explain)
     37 				Bprint(&bout, "no touch of virtual '%s'\n", node->name);
     38 		}
     39 		return(did);
     40 	}
     41 	/*
     42 		build the node list
     43 	*/
     44 	node->next = 0;
     45 	head.next = 0;
     46 	ww = &head;
     47 	ahead.next = 0;
     48 	aw = &ahead;
     49 	if(r->attr&REGEXP){
     50 		ww->next = newword(node->name);
     51 		aw->next = newword(node->name);
     52 	} else {
     53 		for(w = r->alltargets; w; w = w->next){
     54 			if(r->attr&META)
     55 				subst(aa->stem, w->s, buf);
     56 			else
     57 				strcpy(buf, w->s);
     58 			aw->next = newword(buf);
     59 			aw = aw->next;
     60 			if((s = symlook(buf, S_NODE, 0)) == 0)
     61 				continue;	/* not a node we are interested in */
     62 			n = s->u.ptr;
     63 			if(aflag == 0 && n->time) {
     64 				for(a = n->prereqs; a; a = a->next)
     65 					if(a->n && outofdate(n, a, 0))
     66 						break;
     67 				if(a == 0)
     68 					continue;
     69 			}
     70 			ww->next = newword(buf);
     71 			ww = ww->next;
     72 			if(n == node) continue;
     73 			n->next = node->next;
     74 			node->next = n;
     75 		}
     76 	}
     77 	for(n = node; n; n = n->next)
     78 		if((n->flags&READY) == 0)
     79 			return(did);
     80 	/*
     81 		gather the params for the job
     82 	*/
     83 	lp.next = ln.next = 0;
     84 	for(n = node; n; n = n->next){
     85 		for(a = n->prereqs; a; a = a->next){
     86 			if(a->n){
     87 				addw(&lp, a->n->name);
     88 				if(outofdate(n, a, 0)){
     89 					addw(&ln, a->n->name);
     90 					if(explain)
     91 						fprint(1, "%s(%ld) < %s(%ld)\n",
     92 							n->name, n->time, a->n->name, a->n->time);
     93 				}
     94 			} else {
     95 				if(explain)
     96 					fprint(1, "%s has no prerequisites\n",
     97 							n->name);
     98 			}
     99 		}
    100 		MADESET(n, BEINGMADE);
    101 	}
    102 	/*print("lt=%s ln=%s lp=%s\n",wtos(head.next, ' '),wtos(ln.next, ' '),wtos(lp.next, ' '));*/
    103 	run(newjob(r, node, aa->stem, aa->match, lp.next, ln.next, head.next, ahead.next));
    104 	return(1);
    105 }
    106 
    107 void
    108 addw(Word *w, char *s)
    109 {
    110 	Word *lw;
    111 
    112 	for(lw = w; w = w->next; lw = w){
    113 		if(strcmp(s, w->s) == 0)
    114 			return;
    115 	}
    116 	lw->next = newword(s);
    117 }