⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mk.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"mk.h"int runerrs;voidmk(char *target){	Node *node;	int did = 0;	nproc();		/* it can be updated dynamically */	nrep();			/* it can be updated dynamically */	runerrs = 0;	node = graph(target);	if(DEBUG(D_GRAPH)){		dumpn("new target\n", node);		Bflush(&bout);	}	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 didnt get done*/ runerrs || (node->flags&MADE));	if(did == 0)		Bprint(&bout, "mk: '%s' is up to date\n", node->name);}voidclrmade(Node *n){	Arc *a;	n->flags &= ~(CANPRETEND|PRETENDING);	if(strchr(n->name, '(') ==0 || n->time)		n->flags |= CANPRETEND;	MADESET(n, NOTMADE);	for(a = n->prereqs; a; a = a->next)		if(a->n)			clrmade(a->n);}static voidunpretend(Node *n){	MADESET(n, NOTMADE);	n->flags &= ~(CANPRETEND|PRETENDING);	n->time = 0;}intwork(Node *node, Node *p, Arc *parc){	Arc *a, *ra;	int weoutofdate;	int ready;	int did = 0;	char cwd[128];	/*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 prerequisite case */	if(node->prereqs == 0){		if(node->time == 0){			if(getwd(cwd, sizeof cwd))				fprint(2, "mk: don't know how to make '%s' in directory %s\n", node->name, cwd);			else				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);		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)				Bprint(&bout, "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);}voidupdate(int fake, Node *node){	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)				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);/**/}staticpcmp(char *prog, char *p, char *q){	char buf[3*NAMEBLOCK];	int pid;	Bflush(&bout);	sprint(buf, "%s '%s' '%s'\n", prog, p, q);	pid = pipecmd(buf, 0, 0);	while(waitup(-3, &pid) >= 0)		;	return(pid? 2:1);}intoutofdate(Node *node, Arc *arc, int eval){	char buf[3*NAMEBLOCK], *str;	Symtab *sym;	int ret;	str = 0;	if(arc->prog){		sprint(buf, "%s%c%s", node->name, 0377, arc->n->name);		sym = symlook(buf, S_OUTOFDATE, 0);		if(sym == 0 || eval){			if(sym == 0)				str = strdup(buf);			ret = pcmp(arc->prog, node->name, arc->n->name);			if(sym)				sym->u.value = ret;			else				symlook(str, S_OUTOFDATE, (void *)ret);		} else			ret = sym->u.value;		return(ret-1);	} else if(strchr(arc->n->name, '(') && arc->n->time == 0)  /* missing archive member */		return 1;	else		/*		 * Treat equal times as out-of-date.		 * It's a race, and the safer option is to do		 * extra building rather than not enough.	 	 */		return node->time <= arc->n->time;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -