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

📄 view.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
{	Xentry *t = (Xentry*)tt;	if(t->nkid >= 0)		return;	t->nkid = 1;	t->kid = mallocz(sizeof(t->kid[0])*t->nkid, 1);	t->kid[0] = initxsource(t->e, 1);}Tnode*initxentry(Entry e){	Xentry *t;	t = mallocz(sizeof *t, 1);	t->nkid = -1;	t->str = smprint("Entry gen=%#ux psize=%d dsize=%d depth=%d flags=%#ux size=%lld score=%V",		e.gen, e.psize, e.dsize, e.depth, e.flags, e.size, e.score);	if(e.flags & VtEntryLocal)		t->str = smprint("%s archive=%d snap=%d tag=%#ux", t->str, e.archive, e.snap, e.tag);	t->expand = xentryexpand;	t->e = e;	return t;	}intptrgen(void *v, Block *b, int o, Tnode **tp){	Entry *ed;	Entry e;	ed = v;	if(o >= ed->psize/VtScoreSize)		return -1;	e = *ed;	e.depth--;	memmove(e.score, b->data+o*VtScoreSize, VtScoreSize);	if(memcmp(e.score, vtZeroScore, VtScoreSize) == 0)		return 0;	*tp = initxsource(e, 0);	return 1;}static intetype(int flags, int depth){	uint t;	if(flags&VtEntryDir)		t = BtDir;	else		t = BtData;	return t+depth;}Tnode*initxsource(Entry e, int dowrap){	Block *b;	Tnode *t, *tt;	b = dataBlock(e.score, etype(e.flags, e.depth), e.tag);	if(b == nil)		return stringnode("dataBlock: %r");	if((e.flags & VtEntryActive) == 0)		return stringnode("inactive Entry");	if(e.depth == 0){		if(e.flags & VtEntryDir)			tt = initxentryblock(b, copyEntry(e));		else			tt = initxdatablock(b, e.dsize);	}else{		tt = initxblock(b, smprint("%s+%d pointer", (e.flags & VtEntryDir) ? "BtDir" : "BtData", e.depth),			ptrgen, copyEntry(e));	}	/*	 * wrap the contents of the Source in a Source node,	 * just so it's closer to what you see in the code.	 */	if(dowrap){		t = stringnode("Source");		t->nkid = 1;		t->kid = mallocz(sizeof(Tnode*)*1, 1);		t->kid[0] = tt;		tt = t;	}	return tt;}intxlocalrootgen(void*, Block *b, int o, Tnode **tp){	Entry e;	if(o >= 1)		return -1;	entryUnpack(&e, b->data, o);	*tp = initxentry(e);	return 1;}Tnode*initxlocalroot(char *name, u32int addr){	uchar score[VtScoreSize];	Block *b;	localToGlobal(addr, score);	b = dataBlock(score, BtDir, RootTag);	if(b == nil)		return stringnode("read data block %#ux: %R", addr);	return initxblock(b, smprint("'%s' fs root", name), xlocalrootgen, nil);}intxvacrootgen(void*, Block *b, int o, Tnode **tp){	Entry e;	if(o >= 3)		return -1;	entryUnpack(&e, b->data, o);	*tp = initxentry(e);	return 1;}Tnode*initxroot(char *name, uchar score[VtScoreSize]){	Block *b;	b = dataBlock(score, BtDir, RootTag);	if(b == nil)		return stringnode("read data block %V: %R", score);	return initxblock(b, smprint("'%s' fs root", name), xvacrootgen, nil);}Tnode*initxdirentry(MetaEntry *me){	DirEntry dir;	Tnode *t;	if(!deUnpack(&dir, me))		return stringnode("deUnpack: %R");	t = stringnode("dirEntry elem=%s size=%llud data=%#lux/%#lux meta=%#lux/%#lux", dir.elem, dir.size, dir.entry, dir.gen, dir.mentry, dir.mgen);	t->nkid = 1;	t->kid = mallocz(sizeof(t->kid[0])*1, 1);	t->kid[0] = stringnode(		"qid=%#llux\n"		"uid=%s gid=%s mid=%s\n"		"mtime=%lud mcount=%lud ctime=%lud atime=%lud\n"		"mode=%luo\n"		"plan9 %d p9path %#llux p9version %lud\n"		"qidSpace %d offset %#llux max %#llux",		dir.qid,		dir.uid, dir.gid, dir.mid,		dir.mtime, dir.mcount, dir.ctime, dir.atime,		dir.mode,		dir.plan9, dir.p9path, dir.p9version,		dir.qidSpace, dir.qidOffset, dir.qidMax);	return t;}intmetaentrygen(void *v, Block*, int o, Tnode **tp){	Tnode *t;	MetaBlock *mb;	MetaEntry me;	mb = v;	if(o >= mb->nindex)		return -1;	meUnpack(&me, mb, o);	t = stringnode("MetaEntry %d bytes", mb->size);	t->kid = mallocz(sizeof(t->kid[0])*1, 1);	t->kid[0] = initxdirentry(&me);	t->nkid = 1;	*tp = t;	return 1;}intmetablockgen(void *v, Block *b, int o, Tnode **tp){	Xblock *t;	MetaBlock *mb;	if(o >= 1)		return -1;	/* hack: reuse initxblock as a generic iterator */	mb = v;	t = (Xblock*)initxblock(b, "", metaentrygen, mb);	t->str = smprint("MetaBlock %d/%d space used, %d add'l free %d/%d table used%s",		mb->size, mb->maxsize, mb->free, mb->nindex, mb->maxindex,		mb->botch ? " [BOTCH]" : "");	t->printlabel = 0;	*tp = t;	return 1;}/* * attempt to guess at the type of data in the block. * it could just be data from a file, but we're hoping it's MetaBlocks. */Tnode*initxdatablock(Block *b, uint n){	MetaBlock mb;	if(n > h.blockSize)		n = h.blockSize;	if(mbUnpack(&mb, b->data, n))		return initxblock(b, "metadata", metablockgen, copyMetaBlock(mb));	return initxblock(b, "data", nil, nil);}intparseScore(uchar *score, char *buf, int n){	int i, c;	memset(score, 0, VtScoreSize);	if(n < VtScoreSize*2)		return 0;	for(i=0; i<VtScoreSize*2; i++){		if(buf[i] >= '0' && buf[i] <= '9')			c = buf[i] - '0';		else if(buf[i] >= 'a' && buf[i] <= 'f')			c = buf[i] - 'a' + 10;		else if(buf[i] >= 'A' && buf[i] <= 'F')			c = buf[i] - 'A' + 10;		else{			return 0;		}		if((i & 1) == 0)			c <<= 4;			score[i>>1] |= c;	}	return 1;}intscoreFmt(Fmt *f){	uchar *v;	int i;	u32int addr;	v = va_arg(f->args, uchar*);	if(v == nil){		fmtprint(f, "*");	}else if((addr = globalToLocal(v)) != NilBlock)		fmtprint(f, "0x%.8ux", addr);	else{		for(i = 0; i < VtScoreSize; i++)			fmtprint(f, "%2.2ux", v[i]);	}	return 0;}Atree*atreeinit(char *arg){	Atree *a;	uchar score[VtScoreSize];	vtAttach();	fmtinstall('V', scoreFmt);	fmtinstall('R', vtErrFmt);	z = vtDial(nil, 1);	if(z == nil)		fprint(2, "warning: cannot dial venti: %R\n");	if(!vtConnect(z, 0)){		fprint(2, "warning: cannot connect to venti: %R\n");		z = nil;	}	a = mallocz(sizeof(Atree), 1);	if(strncmp(arg, "vac:", 4) == 0){		if(!parseScore(score, arg+4, strlen(arg+4))){			fprint(2, "cannot parse score\n");			return nil;		}		a->root = initxvacroot(score);	}else		a->root = initxcache(arg);	a->resizefd = -1;	return a;}/* --- tree.c */enum{	Nubwidth = 11,	Nubheight = 11,	Linewidth = Nubwidth*2+4,};uintdrawtext(char *s, Image *m, Image *clipr, Point o){	char *t, *nt, *e;	uint dy;	if(s == nil)		s = "???";	dy = 0;	for(t=s; t&&*t; t=nt){		if(nt = strchr(t, '\n')){			e = nt;			nt++;		}else			e = t+strlen(t);		_string(m, Pt(o.x, o.y+dy), display->black, ZP, display->defaultfont,			t, nil, e-t, clipr->clipr, nil, ZP, SoverD);		dy += display->defaultfont->height;	}	return dy;}voiddrawnub(Image *m, Image *clipr, Point o, Tnode *t){	clipr = nil;	if(t->nkid == 0)		return;	if(t->nkid == -1 && t->expand == nil)		return;	o.y += (display->defaultfont->height-Nubheight)/2;	draw(m, rectaddpt(Rect(0,0,1,Nubheight), o), display->black, clipr, ZP);	draw(m, rectaddpt(Rect(0,0,Nubwidth,1), o), display->black, clipr, o);	draw(m, rectaddpt(Rect(Nubwidth-1,0,Nubwidth,Nubheight), o), 		display->black, clipr, addpt(o, Pt(Nubwidth-1, 0)));	draw(m, rectaddpt(Rect(0, Nubheight-1, Nubwidth, Nubheight), o),		display->black, clipr, addpt(o, Pt(0, Nubheight-1)));	draw(m, rectaddpt(Rect(0, Nubheight/2, Nubwidth, Nubheight/2+1), o),		display->black, clipr, addpt(o, Pt(0, Nubheight/2)));	if(!t->expanded)		draw(m, rectaddpt(Rect(Nubwidth/2, 0, Nubwidth/2+1, Nubheight), o),			display->black, clipr, addpt(o, Pt(Nubwidth/2, 0)));}uintdrawnode(Tnode *t, Image *m, Image *clipr, Point o){	int i;	char *fs, *s;	uint dy;	Point oo;	if(t == nil)		return 0;	t->offset = o;	oo = Pt(o.x+Nubwidth+2, o.y);//	if(t->draw)//		dy = (*t->draw)(t, m, clipr, oo);//	else{		fs = nil;		if(t->str)			s = t->str;	//	else if(t->strfn)	//		fs = s = (*t->strfn)(t);		else			s = "???";		dy = drawtext(s, m, clipr, oo);		free(fs);//	}	if(t->expanded){		if(t->nkid == -1 && t->expand)			(*t->expand)(t);		oo = Pt(o.x+Nubwidth+(Linewidth-Nubwidth)/2, o.y+dy);		for(i=0; i<t->nkid; i++)			oo.y += drawnode(t->kid[i], m, clipr, oo);		dy = oo.y - o.y;	}	drawnub(m, clipr, o, t);	return dy;}voiddrawtree(Tree *t, Image *m, Rectangle r){	Point p;	draw(m, r, display->white, nil, ZP);	replclipr(t->clipr, 1, r);	p = addpt(t->offset, r.min);	drawnode(t->root, m, t->clipr, p);}Tnode*findnode(Tnode *t, Point p){	int i;	Tnode *tt;	if(ptinrect(p, rectaddpt(Rect(0,0,Nubwidth, Nubheight), t->offset)))		return t;	if(!t->expanded)		return nil;	for(i=0; i<t->nkid; i++)		if(tt = findnode(t->kid[i], p))			return tt;	return nil;}voidusage(void){	fprint(2, "usage: vtree /dev/sdC0/fossil\n");	exits("usage");}Tree t;voideresized(int new){	Rectangle r;	r = screen->r;	if(new && getwindow(display, Refnone) < 0)		fprint(2,"can't reattach to window");	drawtree(&t, screen, screen->r);}enum{	Left = 1<<0,	Middle = 1<<1,	Right = 1<<2,	MMenu = 2,};char *items[] = { "exit", 0 };enum { IExit, };Menu menu;voidmain(int argc, char **argv){	int n;	char *dir;	Event e;	Point op, p;	Tnode *tn;	Mouse m;	int Eready;	Atree *fs;	ARGBEGIN{	case 'a':		showinactive = 1;		break;	default:		usage();	}ARGEND	switch(argc){	default:		usage();	case 1:		dir = argv[0];		break;	}	fs = atreeinit(dir);	initdraw(0, "/lib/font/bit/lucidasans/unicode.8.font", "tree");	t.root = fs->root;	t.offset = ZP;	t.clipr = allocimage(display, Rect(0,0,1,1), GREY1, 1, DOpaque);	eresized(0);	flushimage(display, 1);	einit(Emouse);	menu.item = items;	menu.gen = 0;	menu.lasthit = 0;	if(fs->resizefd > 0){		Eready = 1<<3;		estart(Eready, fs->resizefd, 1);	}else		Eready = 0;	for(;;){		switch(n=eread(Emouse|Eready, &e)){		default:			if(Eready && n==Eready)				eresized(0);			break;		case Emouse:			m = e.mouse;			switch(m.buttons){			case Left:				op = t.offset;				p = m.xy;				do {					t.offset = addpt(t.offset, subpt(m.xy, p));					p = m.xy;					eresized(0);					m = emouse();				}while(m.buttons == Left);				if(m.buttons){					t.offset = op;					eresized(0);				}				break;			case Middle:				n = emenuhit(MMenu, &m, &menu);				if(n == -1)					break;				switch(n){				case IExit:					exits(nil);				}				break;			case Right:				do					m = emouse();				while(m.buttons == Right);				if(m.buttons)					break;				tn = findnode(t.root, m.xy);				if(tn){					tn->expanded = !tn->expanded;					eresized(0);				}				break;			}		}	}}

⌨️ 快捷键说明

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