📄 view.c
字号:
#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 + -