#include	"mk.h"

static Node *applyrules(char *, char *);
static void togo(Node *);
static int vacuous(Node *);
static Node *newnode(char *);
static void trace(char *, Arc *);
static void cyclechk(Node *);
static void ambiguous(Node *);
static void attribute(Node *);

Node *
graph(char *target)
{
	Node *node;
	char *cnt;

	cnt = rulecnt();
	node = applyrules(target, cnt);
	free(cnt);
	cyclechk(node);
	node->flags |= PROBABLE;	/* make sure it doesn't get deleted */
	vacuous(node);
	ambiguous(node);
	attribute(node);
	return(node);
}

static Node *
applyrules(char *target, char *cnt)
{
	Symtab *sym;
	Node *node;
	Rule *r;
	Arc head, *a = &head;
	Word *w;
	char stem[NAMEBLOCK], buf[NAMEBLOCK];
	Resub rmatch[NREGEXP];

/*	print("applyrules(%lux='%s')\n", target, target);*//**/
	sym = symlook(target, S_NODE, 0);
	if(sym)
		return (Node *)(sym->value);
	target = strdup(target);
	node = newnode(target);
	head.n = 0;
	head.next = 0;
	sym = symlook(target, S_TARGET, 0);
	memset((char*)rmatch, 0, sizeof(rmatch));
	for(r = sym? (Rule *)(sym->value):0; r; r = r->chain){
		if(r->attr&META) continue;
		if(strcmp(target, r->target)) continue;
		if((!r->recipe || !*r->recipe) && (!r->tail || !r->tail->s || !*r->tail->s)) continue;	/* no effect; ignore */
		if(cnt[r->rule] >= nreps) continue;
		cnt[r->rule]++;
		node->flags |= PROBABLE;

/*		if(r->attr&VIR)
 *			node->flags |= VIRTUAL;
 *		if(r->attr&NOREC)
 *			node->flags |= NORECIPE;
 *		if(r->attr&DEL)
 *			node->flags |= DELETE;
 */
		if(!r->tail || !r->tail->s || !*r->tail->s) {
			a->next = newarc((Node *)0, r, "", rmatch);
			a = a->next;
		} else
			for(w = r->tail; w; w = w->next){
				a->next = newarc(applyrules(w->s, cnt), r, "", rmatch);
				a = a->next;
		}
		cnt[r->rule]--;
		head.n = node;
	}
	for(r = metarules; r; r = r->next){
		if((!r->recipe || !*r->recipe) && (!r->tail || !r->tail->s || !*r->tail->s)) continue;	/* no effect; ignore */
		if ((r->attr&NOVIRT) && a != &head && (a->r->attr&VIR))
			continue;
		if(r->attr&REGEXP){
			stem[0] = 0;
			patrule = r;
			memset((char*)rmatch, 0, sizeof(rmatch));
			if(regexec(r->pat, node->name, rmatch, NREGEXP) == 0)
				continue;
		} else {
			if(!match(node->name, r->target, stem)) continue;
		}
		if(cnt[r->rule] >= nreps) continue;
		cnt[r->rule]++;

/*		if(r->attr&VIR)
 *			node->flags |= VIRTUAL;
 *		if(r->attr&NOREC)
 *			node->flags |= NORECIPE;
 *		if(r->attr&DEL)
 *			node->flags |= DELETE;
 */

		if(!r->tail || !r->tail->s || !*r->tail->s) {
			a->next = newarc((Node *)0, r, stem, rmatch);
			a = a->next;
		} else
			for(w = r->tail; w; w = w->next){
				if(r->attr&REGEXP)
					regsub(w->s, buf, sizeof buf, rmatch, NREGEXP);
				else
					subst(stem, w->s, buf);
				a->next = newarc(applyrules(buf, cnt), r, stem, rmatch);
				a = a->next;
			}
		cnt[r->rule]--;
	}
	a->next = node->prereqs;
	node->prereqs = head.next;
	return(node);
}

