File:  [Research Unix] / researchv10no / cmd / mk / src / qed.hup:aq
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:34 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv10, HEAD
researchv10 Norman

#include	"mk.h"

int runerrs;

mk(target)
	char *target;
{
	Node *node;
	int did = 0;

	nproc();		/* it can be updated dynamically */
	nrep();			/* it can be updated dynamically */
	runerrs = 0;
	if(mflag)
		maketarget(target);
	node = graph(target);
	if(DEBUG(D_GRAPH)){
		dumpn("new target\n", node);
		Fflush(1);
	}
	clrmade(node);
	while(node->flags&NOTMADE){
		if(work(node, (Node *)0, (Arc *)0))
			did = 1;	/* found something to do */
		else {
			if(waitup(1, (int *)0) > 0){
				if(node->flags&(NOTMADE|BEINGMADE)){
					assert("must be run errors", runerrs);
					break;	/* nothing more waiting */
				}
			}
		}
	}
	if(node->flags&BEINGMADE)
		waitup(-1, (int *)0);
	while(jobs)
		waitup(-2, (int *)0);
	assert("target didn't get done", runerrs || (node->flags&MADE));
	if(did == 0)
		Fprint(1, "mk: '%s' is up to date\n", node->name);
}

clrmade(n)
	register Node *n;
{
	register Arc *a;

	n->flags &= ~(CANPRETEND|PRETENDING);
	n->flags |= CANPRETEND;
	MADESET(n, NOTMADE);
	for(a = n->prereqs; a; a = a->next)
		if(a->n)
			clrmade(a->n);
}

static void
unpretend(n)
	register Node *n;
{
	MADESET(n, NOTMADE);
	n->flags &= ~(CANPRETEND|PRETENDING);
	n->time = 0;
}

work(node, p, parc)
	Node *node, *p;
	Arc *parc;
{
	register Arc *a, *ra;
	int weoutofdate;
	int ready;
	int did = 0;

	print("work(%s) flags=0x%x time=%ld\n", node->name, node->flags, node->time);/**/
	if(node->flags&BEINGMADE)
		return(did);
	if((node->flags&MADE) && (node->flags&PRETENDING) && p && outofdate(p, parc, 0)){
		if(explain)
			fprint(1, "unpretending %s(%ld) because %s is out of date(%ld)\n",
				node->name, node->time, p->name, p->time);
		unpretend(node);
	}
	/*
		have a look if we are pretending in case
		someone has been unpretended out from underneath us
	*/
	if(node->flags&MADE){
		if(node->flags&PRETENDING){
			node->time = 0;
		}else
			return(did);
	}
	/* consider no prerequsite case */
	if(node->prereqs == 0){
		if(node->time == 0){
			Fprint(2, "mk: don't know how to make '%s'\n", node->name);
			if(kflag){
				node->flags |= BEINGMADE;
				runerrs++;
			} else
				Exit();
		} else
			MADESET(node, MADE);
		return(did);
	}
	/*
		now see if we are out of date or what
	*/
	ready = 1;
	weoutofdate = aflag;
	ra = 0;
	for(a = node->prereqs; a; a = a->next)
		if(a->n){
			did = work(a->n, node, a) || did;
			if(a->n->flags&(NOTMADE|BEINGMADE))
				ready = 0;
			if(outofdate(node, a, 0)){
				weoutofdate = 1;
				if((ra == 0) || (ra->n == 0)
						|| (ra->n->time < a->n->time))
					ra = a;
			}
		} else {
			if(node->time == 0){
				if(ra == 0)
					ra = a;
				weoutofdate = 1;
			}
		}
	if(ready == 0)	/* can't do anything now */
		return(did);
	if(weoutofdate == 0){
		MADESET(node, MADE);
		return(did);
	}
	/*
		can we pretend to be made?
	*/
	if((iflag == 0) && (node->time == 0) && (node->flags&(PRETENDING|CANPRETEND)) && p && ra->n && !outofdate(p, ra, 0)){
		node->flags &= ~CANPRETEND;
		MADESET(node, MADE);
		node->time = ra->n->time;
		if(explain && ((node->flags&PRETENDING) == 0))
			fprint(1, "pretending %s has time %ld\n", node->name, node->time);
		node->flags |= PRETENDING;
		return(did);
	}
	/*
		node is out of date and we REALLY do have to do something.
		quickly rescan for pretenders
	*/
	for(a = node->prereqs; a; a = a->next)
		if(a->n && (a->n->flags&PRETENDING)){
			if(explain)
				Fprint(1, "unpretending %s because of %s because of %s\n",
				a->n->name, node->name, ra->n? ra->n->name : "rule with no prerequisites");

			unpretend(a->n);
			did = work(a->n, node, a) || did;
			ready = 0;
		}
	if(ready == 0)	/* try later unless nothing has happened for -k's sake */
		return(did || work(node, p, parc));
	did = dorecipe(node) || did;
	return(did);
}

update(fake, node)
	register Node *node;
{
	register Arc *a;

	MADESET(node, fake? BEINGMADE : MADE);
	if(((node->flags&VIRTUAL) == 0) && (access(node->name, 0) == 0)){
		node->time = timeof(node->name, 1);
		node->flags &= ~(CANPRETEND|PRETENDING);
		for(a = node->prereqs; a; a = a->next)
			if(a->prog)
				(void)outofdate(node, a, 1);
	} else {
		node->time = 1;
		for(a = node->prereqs; a; a = a->next)
			if(a->n && outofdate(node, a, 1))
				node->time = a->n->time;
	}
	print("----node %s time=%ld flags=0x%x\n", node->name, node->time, node->flags);/**/
}

static
pcmp(prog, n1, n2)
	char *prog, *n1, *n2;
{
	char buf[3*NAMEBLOCK];
	int ret, pid;

	pid = fork();
	if(pid < 0){
		fprint(2, "mk: ");
		perror("pcmp fork");
		Exit();
	}
	Fexit(0);
	if(pid == 0){
		sprint(buf, "%s '%s' '%s'", prog, n1, n2);
		execle("/bin/sh", "sh", "-c", buf, (char *)0);
		perror("exec /bin/sh");
		_exit(1);
	} else {
		while(waitup(-3, &pid) >= 0)
			;
		return(pid? 2:1);
	}
}


outofdate(node, arc, eval)
	register Node *node;
	register Arc *arc;
{
	char buf[3*NAMEBLOCK], *str;
	Symtab *sym;
	int ret;

	if(arc->prog){
		sprint(buf, "%s%c%s", node->name, 0377, arc->n->name);
		if(!(sym = symlook(buf, S_OUTOFDATE, (char *)0)) || eval){
			if(!sym)
				str = strdup(buf);
			ret = pcmp(arc->prog, node->name, arc->n->name);
			if(sym)
				sym->value = (char *)ret;
			else
				symlook(str, S_OUTOFDATE, (char *)ret);
		} else
			ret = (int)sym->value;
		return(ret-1);
	} else
		return(node->time < arc->n->time);
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.