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

📄 view.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "stdinc.h"#include "dat.h"#include "fns.h"#include <draw.h>#include <event.h>/* --- tree.h */typedef struct Tree Tree;typedef struct Tnode Tnode;struct Tree{	Tnode *root;	Point offset;	Image *clipr;};struct Tnode{	Point offset;	char *str;//	char *(*strfn)(Tnode*);//	uint (*draw)(Tnode*, Image*, Image*, Point);	void (*expand)(Tnode*);	void (*collapse)(Tnode*);	uint expanded;	Tnode **kid;	int nkid;	void *aux;};typedef struct Atree Atree;struct Atree{	int resizefd;	Tnode *root;};Atree *atreeinit(char*);/* --- visfossil.c */Tnode *initxheader(void);Tnode *initxcache(char *name);Tnode *initxsuper(void);Tnode *initxlocalroot(char *name, u32int addr);Tnode *initxentry(Entry);Tnode *initxsource(Entry, int);Tnode *initxentryblock(Block*, Entry*);Tnode *initxdatablock(Block*, uint);Tnode *initxroot(char *name, uchar[VtScoreSize]);int fd;Header h;Super super;VtSession *z;VtRoot vac;int showinactive;/* * dumbed down versions of fossil routines */char*bsStr(int state){	static char s[100];	if(state == BsFree)		return "Free";	if(state == BsBad)		return "Bad";	sprint(s, "%x", state);	if(!(state&BsAlloc))		strcat(s, ",Free");	/* should not happen */	if(state&BsVenti)		strcat(s, ",Venti");	if(state&BsClosed)		strcat(s, ",Closed");	return s;}char *bttab[] = {	"BtData",	"BtData+1",	"BtData+2",	"BtData+3",	"BtData+4",	"BtData+5",	"BtData+6",	"BtData+7",	"BtDir",	"BtDir+1",	"BtDir+2",	"BtDir+3",	"BtDir+4",	"BtDir+5",	"BtDir+6",	"BtDir+7",};char*btStr(int type){	if(type < nelem(bttab))		return bttab[type];	return "unknown";}#pragma varargck argpos stringnode 1Block*allocBlock(void){	Block *b;	b = mallocz(sizeof(Block)+h.blockSize, 1);	b->data = (void*)&b[1];	return b;}voidblockPut(Block *b){	free(b);}static u32intpartStart(int part){	switch(part){	default:		assert(0);	case PartSuper:		return h.super;	case PartLabel:		return h.label;	case PartData:		return h.data;	}}static u32intpartEnd(int part){	switch(part){	default:		assert(0);	case PartSuper:		return h.super+1;	case PartLabel:		return h.data;	case PartData:		return h.end;	}}Block*readBlock(int part, u32int addr){	u32int start, end;	u64int offset;	int n, nn;	Block *b;	uchar *buf;	start = partStart(part);	end = partEnd(part);	if(addr >= end-start){		werrstr("bad addr 0x%.8ux; wanted 0x%.8ux - 0x%.8ux", addr, start, end);		return nil;	}	b = allocBlock();	b->addr = addr;	buf = b->data;	offset = ((u64int)(addr+start))*h.blockSize;	n = h.blockSize;	while(n > 0){		nn = pread(fd, buf, n, offset);		if(nn < 0){			blockPut(b);			return nil;		}		if(nn == 0){			werrstr("short read");			blockPut(b);			return nil;		}		n -= nn;		offset += nn;		buf += nn;	}	return b;}int vtType[BtMax] = {	VtDataType,		/* BtData | 0  */	VtPointerType0,		/* BtData | 1  */	VtPointerType1,		/* BtData | 2  */	VtPointerType2,		/* BtData | 3  */	VtPointerType3,		/* BtData | 4  */	VtPointerType4,		/* BtData | 5  */	VtPointerType5,		/* BtData | 6  */	VtPointerType6,		/* BtData | 7  */	VtDirType,		/* BtDir | 0  */	VtPointerType0,		/* BtDir | 1  */	VtPointerType1,		/* BtDir | 2  */	VtPointerType2,		/* BtDir | 3  */	VtPointerType3,		/* BtDir | 4  */	VtPointerType4,		/* BtDir | 5  */	VtPointerType5,		/* BtDir | 6  */	VtPointerType6,		/* BtDir | 7  */};Block*ventiBlock(uchar score[VtScoreSize], uint type){	int n;	Block *b;	b = allocBlock();	memmove(b->score, score, VtScoreSize);	b->addr = NilBlock;	n = vtRead(z, b->score, vtType[type], b->data, h.blockSize);	if(n < 0){		fprint(2, "vtRead returns %d: %R\n", n);		blockPut(b);		return nil;	}	vtZeroExtend(vtType[type], b->data, n, h.blockSize);	b->l.type = type;	b->l.state = 0;	b->l.tag = 0;	b->l.epoch = 0;	return b;}Block*dataBlock(uchar score[VtScoreSize], uint type, uint tag){	Block *b, *bl;	int lpb;	Label l;	u32int addr;	addr = globalToLocal(score);	if(addr == NilBlock)		return ventiBlock(score, type);	lpb = h.blockSize/LabelSize;	bl = readBlock(PartLabel, addr/lpb);	if(bl == nil)		return nil;	if(!labelUnpack(&l, bl->data, addr%lpb)){		werrstr("%R");		blockPut(bl);		return nil;	}	blockPut(bl);	if(l.type != type){		werrstr("type mismatch; got %d (%s) wanted %d (%s)",			l.type, btStr(l.type), type, btStr(type));		return nil;	}	if(tag && l.tag != tag){		werrstr("tag mismatch; got 0x%.8ux wanted 0x%.8ux",			l.tag, tag);		return nil;	}	b = readBlock(PartData, addr);	if(b == nil)		return nil;	b->l = l;	return b;}Entry*copyEntry(Entry e){	Entry *p;	p = mallocz(sizeof *p, 1);	*p = e;	return p;}MetaBlock*copyMetaBlock(MetaBlock mb){	MetaBlock *p;	p = mallocz(sizeof mb, 1);	*p = mb;	return p;}/* * visualizer  */Tnode*stringnode(char *fmt, ...){	va_list arg;	Tnode *t;	t = mallocz(sizeof(Tnode), 1);	va_start(arg, fmt);	t->str = vsmprint(fmt, arg);	va_end(arg);	t->nkid = -1;	return t;}voidxcacheexpand(Tnode *t){	if(t->nkid >= 0)		return;	t->nkid = 1;	t->kid = mallocz(sizeof(t->kid[0])*t->nkid, 1);	t->kid[0] = initxheader();}Tnode*initxcache(char *name){	Tnode *t;	if((fd = open(name, OREAD)) < 0)		sysfatal("cannot open %s: %r", name);	t = stringnode("%s", name);	t->expand = xcacheexpand;	return t;}voidxheaderexpand(Tnode *t){	if(t->nkid >= 0)		return;	t->nkid = 1;	t->kid = mallocz(sizeof(t->kid[0])*t->nkid, 1);	t->kid[0] = initxsuper();	//t->kid[1] = initxlabel(h.label);	//t->kid[2] = initxdata(h.data);}Tnode*initxheader(void){	u8int buf[HeaderSize];	Tnode *t;	if(pread(fd, buf, HeaderSize, HeaderOffset) < HeaderSize)		return stringnode("error reading header: %r");	if(!headerUnpack(&h, buf))		return stringnode("error unpacking header: %R");	t = stringnode("header "		"version=%#ux (%d) "		"blockSize=%#ux (%d) "		"super=%#lux (%ld) "		"label=%#lux (%ld) "		"data=%#lux (%ld) "		"end=%#lux (%ld)",		h.version, h.version, h.blockSize, h.blockSize,		h.super, h.super,		h.label, h.label, h.data, h.data, h.end, h.end);	t->expand = xheaderexpand;	return t;}voidxsuperexpand(Tnode *t){	if(t->nkid >= 0)		return;	t->nkid = 1;	t->kid = mallocz(sizeof(t->kid[0])*t->nkid, 1);	t->kid[0] = initxlocalroot("active", super.active);//	t->kid[1] = initxlocalroot("next", super.next);//	t->kid[2] = initxlocalroot("current", super.current);}Tnode*initxsuper(void){	Block *b;	Tnode *t;	b = readBlock(PartSuper, 0);	if(b == nil)		return stringnode("reading super: %r");	if(!superUnpack(&super, b->data)){		blockPut(b);		return stringnode("unpacking super: %R");	}	blockPut(b);	t = stringnode("super "		"version=%#ux "		"epoch=[%#ux,%#ux) "		"qid=%#llux "		"active=%#x "		"next=%#x "		"current=%#x "		"last=%V "		"name=%s",		super.version, super.epochLow, super.epochHigh,		super.qid, super.active, super.next, super.current,		super.last, super.name);	t->expand = xsuperexpand;	return t;}voidxvacrootexpand(Tnode *t){	if(t->nkid >= 0)		return;	t->nkid = 1;	t->kid = mallocz(sizeof(t->kid[0])*t->nkid, 1);	t->kid[0] = initxroot("root", vac.score);}Tnode*initxvacroot(uchar score[VtScoreSize]){	Tnode *t;	uchar buf[VtRootSize];	int n;	if((n = vtRead(z, score, VtRootType, buf, VtRootSize)) < 0)		return stringnode("reading root %V: %R", score);	if(!vtRootUnpack(&vac, buf))		return stringnode("unpack %d-byte root: %R", n);	h.blockSize = vac.blockSize;	t = stringnode("vac version=%#ux name=%s type=%s blockSize=%ud score=%V prev=%V",		vac.version, vac.name, vac.type, vac.blockSize, vac.score, vac.prev);	t->expand = xvacrootexpand;	return t;}Tnode*initxlabel(Label l){	return stringnode("label type=%s state=%s epoch=%#ux tag=%#ux",		btStr(l.type), bsStr(l.state), l.epoch, l.tag);}typedef struct Xblock Xblock;struct Xblock{	Tnode;	Block *b;	int (*gen)(void*, Block*, int, Tnode**);	void *arg;	int printlabel;};voidxblockexpand(Tnode *tt){	int i, j;	enum { Q = 32 };	Xblock *t = (Xblock*)tt;	Tnode *nn;	if(t->nkid >= 0)		return;	j = 0;	if(t->printlabel){		t->kid = mallocz(Q*sizeof(t->kid[0]), 1);		t->kid[0] = initxlabel(t->b->l);		j = 1;	}	for(i=0;; i++){		switch((*t->gen)(t->arg, t->b, i, &nn)){		case -1:			t->nkid = j;			return;		case 0:			break;		case 1:			if(j%Q == 0)				t->kid = realloc(t->kid, (j+Q)*sizeof(t->kid[0]));			t->kid[j++] = nn;			break;		}	}}intnilgen(void*, Block*, int, Tnode**){	return -1;}Tnode*initxblock(Block *b, char *s, int (*gen)(void*, Block*, int, Tnode**), void *arg){	Xblock *t;	if(gen == nil)		gen = nilgen;	t = mallocz(sizeof(Xblock), 1);	t->b = b;	t->gen = gen;	t->arg = arg;	if(b->addr == NilBlock)		t->str = smprint("Block %V: %s", b->score, s);	else		t->str = smprint("Block %#ux: %s", b->addr, s);	t->printlabel = 1;	t->nkid = -1;	t->expand = xblockexpand;	return t;}intxentrygen(void *v, Block *b, int o, Tnode **tp){	Entry e;	Entry *ed;	ed = v;	if(o >= ed->dsize/VtEntrySize)		return -1;	entryUnpack(&e, b->data, o);	if(!showinactive && !(e.flags & VtEntryActive))		return 0;	*tp = initxentry(e);	return 1;}Tnode*initxentryblock(Block *b, Entry *ed){	return initxblock(b, "entry", xentrygen, ed);}typedef struct Xentry Xentry;struct Xentry {	Tnode;	Entry e;};voidxentryexpand(Tnode *tt)

⌨️ 快捷键说明

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