static void
togo(Node *node)
{
	Arc *la, *a;

	/* delete them now */
	la = 0;
	for(a = node->prereqs; a; la = a, a = a->next)
		if(a->flag&TOGO){
			if(a == node->prereqs)
				node->prereqs = a->next;
			else
				la->next = a->next, a = la;
		}
}

static int
vacuous(Node *node)
{
	Arc *la, *a;
	int vac = !(node->flags&PROBABLE);

	if(node->flags&READY)
		return(node->flags&VACUOUS);
	node->flags |= READY;
	for(a = node->prereqs; a; a = a->next)
		if(a->n && vacuous(a->n) && (a->r->attr&META))
			a->flag |= TOGO;
		else
			vac = 0;
	/* if a rule generated arcs that DON'T go; no others from that rule go */
	for(a = node->prereqs; a; a = a->next)
		if((a->flag&TOGO) == 0)
			for(la = node->prereqs; la; la = la->next)
				if((la->flag&TOGO) && (la->r == a->r)){
					la->flag &= ~TOGO;
				}
	togo(node);
	if(vac)
		node->flags |= VACUOUS;
	return(vac);
}

static Node *
newnode(char *name)
{
	register Node *node;

	node = (Node *)Malloc(sizeof(Node));
	symlook(name, S_NODE, (void *)node);
	node->name = name;
	node->time = timeof(name, 0);
	node->prereqs = 0;
	node->flags = node->time? PROBABLE : 0;
	node->next = 0;
	return(node);
}

void
dumpn(char *s, Node *n)
{
	char buf[1024];
	Arc *a;

	snprint(buf, sizeof buf, "%s   ", (*s == ' ')? s:"");
	Bprint(&bout, "%s%s@%ld: time=%ld flags=0x%x next=%ld\n",
		s, n->name, n, n->time, n->flags, n->next);
	for(a = n->prereqs; a; a = a->next)
		dumpa(buf, a);
}

static void
trace(char *s, Arc *a)
{
	fprint(2, "\t%s", s);
	while(a){
		fprint(2, " <-(%s:%d)- %s", a->r->file, a->r->line,
			a->n? a->n->name:"");
		if(a->n){
			for(a = a->n->prereqs; a; a = a->next)
				if(*a->r->recipe) break;
		} else
			a = 0;
	}
	fprint(2, "\n");
}

static void
cyclechk(Node *n)
{
	Arc *a;

	if((n->flags&CYCLE) && n->prereqs){
		fprint(2, "mk: cycle in graph detected at target %s\n", n->name);
		Exit();
	}
	n->flags |= CYCLE;
	for(a = n->prereqs; a; a = a->next)
		if(a->n)
			cyclechk(a->n);
	n->flags &= ~CYCLE;
}

static void
ambiguous(Node *n)
{
	Arc *a;
	Rule *r = 0;
	Arc *la;
	int bad = 0;

	la = 0;
	for(a = n->prereqs; a; a = a->next){
		if(a->n)
			ambiguous(a->n);
		if(*a->r->recipe == 0) continue;
		if(r == 0)
			r = a->r, la = a;
		else{
			if(r->recipe != a->r->recipe){
				if((r->attr&META) && !(a->r->attr&META)){
					la->flag |= TOGO;
					r = a->r, la = a;
				} else if(!(r->attr&META) && (a->r->attr&META)){
					a->flag |= TOGO;
					continue;
				}
			}
			if(r->recipe != a->r->recipe){
				if(bad == 0){
					fprint(2, "mk: ambiguous recipes for %s:\n", n->name);
					bad = 1;
					trace(n->name, la);
				}
				trace(n->name, a);
			}
		}
	}
	if(bad)
		Exit();
	togo(n);
}

static void
attribute(Node *n)
{
	register Arc *a;

	for(a = n->prereqs; a; a = a->next){
		if(a->r->attr&VIR)
			n->flags |= VIRTUAL;
		if(a->r->attr&NOREC)
			n->flags |= NORECIPE;
		if(a->r->attr&DEL)
			n->flags |= DELETE;
		if(a->n)
			attribute(a->n);
	}
	if(n->flags&VIRTUAL)
		n->time = 0;
}
