1 6f4d00ee 2013-09-23 0intro #include "stdinc.h"
2 6f4d00ee 2013-09-23 0intro #include "dat.h"
3 6f4d00ee 2013-09-23 0intro #include "fns.h"
4 6f4d00ee 2013-09-23 0intro #include <draw.h>
5 6f4d00ee 2013-09-23 0intro #include <event.h>
7 6f4d00ee 2013-09-23 0intro /* --- tree.h */
8 6f4d00ee 2013-09-23 0intro typedef struct Tree Tree;
9 6f4d00ee 2013-09-23 0intro typedef struct Tnode Tnode;
11 6f4d00ee 2013-09-23 0intro struct Tree
13 6f4d00ee 2013-09-23 0intro Tnode *root;
14 6f4d00ee 2013-09-23 0intro Point offset;
15 6f4d00ee 2013-09-23 0intro Image *clipr;
18 6f4d00ee 2013-09-23 0intro struct Tnode
20 6f4d00ee 2013-09-23 0intro Point offset;
22 6f4d00ee 2013-09-23 0intro char *str;
23 6f4d00ee 2013-09-23 0intro // char *(*strfn)(Tnode*);
24 6f4d00ee 2013-09-23 0intro // uint (*draw)(Tnode*, Image*, Image*, Point);
25 6f4d00ee 2013-09-23 0intro void (*expand)(Tnode*);
26 6f4d00ee 2013-09-23 0intro void (*collapse)(Tnode*);
28 6f4d00ee 2013-09-23 0intro uint expanded;
29 6f4d00ee 2013-09-23 0intro Tnode **kid;
31 6f4d00ee 2013-09-23 0intro void *aux;
34 6f4d00ee 2013-09-23 0intro typedef struct Atree Atree;
35 6f4d00ee 2013-09-23 0intro struct Atree
37 6f4d00ee 2013-09-23 0intro int resizefd;
38 6f4d00ee 2013-09-23 0intro Tnode *root;
41 6f4d00ee 2013-09-23 0intro Atree *atreeinit(char*);
43 6f4d00ee 2013-09-23 0intro /* --- visfossil.c */
44 6f4d00ee 2013-09-23 0intro Tnode *initxheader(void);
45 6f4d00ee 2013-09-23 0intro Tnode *initxcache(char *name);
46 6f4d00ee 2013-09-23 0intro Tnode *initxsuper(void);
47 6f4d00ee 2013-09-23 0intro Tnode *initxlocalroot(char *name, u32int addr);
48 6f4d00ee 2013-09-23 0intro Tnode *initxentry(Entry);
49 6f4d00ee 2013-09-23 0intro Tnode *initxsource(Entry, int);
50 6f4d00ee 2013-09-23 0intro Tnode *initxentryblock(Block*, Entry*);
51 6f4d00ee 2013-09-23 0intro Tnode *initxdatablock(Block*, uint);
52 6f4d00ee 2013-09-23 0intro Tnode *initxroot(char *name, uchar[VtScoreSize]);
55 4b576658 2013-09-23 0intro int mainstacksize = STACK;
57 6f4d00ee 2013-09-23 0intro Super super;
58 4b576658 2013-09-23 0intro VtConn *z;
59 6f4d00ee 2013-09-23 0intro VtRoot vac;
60 6f4d00ee 2013-09-23 0intro int showinactive;
63 6f4d00ee 2013-09-23 0intro * dumbed down versions of fossil routines
66 6f4d00ee 2013-09-23 0intro bsStr(int state)
68 6f4d00ee 2013-09-23 0intro static char s[100];
70 6f4d00ee 2013-09-23 0intro if(state == BsFree)
71 6f4d00ee 2013-09-23 0intro return "Free";
72 6f4d00ee 2013-09-23 0intro if(state == BsBad)
73 6f4d00ee 2013-09-23 0intro return "Bad";
75 6f4d00ee 2013-09-23 0intro sprint(s, "%x", state);
76 6f4d00ee 2013-09-23 0intro if(!(state&BsAlloc))
77 6f4d00ee 2013-09-23 0intro strcat(s, ",Free"); /* should not happen */
78 6f4d00ee 2013-09-23 0intro if(state&BsVenti)
79 6f4d00ee 2013-09-23 0intro strcat(s, ",Venti");
80 6f4d00ee 2013-09-23 0intro if(state&BsClosed)
81 6f4d00ee 2013-09-23 0intro strcat(s, ",Closed");
85 6f4d00ee 2013-09-23 0intro char *bttab[] = {
87 6f4d00ee 2013-09-23 0intro "BtData+1",
88 6f4d00ee 2013-09-23 0intro "BtData+2",
89 6f4d00ee 2013-09-23 0intro "BtData+3",
90 6f4d00ee 2013-09-23 0intro "BtData+4",
91 6f4d00ee 2013-09-23 0intro "BtData+5",
92 6f4d00ee 2013-09-23 0intro "BtData+6",
93 6f4d00ee 2013-09-23 0intro "BtData+7",
95 6f4d00ee 2013-09-23 0intro "BtDir+1",
96 6f4d00ee 2013-09-23 0intro "BtDir+2",
97 6f4d00ee 2013-09-23 0intro "BtDir+3",
98 6f4d00ee 2013-09-23 0intro "BtDir+4",
99 6f4d00ee 2013-09-23 0intro "BtDir+5",
100 6f4d00ee 2013-09-23 0intro "BtDir+6",
101 6f4d00ee 2013-09-23 0intro "BtDir+7",
105 6f4d00ee 2013-09-23 0intro btStr(int type)
107 6f4d00ee 2013-09-23 0intro if(type < nelem(bttab))
108 6f4d00ee 2013-09-23 0intro return bttab[type];
109 6f4d00ee 2013-09-23 0intro return "unknown";
113 6f4d00ee 2013-09-23 0intro allocBlock(void)
115 6f4d00ee 2013-09-23 0intro Block *b;
117 6f4d00ee 2013-09-23 0intro b = mallocz(sizeof(Block)+h.blockSize, 1);
118 6f4d00ee 2013-09-23 0intro b->data = (void*)&b[1];
119 6f4d00ee 2013-09-23 0intro return b;
123 6f4d00ee 2013-09-23 0intro blockPut(Block *b)
128 6f4d00ee 2013-09-23 0intro static u32int
129 6f4d00ee 2013-09-23 0intro partStart(int part)
131 6f4d00ee 2013-09-23 0intro switch(part){
133 6f4d00ee 2013-09-23 0intro assert(0);
134 6f4d00ee 2013-09-23 0intro case PartSuper:
135 6f4d00ee 2013-09-23 0intro return h.super;
136 6f4d00ee 2013-09-23 0intro case PartLabel:
137 6f4d00ee 2013-09-23 0intro return h.label;
138 6f4d00ee 2013-09-23 0intro case PartData:
139 6f4d00ee 2013-09-23 0intro return h.data;
144 6f4d00ee 2013-09-23 0intro static u32int
145 6f4d00ee 2013-09-23 0intro partEnd(int part)
147 6f4d00ee 2013-09-23 0intro switch(part){
149 6f4d00ee 2013-09-23 0intro assert(0);
150 6f4d00ee 2013-09-23 0intro case PartSuper:
151 6f4d00ee 2013-09-23 0intro return h.super+1;
152 6f4d00ee 2013-09-23 0intro case PartLabel:
153 6f4d00ee 2013-09-23 0intro return h.data;
154 6f4d00ee 2013-09-23 0intro case PartData:
155 6f4d00ee 2013-09-23 0intro return h.end;
160 6f4d00ee 2013-09-23 0intro readBlock(int part, u32int addr)
162 6f4d00ee 2013-09-23 0intro u32int start, end;
163 6f4d00ee 2013-09-23 0intro u64int offset;
164 6f4d00ee 2013-09-23 0intro int n, nn;
165 6f4d00ee 2013-09-23 0intro Block *b;
166 6f4d00ee 2013-09-23 0intro uchar *buf;
168 6f4d00ee 2013-09-23 0intro start = partStart(part);
169 6f4d00ee 2013-09-23 0intro end = partEnd(part);
170 6f4d00ee 2013-09-23 0intro if(addr >= end-start){
171 6f4d00ee 2013-09-23 0intro werrstr("bad addr 0x%.8ux; wanted 0x%.8ux - 0x%.8ux", addr, start, end);
172 6f4d00ee 2013-09-23 0intro return nil;
175 6f4d00ee 2013-09-23 0intro b = allocBlock();
176 6f4d00ee 2013-09-23 0intro b->addr = addr;
177 6f4d00ee 2013-09-23 0intro buf = b->data;
178 6f4d00ee 2013-09-23 0intro offset = ((u64int)(addr+start))*h.blockSize;
179 6f4d00ee 2013-09-23 0intro n = h.blockSize;
180 6f4d00ee 2013-09-23 0intro while(n > 0){
181 6f4d00ee 2013-09-23 0intro nn = pread(fd, buf, n, offset);
182 6f4d00ee 2013-09-23 0intro if(nn < 0){
183 6f4d00ee 2013-09-23 0intro blockPut(b);
184 6f4d00ee 2013-09-23 0intro return nil;
186 6f4d00ee 2013-09-23 0intro if(nn == 0){
187 6f4d00ee 2013-09-23 0intro werrstr("short read");
188 6f4d00ee 2013-09-23 0intro blockPut(b);
189 6f4d00ee 2013-09-23 0intro return nil;
192 6f4d00ee 2013-09-23 0intro offset += nn;
193 6f4d00ee 2013-09-23 0intro buf += nn;
195 6f4d00ee 2013-09-23 0intro return b;
198 6f4d00ee 2013-09-23 0intro int vtType[BtMax] = {
199 6f4d00ee 2013-09-23 0intro VtDataType, /* BtData | 0 */
200 4b576658 2013-09-23 0intro VtDataType+1, /* BtData | 1 */
201 4b576658 2013-09-23 0intro VtDataType+2, /* BtData | 2 */
202 4b576658 2013-09-23 0intro VtDataType+3, /* BtData | 3 */
203 4b576658 2013-09-23 0intro VtDataType+4, /* BtData | 4 */
204 4b576658 2013-09-23 0intro VtDataType+5, /* BtData | 5 */
205 4b576658 2013-09-23 0intro VtDataType+6, /* BtData | 6 */
206 4b576658 2013-09-23 0intro VtDataType+7, /* BtData | 7 */
207 6f4d00ee 2013-09-23 0intro VtDirType, /* BtDir | 0 */
208 4b576658 2013-09-23 0intro VtDirType+1, /* BtDir | 1 */
209 4b576658 2013-09-23 0intro VtDirType+2, /* BtDir | 2 */
210 4b576658 2013-09-23 0intro VtDirType+3, /* BtDir | 3 */
211 4b576658 2013-09-23 0intro VtDirType+4, /* BtDir | 4 */
212 4b576658 2013-09-23 0intro VtDirType+5, /* BtDir | 5 */
213 4b576658 2013-09-23 0intro VtDirType+6, /* BtDir | 6 */
214 4b576658 2013-09-23 0intro VtDirType+7, /* BtDir | 7 */
218 6f4d00ee 2013-09-23 0intro ventiBlock(uchar score[VtScoreSize], uint type)
221 6f4d00ee 2013-09-23 0intro Block *b;
223 6f4d00ee 2013-09-23 0intro b = allocBlock();
224 6f4d00ee 2013-09-23 0intro memmove(b->score, score, VtScoreSize);
225 6f4d00ee 2013-09-23 0intro b->addr = NilBlock;
227 4b576658 2013-09-23 0intro n = vtread(z, b->score, vtType[type], b->data, h.blockSize);
228 6f4d00ee 2013-09-23 0intro if(n < 0){
229 4b576658 2013-09-23 0intro fprint(2, "vtread returns %d: %r\n", n);
230 6f4d00ee 2013-09-23 0intro blockPut(b);
231 6f4d00ee 2013-09-23 0intro return nil;
233 4b576658 2013-09-23 0intro vtzeroextend(vtType[type], b->data, n, h.blockSize);
234 6f4d00ee 2013-09-23 0intro b->l.type = type;
235 6f4d00ee 2013-09-23 0intro b->l.state = 0;
236 6f4d00ee 2013-09-23 0intro b->l.tag = 0;
237 6f4d00ee 2013-09-23 0intro b->l.epoch = 0;
238 6f4d00ee 2013-09-23 0intro return b;
242 6f4d00ee 2013-09-23 0intro dataBlock(uchar score[VtScoreSize], uint type, uint tag)
244 6f4d00ee 2013-09-23 0intro Block *b, *bl;
247 6f4d00ee 2013-09-23 0intro u32int addr;
249 6f4d00ee 2013-09-23 0intro addr = globalToLocal(score);
250 6f4d00ee 2013-09-23 0intro if(addr == NilBlock)
251 6f4d00ee 2013-09-23 0intro return ventiBlock(score, type);
253 6f4d00ee 2013-09-23 0intro lpb = h.blockSize/LabelSize;
254 6f4d00ee 2013-09-23 0intro bl = readBlock(PartLabel, addr/lpb);
255 6f4d00ee 2013-09-23 0intro if(bl == nil)
256 6f4d00ee 2013-09-23 0intro return nil;
257 6f4d00ee 2013-09-23 0intro if(!labelUnpack(&l, bl->data, addr%lpb)){
258 4b576658 2013-09-23 0intro werrstr("%r");
259 6f4d00ee 2013-09-23 0intro blockPut(bl);
260 6f4d00ee 2013-09-23 0intro return nil;
262 6f4d00ee 2013-09-23 0intro blockPut(bl);
263 6f4d00ee 2013-09-23 0intro if(l.type != type){
264 6f4d00ee 2013-09-23 0intro werrstr("type mismatch; got %d (%s) wanted %d (%s)",
265 6f4d00ee 2013-09-23 0intro l.type, btStr(l.type), type, btStr(type));
266 6f4d00ee 2013-09-23 0intro return nil;
268 6f4d00ee 2013-09-23 0intro if(tag && l.tag != tag){
269 6f4d00ee 2013-09-23 0intro werrstr("tag mismatch; got 0x%.8ux wanted 0x%.8ux",
270 6f4d00ee 2013-09-23 0intro l.tag, tag);
271 6f4d00ee 2013-09-23 0intro return nil;
273 6f4d00ee 2013-09-23 0intro b = readBlock(PartData, addr);
274 6f4d00ee 2013-09-23 0intro if(b == nil)
275 6f4d00ee 2013-09-23 0intro return nil;
276 6f4d00ee 2013-09-23 0intro b->l = l;
277 6f4d00ee 2013-09-23 0intro return b;
281 6f4d00ee 2013-09-23 0intro copyEntry(Entry e)
283 6f4d00ee 2013-09-23 0intro Entry *p;
285 6f4d00ee 2013-09-23 0intro p = mallocz(sizeof *p, 1);
287 6f4d00ee 2013-09-23 0intro return p;
290 6f4d00ee 2013-09-23 0intro MetaBlock*
291 6f4d00ee 2013-09-23 0intro copyMetaBlock(MetaBlock mb)
293 6f4d00ee 2013-09-23 0intro MetaBlock *p;
295 6f4d00ee 2013-09-23 0intro p = mallocz(sizeof mb, 1);
297 6f4d00ee 2013-09-23 0intro return p;
301 fa325e9b 2020-01-10 cross * visualizer
304 6f4d00ee 2013-09-23 0intro #pragma varargck argpos stringnode 1
307 6f4d00ee 2013-09-23 0intro stringnode(char *fmt, ...)
309 6f4d00ee 2013-09-23 0intro va_list arg;
310 6f4d00ee 2013-09-23 0intro Tnode *t;
312 6f4d00ee 2013-09-23 0intro t = mallocz(sizeof(Tnode), 1);
313 6f4d00ee 2013-09-23 0intro va_start(arg, fmt);
314 6f4d00ee 2013-09-23 0intro t->str = vsmprint(fmt, arg);
315 6f4d00ee 2013-09-23 0intro va_end(arg);
316 6f4d00ee 2013-09-23 0intro t->nkid = -1;
317 6f4d00ee 2013-09-23 0intro return t;
321 6f4d00ee 2013-09-23 0intro xcacheexpand(Tnode *t)
323 6f4d00ee 2013-09-23 0intro if(t->nkid >= 0)
326 6f4d00ee 2013-09-23 0intro t->nkid = 1;
327 6f4d00ee 2013-09-23 0intro t->kid = mallocz(sizeof(t->kid[0])*t->nkid, 1);
328 6f4d00ee 2013-09-23 0intro t->kid[0] = initxheader();
332 6f4d00ee 2013-09-23 0intro initxcache(char *name)
334 6f4d00ee 2013-09-23 0intro Tnode *t;
336 6f4d00ee 2013-09-23 0intro if((fd = open(name, OREAD)) < 0)
337 6f4d00ee 2013-09-23 0intro sysfatal("cannot open %s: %r", name);
339 6f4d00ee 2013-09-23 0intro t = stringnode("%s", name);
340 6f4d00ee 2013-09-23 0intro t->expand = xcacheexpand;
341 6f4d00ee 2013-09-23 0intro return t;
345 6f4d00ee 2013-09-23 0intro xheaderexpand(Tnode *t)
347 6f4d00ee 2013-09-23 0intro if(t->nkid >= 0)
350 6f4d00ee 2013-09-23 0intro t->nkid = 1;
351 6f4d00ee 2013-09-23 0intro t->kid = mallocz(sizeof(t->kid[0])*t->nkid, 1);
352 6f4d00ee 2013-09-23 0intro t->kid[0] = initxsuper();
353 6f4d00ee 2013-09-23 0intro //t->kid[1] = initxlabel(h.label);
354 6f4d00ee 2013-09-23 0intro //t->kid[2] = initxdata(h.data);
358 6f4d00ee 2013-09-23 0intro initxheader(void)
360 6f4d00ee 2013-09-23 0intro u8int buf[HeaderSize];
361 6f4d00ee 2013-09-23 0intro Tnode *t;
363 6f4d00ee 2013-09-23 0intro if(pread(fd, buf, HeaderSize, HeaderOffset) < HeaderSize)
364 6f4d00ee 2013-09-23 0intro return stringnode("error reading header: %r");
365 6f4d00ee 2013-09-23 0intro if(!headerUnpack(&h, buf))
366 4b576658 2013-09-23 0intro return stringnode("error unpacking header: %r");
368 6f4d00ee 2013-09-23 0intro t = stringnode("header "
369 6f4d00ee 2013-09-23 0intro "version=%#ux (%d) "
370 6f4d00ee 2013-09-23 0intro "blockSize=%#ux (%d) "
371 6f4d00ee 2013-09-23 0intro "super=%#lux (%ld) "
372 6f4d00ee 2013-09-23 0intro "label=%#lux (%ld) "
373 6f4d00ee 2013-09-23 0intro "data=%#lux (%ld) "
374 6f4d00ee 2013-09-23 0intro "end=%#lux (%ld)",
375 6f4d00ee 2013-09-23 0intro h.version, h.version, h.blockSize, h.blockSize,
376 6f4d00ee 2013-09-23 0intro h.super, h.super,
377 6f4d00ee 2013-09-23 0intro h.label, h.label, h.data, h.data, h.end, h.end);
378 6f4d00ee 2013-09-23 0intro t->expand = xheaderexpand;
379 6f4d00ee 2013-09-23 0intro return t;
383 6f4d00ee 2013-09-23 0intro xsuperexpand(Tnode *t)
385 6f4d00ee 2013-09-23 0intro if(t->nkid >= 0)
388 6f4d00ee 2013-09-23 0intro t->nkid = 1;
389 6f4d00ee 2013-09-23 0intro t->kid = mallocz(sizeof(t->kid[0])*t->nkid, 1);
390 6f4d00ee 2013-09-23 0intro t->kid[0] = initxlocalroot("active", super.active);
391 6f4d00ee 2013-09-23 0intro // t->kid[1] = initxlocalroot("next", super.next);
392 6f4d00ee 2013-09-23 0intro // t->kid[2] = initxlocalroot("current", super.current);
396 6f4d00ee 2013-09-23 0intro initxsuper(void)
398 6f4d00ee 2013-09-23 0intro Block *b;
399 6f4d00ee 2013-09-23 0intro Tnode *t;
401 6f4d00ee 2013-09-23 0intro b = readBlock(PartSuper, 0);
402 6f4d00ee 2013-09-23 0intro if(b == nil)
403 6f4d00ee 2013-09-23 0intro return stringnode("reading super: %r");
404 6f4d00ee 2013-09-23 0intro if(!superUnpack(&super, b->data)){
405 6f4d00ee 2013-09-23 0intro blockPut(b);
406 4b576658 2013-09-23 0intro return stringnode("unpacking super: %r");
408 6f4d00ee 2013-09-23 0intro blockPut(b);
409 6f4d00ee 2013-09-23 0intro t = stringnode("super "
410 6f4d00ee 2013-09-23 0intro "version=%#ux "
411 6f4d00ee 2013-09-23 0intro "epoch=[%#ux,%#ux) "
412 6f4d00ee 2013-09-23 0intro "qid=%#llux "
413 6f4d00ee 2013-09-23 0intro "active=%#x "
414 6f4d00ee 2013-09-23 0intro "next=%#x "
415 6f4d00ee 2013-09-23 0intro "current=%#x "
416 6f4d00ee 2013-09-23 0intro "last=%V "
417 6f4d00ee 2013-09-23 0intro "name=%s",
418 6f4d00ee 2013-09-23 0intro super.version, super.epochLow, super.epochHigh,
419 6f4d00ee 2013-09-23 0intro super.qid, super.active, super.next, super.current,
420 6f4d00ee 2013-09-23 0intro super.last, super.name);
421 6f4d00ee 2013-09-23 0intro t->expand = xsuperexpand;
422 6f4d00ee 2013-09-23 0intro return t;
426 6f4d00ee 2013-09-23 0intro xvacrootexpand(Tnode *t)
428 6f4d00ee 2013-09-23 0intro if(t->nkid >= 0)
431 6f4d00ee 2013-09-23 0intro t->nkid = 1;
432 6f4d00ee 2013-09-23 0intro t->kid = mallocz(sizeof(t->kid[0])*t->nkid, 1);
433 6f4d00ee 2013-09-23 0intro t->kid[0] = initxroot("root", vac.score);
437 6f4d00ee 2013-09-23 0intro initxvacroot(uchar score[VtScoreSize])
439 6f4d00ee 2013-09-23 0intro Tnode *t;
440 6f4d00ee 2013-09-23 0intro uchar buf[VtRootSize];
443 4b576658 2013-09-23 0intro if((n = vtread(z, score, VtRootType, buf, VtRootSize)) < 0)
444 4b576658 2013-09-23 0intro return stringnode("reading root %V: %r", score);
446 4b576658 2013-09-23 0intro if(vtrootunpack(&vac, buf) < 0)
447 4b576658 2013-09-23 0intro return stringnode("unpack %d-byte root: %r", n);
449 4b576658 2013-09-23 0intro h.blockSize = vac.blocksize;
450 4b576658 2013-09-23 0intro t = stringnode("vac version=%#ux name=%s type=%s blocksize=%lud score=%V prev=%V",
451 4b576658 2013-09-23 0intro VtRootVersion, vac.name, vac.type, vac.blocksize, vac.score, vac.prev);
452 6f4d00ee 2013-09-23 0intro t->expand = xvacrootexpand;
453 6f4d00ee 2013-09-23 0intro return t;
457 6f4d00ee 2013-09-23 0intro initxlabel(Label l)
459 6f4d00ee 2013-09-23 0intro return stringnode("label type=%s state=%s epoch=%#ux tag=%#ux",
460 6f4d00ee 2013-09-23 0intro btStr(l.type), bsStr(l.state), l.epoch, l.tag);
463 6f4d00ee 2013-09-23 0intro typedef struct Xblock Xblock;
464 6f4d00ee 2013-09-23 0intro struct Xblock
467 6f4d00ee 2013-09-23 0intro Block *b;
468 6f4d00ee 2013-09-23 0intro int (*gen)(void*, Block*, int, Tnode**);
469 6f4d00ee 2013-09-23 0intro void *arg;
470 6f4d00ee 2013-09-23 0intro int printlabel;
474 6f4d00ee 2013-09-23 0intro xblockexpand(Tnode *tt)
476 6f4d00ee 2013-09-23 0intro int i, j;
477 6f4d00ee 2013-09-23 0intro enum { Q = 32 };
478 6f4d00ee 2013-09-23 0intro Xblock *t = (Xblock*)tt;
479 6f4d00ee 2013-09-23 0intro Tnode *nn;
481 24b8994d 2014-03-03 0intro if(t->t.nkid >= 0)
485 6f4d00ee 2013-09-23 0intro if(t->printlabel){
486 24b8994d 2014-03-03 0intro t->t.kid = mallocz(Q*sizeof(t->t.kid[0]), 1);
487 24b8994d 2014-03-03 0intro t->t.kid[0] = initxlabel(t->b->l);
491 6f4d00ee 2013-09-23 0intro for(i=0;; i++){
492 6f4d00ee 2013-09-23 0intro switch((*t->gen)(t->arg, t->b, i, &nn)){
494 24b8994d 2014-03-03 0intro t->t.nkid = j;
499 6f4d00ee 2013-09-23 0intro if(j%Q == 0)
500 24b8994d 2014-03-03 0intro t->t.kid = realloc(t->t.kid, (j+Q)*sizeof(t->t.kid[0]));
501 24b8994d 2014-03-03 0intro t->t.kid[j++] = nn;
508 b32de4ae 2013-09-26 0intro nilgen(void *v, Block *b, int o, Tnode **tp)
510 6f4d00ee 2013-09-23 0intro return -1;
514 b32de4ae 2013-09-26 0intro initxblock(Block *b, char *s, int (*gen)(void *v, Block *b, int o, Tnode **tp), void *arg)
516 6f4d00ee 2013-09-23 0intro Xblock *t;
518 6f4d00ee 2013-09-23 0intro if(gen == nil)
519 6f4d00ee 2013-09-23 0intro gen = nilgen;
520 6f4d00ee 2013-09-23 0intro t = mallocz(sizeof(Xblock), 1);
521 6f4d00ee 2013-09-23 0intro t->b = b;
522 6f4d00ee 2013-09-23 0intro t->gen = gen;
523 6f4d00ee 2013-09-23 0intro t->arg = arg;
524 6f4d00ee 2013-09-23 0intro if(b->addr == NilBlock)
525 24b8994d 2014-03-03 0intro t->t.str = smprint("Block %V: %s", b->score, s);
527 24b8994d 2014-03-03 0intro t->t.str = smprint("Block %#ux: %s", b->addr, s);
528 6f4d00ee 2013-09-23 0intro t->printlabel = 1;
529 24b8994d 2014-03-03 0intro t->t.nkid = -1;
530 24b8994d 2014-03-03 0intro t->t.expand = xblockexpand;
531 24b8994d 2014-03-03 0intro return (Tnode*)t;
535 6f4d00ee 2013-09-23 0intro xentrygen(void *v, Block *b, int o, Tnode **tp)
538 6f4d00ee 2013-09-23 0intro Entry *ed;
541 6f4d00ee 2013-09-23 0intro if(o >= ed->dsize/VtEntrySize)
542 6f4d00ee 2013-09-23 0intro return -1;
544 6f4d00ee 2013-09-23 0intro entryUnpack(&e, b->data, o);
545 6f4d00ee 2013-09-23 0intro if(!showinactive && !(e.flags & VtEntryActive))
546 6f4d00ee 2013-09-23 0intro return 0;
547 6f4d00ee 2013-09-23 0intro *tp = initxentry(e);
548 6f4d00ee 2013-09-23 0intro return 1;
552 6f4d00ee 2013-09-23 0intro initxentryblock(Block *b, Entry *ed)
554 6f4d00ee 2013-09-23 0intro return initxblock(b, "entry", xentrygen, ed);
557 6f4d00ee 2013-09-23 0intro typedef struct Xentry Xentry;
558 fa325e9b 2020-01-10 cross struct Xentry
565 6f4d00ee 2013-09-23 0intro xentryexpand(Tnode *tt)
567 6f4d00ee 2013-09-23 0intro Xentry *t = (Xentry*)tt;
569 24b8994d 2014-03-03 0intro if(t->t.nkid >= 0)
572 24b8994d 2014-03-03 0intro t->t.nkid = 1;
573 24b8994d 2014-03-03 0intro t->t.kid = mallocz(sizeof(t->t.kid[0])*t->t.nkid, 1);
574 24b8994d 2014-03-03 0intro t->t.kid[0] = initxsource(t->e, 1);
578 6f4d00ee 2013-09-23 0intro initxentry(Entry e)
580 6f4d00ee 2013-09-23 0intro Xentry *t;
582 6f4d00ee 2013-09-23 0intro t = mallocz(sizeof *t, 1);
583 24b8994d 2014-03-03 0intro t->t.nkid = -1;
584 24b8994d 2014-03-03 0intro t->t.str = smprint("Entry gen=%#ux psize=%d dsize=%d depth=%d flags=%#ux size=%lld score=%V",
585 6f4d00ee 2013-09-23 0intro e.gen, e.psize, e.dsize, e.depth, e.flags, e.size, e.score);
586 6f4d00ee 2013-09-23 0intro if(e.flags & VtEntryLocal)
587 24b8994d 2014-03-03 0intro t->t.str = smprint("%s archive=%d snap=%d tag=%#ux", t->t.str, e.archive, e.snap, e.tag);
588 24b8994d 2014-03-03 0intro t->t.expand = xentryexpand;
589 6f4d00ee 2013-09-23 0intro t->e = e;
590 24b8994d 2014-03-03 0intro return (Tnode*)t;
594 6f4d00ee 2013-09-23 0intro ptrgen(void *v, Block *b, int o, Tnode **tp)
596 6f4d00ee 2013-09-23 0intro Entry *ed;
600 6f4d00ee 2013-09-23 0intro if(o >= ed->psize/VtScoreSize)
601 6f4d00ee 2013-09-23 0intro return -1;
604 6f4d00ee 2013-09-23 0intro e.depth--;
605 6f4d00ee 2013-09-23 0intro memmove(e.score, b->data+o*VtScoreSize, VtScoreSize);
606 4b576658 2013-09-23 0intro if(memcmp(e.score, vtzeroscore, VtScoreSize) == 0)
607 6f4d00ee 2013-09-23 0intro return 0;
608 6f4d00ee 2013-09-23 0intro *tp = initxsource(e, 0);
609 6f4d00ee 2013-09-23 0intro return 1;
612 6f4d00ee 2013-09-23 0intro static int
613 6f4d00ee 2013-09-23 0intro etype(int flags, int depth)
617 4b576658 2013-09-23 0intro if(flags&_VtEntryDir)
618 6f4d00ee 2013-09-23 0intro t = BtDir;
620 6f4d00ee 2013-09-23 0intro t = BtData;
621 6f4d00ee 2013-09-23 0intro return t+depth;
625 6f4d00ee 2013-09-23 0intro initxsource(Entry e, int dowrap)
627 6f4d00ee 2013-09-23 0intro Block *b;
628 6f4d00ee 2013-09-23 0intro Tnode *t, *tt;
630 6f4d00ee 2013-09-23 0intro b = dataBlock(e.score, etype(e.flags, e.depth), e.tag);
631 6f4d00ee 2013-09-23 0intro if(b == nil)
632 6f4d00ee 2013-09-23 0intro return stringnode("dataBlock: %r");
634 6f4d00ee 2013-09-23 0intro if((e.flags & VtEntryActive) == 0)
635 6f4d00ee 2013-09-23 0intro return stringnode("inactive Entry");
637 6f4d00ee 2013-09-23 0intro if(e.depth == 0){
638 4b576658 2013-09-23 0intro if(e.flags & _VtEntryDir)
639 6f4d00ee 2013-09-23 0intro tt = initxentryblock(b, copyEntry(e));
641 6f4d00ee 2013-09-23 0intro tt = initxdatablock(b, e.dsize);
643 4b576658 2013-09-23 0intro tt = initxblock(b, smprint("%s+%d pointer", (e.flags & _VtEntryDir) ? "BtDir" : "BtData", e.depth),
644 6f4d00ee 2013-09-23 0intro ptrgen, copyEntry(e));
648 6f4d00ee 2013-09-23 0intro * wrap the contents of the Source in a Source node,
649 6f4d00ee 2013-09-23 0intro * just so it's closer to what you see in the code.
651 6f4d00ee 2013-09-23 0intro if(dowrap){
652 6f4d00ee 2013-09-23 0intro t = stringnode("Source");
653 6f4d00ee 2013-09-23 0intro t->nkid = 1;
654 6f4d00ee 2013-09-23 0intro t->kid = mallocz(sizeof(Tnode*)*1, 1);
655 6f4d00ee 2013-09-23 0intro t->kid[0] = tt;
658 6f4d00ee 2013-09-23 0intro return tt;
662 b32de4ae 2013-09-26 0intro xlocalrootgen(void *v, Block *b, int o, Tnode **tp)
666 6f4d00ee 2013-09-23 0intro if(o >= 1)
667 6f4d00ee 2013-09-23 0intro return -1;
668 6f4d00ee 2013-09-23 0intro entryUnpack(&e, b->data, o);
669 6f4d00ee 2013-09-23 0intro *tp = initxentry(e);
670 6f4d00ee 2013-09-23 0intro return 1;
674 6f4d00ee 2013-09-23 0intro initxlocalroot(char *name, u32int addr)
676 6f4d00ee 2013-09-23 0intro uchar score[VtScoreSize];
677 6f4d00ee 2013-09-23 0intro Block *b;
679 6f4d00ee 2013-09-23 0intro localToGlobal(addr, score);
680 6f4d00ee 2013-09-23 0intro b = dataBlock(score, BtDir, RootTag);
681 6f4d00ee 2013-09-23 0intro if(b == nil)
682 4b576658 2013-09-23 0intro return stringnode("read data block %#ux: %r", addr);
683 6f4d00ee 2013-09-23 0intro return initxblock(b, smprint("'%s' fs root", name), xlocalrootgen, nil);
687 b32de4ae 2013-09-26 0intro xvacrootgen(void *v, Block *b, int o, Tnode **tp)
691 6f4d00ee 2013-09-23 0intro if(o >= 3)
692 6f4d00ee 2013-09-23 0intro return -1;
693 6f4d00ee 2013-09-23 0intro entryUnpack(&e, b->data, o);
694 6f4d00ee 2013-09-23 0intro *tp = initxentry(e);
695 6f4d00ee 2013-09-23 0intro return 1;
699 6f4d00ee 2013-09-23 0intro initxroot(char *name, uchar score[VtScoreSize])
701 6f4d00ee 2013-09-23 0intro Block *b;
703 6f4d00ee 2013-09-23 0intro b = dataBlock(score, BtDir, RootTag);
704 6f4d00ee 2013-09-23 0intro if(b == nil)
705 4b576658 2013-09-23 0intro return stringnode("read data block %V: %r", score);
706 6f4d00ee 2013-09-23 0intro return initxblock(b, smprint("'%s' fs root", name), xvacrootgen, nil);
709 6f4d00ee 2013-09-23 0intro initxdirentry(MetaEntry *me)
711 6f4d00ee 2013-09-23 0intro DirEntry dir;
712 6f4d00ee 2013-09-23 0intro Tnode *t;
714 6f4d00ee 2013-09-23 0intro if(!deUnpack(&dir, me))
715 4b576658 2013-09-23 0intro return stringnode("deUnpack: %r");
717 6f4d00ee 2013-09-23 0intro 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);
718 6f4d00ee 2013-09-23 0intro t->nkid = 1;
719 6f4d00ee 2013-09-23 0intro t->kid = mallocz(sizeof(t->kid[0])*1, 1);
720 6f4d00ee 2013-09-23 0intro t->kid[0] = stringnode(
721 6f4d00ee 2013-09-23 0intro "qid=%#llux\n"
722 6f4d00ee 2013-09-23 0intro "uid=%s gid=%s mid=%s\n"
723 6f4d00ee 2013-09-23 0intro "mtime=%lud mcount=%lud ctime=%lud atime=%lud\n"
724 6f4d00ee 2013-09-23 0intro "mode=%luo\n"
725 6f4d00ee 2013-09-23 0intro "plan9 %d p9path %#llux p9version %lud\n"
726 6f4d00ee 2013-09-23 0intro "qidSpace %d offset %#llux max %#llux",
728 6f4d00ee 2013-09-23 0intro dir.uid, dir.gid, dir.mid,
729 6f4d00ee 2013-09-23 0intro dir.mtime, dir.mcount, dir.ctime, dir.atime,
730 6f4d00ee 2013-09-23 0intro dir.mode,
731 6f4d00ee 2013-09-23 0intro dir.plan9, dir.p9path, dir.p9version,
732 6f4d00ee 2013-09-23 0intro dir.qidSpace, dir.qidOffset, dir.qidMax);
733 6f4d00ee 2013-09-23 0intro return t;
737 b32de4ae 2013-09-26 0intro metaentrygen(void *v, Block *b, int o, Tnode **tp)
739 6f4d00ee 2013-09-23 0intro Tnode *t;
740 6f4d00ee 2013-09-23 0intro MetaBlock *mb;
741 6f4d00ee 2013-09-23 0intro MetaEntry me;
744 6f4d00ee 2013-09-23 0intro if(o >= mb->nindex)
745 6f4d00ee 2013-09-23 0intro return -1;
746 6f4d00ee 2013-09-23 0intro meUnpack(&me, mb, o);
748 6f4d00ee 2013-09-23 0intro t = stringnode("MetaEntry %d bytes", mb->size);
749 6f4d00ee 2013-09-23 0intro t->kid = mallocz(sizeof(t->kid[0])*1, 1);
750 6f4d00ee 2013-09-23 0intro t->kid[0] = initxdirentry(&me);
751 6f4d00ee 2013-09-23 0intro t->nkid = 1;
753 6f4d00ee 2013-09-23 0intro return 1;
757 6f4d00ee 2013-09-23 0intro metablockgen(void *v, Block *b, int o, Tnode **tp)
759 6f4d00ee 2013-09-23 0intro Xblock *t;
760 6f4d00ee 2013-09-23 0intro MetaBlock *mb;
762 6f4d00ee 2013-09-23 0intro if(o >= 1)
763 6f4d00ee 2013-09-23 0intro return -1;
765 6f4d00ee 2013-09-23 0intro /* hack: reuse initxblock as a generic iterator */
767 6f4d00ee 2013-09-23 0intro t = (Xblock*)initxblock(b, "", metaentrygen, mb);
768 24b8994d 2014-03-03 0intro t->t.str = smprint("MetaBlock %d/%d space used, %d add'l free %d/%d table used%s",
769 6f4d00ee 2013-09-23 0intro mb->size, mb->maxsize, mb->free, mb->nindex, mb->maxindex,
770 6f4d00ee 2013-09-23 0intro mb->botch ? " [BOTCH]" : "");
771 6f4d00ee 2013-09-23 0intro t->printlabel = 0;
772 24b8994d 2014-03-03 0intro *tp = (Tnode*)t;
773 6f4d00ee 2013-09-23 0intro return 1;
777 6f4d00ee 2013-09-23 0intro * attempt to guess at the type of data in the block.
778 6f4d00ee 2013-09-23 0intro * it could just be data from a file, but we're hoping it's MetaBlocks.
781 6f4d00ee 2013-09-23 0intro initxdatablock(Block *b, uint n)
783 6f4d00ee 2013-09-23 0intro MetaBlock mb;
785 6f4d00ee 2013-09-23 0intro if(n > h.blockSize)
786 6f4d00ee 2013-09-23 0intro n = h.blockSize;
788 6f4d00ee 2013-09-23 0intro if(mbUnpack(&mb, b->data, n))
789 6f4d00ee 2013-09-23 0intro return initxblock(b, "metadata", metablockgen, copyMetaBlock(mb));
791 6f4d00ee 2013-09-23 0intro return initxblock(b, "data", nil, nil);
795 6f4d00ee 2013-09-23 0intro parseScore(uchar *score, char *buf, int n)
797 6f4d00ee 2013-09-23 0intro int i, c;
799 6f4d00ee 2013-09-23 0intro memset(score, 0, VtScoreSize);
801 6f4d00ee 2013-09-23 0intro if(n < VtScoreSize*2)
802 6f4d00ee 2013-09-23 0intro return 0;
803 6f4d00ee 2013-09-23 0intro for(i=0; i<VtScoreSize*2; i++){
804 6f4d00ee 2013-09-23 0intro if(buf[i] >= '0' && buf[i] <= '9')
805 6f4d00ee 2013-09-23 0intro c = buf[i] - '0';
806 6f4d00ee 2013-09-23 0intro else if(buf[i] >= 'a' && buf[i] <= 'f')
807 6f4d00ee 2013-09-23 0intro c = buf[i] - 'a' + 10;
808 6f4d00ee 2013-09-23 0intro else if(buf[i] >= 'A' && buf[i] <= 'F')
809 6f4d00ee 2013-09-23 0intro c = buf[i] - 'A' + 10;
811 6f4d00ee 2013-09-23 0intro return 0;
814 6f4d00ee 2013-09-23 0intro if((i & 1) == 0)
817 6f4d00ee 2013-09-23 0intro score[i>>1] |= c;
819 6f4d00ee 2013-09-23 0intro return 1;
823 6f4d00ee 2013-09-23 0intro scoreFmt(Fmt *f)
825 6f4d00ee 2013-09-23 0intro uchar *v;
827 6f4d00ee 2013-09-23 0intro u32int addr;
829 6f4d00ee 2013-09-23 0intro v = va_arg(f->args, uchar*);
830 6f4d00ee 2013-09-23 0intro if(v == nil){
831 6f4d00ee 2013-09-23 0intro fmtprint(f, "*");
832 6f4d00ee 2013-09-23 0intro }else if((addr = globalToLocal(v)) != NilBlock)
833 6f4d00ee 2013-09-23 0intro fmtprint(f, "0x%.8ux", addr);
835 6f4d00ee 2013-09-23 0intro for(i = 0; i < VtScoreSize; i++)
836 6f4d00ee 2013-09-23 0intro fmtprint(f, "%2.2ux", v[i]);
839 6f4d00ee 2013-09-23 0intro return 0;
843 6f4d00ee 2013-09-23 0intro atreeinit(char *arg)
845 6f4d00ee 2013-09-23 0intro Atree *a;
846 6f4d00ee 2013-09-23 0intro uchar score[VtScoreSize];
848 6f4d00ee 2013-09-23 0intro fmtinstall('V', scoreFmt);
850 4b576658 2013-09-23 0intro z = vtdial(nil);
851 6f4d00ee 2013-09-23 0intro if(z == nil)
852 4b576658 2013-09-23 0intro fprint(2, "warning: cannot dial venti: %r\n");
853 4b576658 2013-09-23 0intro else if(vtconnect(z) < 0){
854 4b576658 2013-09-23 0intro fprint(2, "warning: cannot connect to venti: %r\n");
857 6f4d00ee 2013-09-23 0intro a = mallocz(sizeof(Atree), 1);
858 6f4d00ee 2013-09-23 0intro if(strncmp(arg, "vac:", 4) == 0){
859 6f4d00ee 2013-09-23 0intro if(!parseScore(score, arg+4, strlen(arg+4))){
860 6f4d00ee 2013-09-23 0intro fprint(2, "cannot parse score\n");
861 6f4d00ee 2013-09-23 0intro return nil;
863 6f4d00ee 2013-09-23 0intro a->root = initxvacroot(score);
865 6f4d00ee 2013-09-23 0intro a->root = initxcache(arg);
866 6f4d00ee 2013-09-23 0intro a->resizefd = -1;
867 6f4d00ee 2013-09-23 0intro return a;
870 6f4d00ee 2013-09-23 0intro /* --- tree.c */
873 6f4d00ee 2013-09-23 0intro Nubwidth = 11,
874 6f4d00ee 2013-09-23 0intro Nubheight = 11,
875 6f4d00ee 2013-09-23 0intro Linewidth = Nubwidth*2+4,
879 6f4d00ee 2013-09-23 0intro drawtext(char *s, Image *m, Image *clipr, Point o)
881 6f4d00ee 2013-09-23 0intro char *t, *nt, *e;
884 6f4d00ee 2013-09-23 0intro if(s == nil)
885 6f4d00ee 2013-09-23 0intro s = "???";
888 6f4d00ee 2013-09-23 0intro for(t=s; t&&*t; t=nt){
889 6f4d00ee 2013-09-23 0intro if(nt = strchr(t, '\n')){
893 6f4d00ee 2013-09-23 0intro e = t+strlen(t);
895 6f4d00ee 2013-09-23 0intro _string(m, Pt(o.x, o.y+dy), display->black, ZP, display->defaultfont,
896 6f4d00ee 2013-09-23 0intro t, nil, e-t, clipr->clipr, nil, ZP, SoverD);
897 6f4d00ee 2013-09-23 0intro dy += display->defaultfont->height;
899 6f4d00ee 2013-09-23 0intro return dy;
903 6f4d00ee 2013-09-23 0intro drawnub(Image *m, Image *clipr, Point o, Tnode *t)
905 6f4d00ee 2013-09-23 0intro clipr = nil;
907 6f4d00ee 2013-09-23 0intro if(t->nkid == 0)
909 6f4d00ee 2013-09-23 0intro if(t->nkid == -1 && t->expand == nil)
912 6f4d00ee 2013-09-23 0intro o.y += (display->defaultfont->height-Nubheight)/2;
913 6f4d00ee 2013-09-23 0intro draw(m, rectaddpt(Rect(0,0,1,Nubheight), o), display->black, clipr, ZP);
914 6f4d00ee 2013-09-23 0intro draw(m, rectaddpt(Rect(0,0,Nubwidth,1), o), display->black, clipr, o);
915 fa325e9b 2020-01-10 cross draw(m, rectaddpt(Rect(Nubwidth-1,0,Nubwidth,Nubheight), o),
916 6f4d00ee 2013-09-23 0intro display->black, clipr, addpt(o, Pt(Nubwidth-1, 0)));
917 6f4d00ee 2013-09-23 0intro draw(m, rectaddpt(Rect(0, Nubheight-1, Nubwidth, Nubheight), o),
918 6f4d00ee 2013-09-23 0intro display->black, clipr, addpt(o, Pt(0, Nubheight-1)));
920 6f4d00ee 2013-09-23 0intro draw(m, rectaddpt(Rect(0, Nubheight/2, Nubwidth, Nubheight/2+1), o),
921 6f4d00ee 2013-09-23 0intro display->black, clipr, addpt(o, Pt(0, Nubheight/2)));
922 6f4d00ee 2013-09-23 0intro if(!t->expanded)
923 6f4d00ee 2013-09-23 0intro draw(m, rectaddpt(Rect(Nubwidth/2, 0, Nubwidth/2+1, Nubheight), o),
924 6f4d00ee 2013-09-23 0intro display->black, clipr, addpt(o, Pt(Nubwidth/2, 0)));
929 6f4d00ee 2013-09-23 0intro drawnode(Tnode *t, Image *m, Image *clipr, Point o)
932 6f4d00ee 2013-09-23 0intro char *fs, *s;
934 6f4d00ee 2013-09-23 0intro Point oo;
936 6f4d00ee 2013-09-23 0intro if(t == nil)
937 6f4d00ee 2013-09-23 0intro return 0;
939 6f4d00ee 2013-09-23 0intro t->offset = o;
941 6f4d00ee 2013-09-23 0intro oo = Pt(o.x+Nubwidth+2, o.y);
942 6f4d00ee 2013-09-23 0intro // if(t->draw)
943 6f4d00ee 2013-09-23 0intro // dy = (*t->draw)(t, m, clipr, oo);
945 6f4d00ee 2013-09-23 0intro fs = nil;
946 6f4d00ee 2013-09-23 0intro if(t->str)
947 6f4d00ee 2013-09-23 0intro s = t->str;
948 6f4d00ee 2013-09-23 0intro // else if(t->strfn)
949 6f4d00ee 2013-09-23 0intro // fs = s = (*t->strfn)(t);
951 6f4d00ee 2013-09-23 0intro s = "???";
952 6f4d00ee 2013-09-23 0intro dy = drawtext(s, m, clipr, oo);
953 6f4d00ee 2013-09-23 0intro free(fs);
956 6f4d00ee 2013-09-23 0intro if(t->expanded){
957 6f4d00ee 2013-09-23 0intro if(t->nkid == -1 && t->expand)
958 6f4d00ee 2013-09-23 0intro (*t->expand)(t);
959 6f4d00ee 2013-09-23 0intro oo = Pt(o.x+Nubwidth+(Linewidth-Nubwidth)/2, o.y+dy);
960 6f4d00ee 2013-09-23 0intro for(i=0; i<t->nkid; i++)
961 6f4d00ee 2013-09-23 0intro oo.y += drawnode(t->kid[i], m, clipr, oo);
962 6f4d00ee 2013-09-23 0intro dy = oo.y - o.y;
964 6f4d00ee 2013-09-23 0intro drawnub(m, clipr, o, t);
965 6f4d00ee 2013-09-23 0intro return dy;
969 6f4d00ee 2013-09-23 0intro drawtree(Tree *t, Image *m, Rectangle r)
973 6f4d00ee 2013-09-23 0intro draw(m, r, display->white, nil, ZP);
975 6f4d00ee 2013-09-23 0intro replclipr(t->clipr, 1, r);
976 6f4d00ee 2013-09-23 0intro p = addpt(t->offset, r.min);
977 6f4d00ee 2013-09-23 0intro drawnode(t->root, m, t->clipr, p);
981 6f4d00ee 2013-09-23 0intro findnode(Tnode *t, Point p)
984 6f4d00ee 2013-09-23 0intro Tnode *tt;
986 6f4d00ee 2013-09-23 0intro if(ptinrect(p, rectaddpt(Rect(0,0,Nubwidth, Nubheight), t->offset)))
987 6f4d00ee 2013-09-23 0intro return t;
988 6f4d00ee 2013-09-23 0intro if(!t->expanded)
989 6f4d00ee 2013-09-23 0intro return nil;
990 6f4d00ee 2013-09-23 0intro for(i=0; i<t->nkid; i++)
991 6f4d00ee 2013-09-23 0intro if(tt = findnode(t->kid[i], p))
992 6f4d00ee 2013-09-23 0intro return tt;
993 6f4d00ee 2013-09-23 0intro return nil;
997 6f4d00ee 2013-09-23 0intro usage(void)
999 4b576658 2013-09-23 0intro fprint(2, "usage: fossil/view /dev/sdC0/fossil\n");
1000 4b576658 2013-09-23 0intro threadexitsall("usage");
1006 6f4d00ee 2013-09-23 0intro eresized(int new)
1008 6f4d00ee 2013-09-23 0intro if(new && getwindow(display, Refnone) < 0)
1009 6f4d00ee 2013-09-23 0intro fprint(2,"can't reattach to window");
1010 6f4d00ee 2013-09-23 0intro drawtree(&t, screen, screen->r);
1015 6f4d00ee 2013-09-23 0intro Left = 1<<0,
1016 6f4d00ee 2013-09-23 0intro Middle = 1<<1,
1017 6f4d00ee 2013-09-23 0intro Right = 1<<2,
1019 6f4d00ee 2013-09-23 0intro MMenu = 2,
1022 6f4d00ee 2013-09-23 0intro char *items[] = { "exit", 0 };
1023 6f4d00ee 2013-09-23 0intro enum { IExit, };
1025 6f4d00ee 2013-09-23 0intro Menu menu;
1028 4b576658 2013-09-23 0intro threadmain(int argc, char **argv)
1031 6f4d00ee 2013-09-23 0intro char *dir;
1032 6f4d00ee 2013-09-23 0intro Event e;
1033 6f4d00ee 2013-09-23 0intro Point op, p;
1034 6f4d00ee 2013-09-23 0intro Tnode *tn;
1035 6f4d00ee 2013-09-23 0intro Mouse m;
1036 6f4d00ee 2013-09-23 0intro int Eready;
1037 6f4d00ee 2013-09-23 0intro Atree *fs;
1039 6f4d00ee 2013-09-23 0intro ARGBEGIN{
1040 6f4d00ee 2013-09-23 0intro case 'a':
1041 6f4d00ee 2013-09-23 0intro showinactive = 1;
1043 6f4d00ee 2013-09-23 0intro default:
1044 6f4d00ee 2013-09-23 0intro usage();
1047 6f4d00ee 2013-09-23 0intro switch(argc){
1048 6f4d00ee 2013-09-23 0intro default:
1049 6f4d00ee 2013-09-23 0intro usage();
1051 6f4d00ee 2013-09-23 0intro dir = argv[0];
1055 6f4d00ee 2013-09-23 0intro fs = atreeinit(dir);
1056 24b8994d 2014-03-03 0intro #ifdef PLAN9PORT
1057 24b8994d 2014-03-03 0intro initdraw(0, "/lib/font/bit/lucsans/unicode.8.font", "tree");
1059 6f4d00ee 2013-09-23 0intro initdraw(0, "/lib/font/bit/lucidasans/unicode.8.font", "tree");
1061 6f4d00ee 2013-09-23 0intro t.root = fs->root;
1062 6f4d00ee 2013-09-23 0intro t.offset = ZP;
1063 6f4d00ee 2013-09-23 0intro t.clipr = allocimage(display, Rect(0,0,1,1), GREY1, 1, DOpaque);
1065 6f4d00ee 2013-09-23 0intro eresized(0);
1066 6f4d00ee 2013-09-23 0intro flushimage(display, 1);
1068 6f4d00ee 2013-09-23 0intro einit(Emouse);
1070 6f4d00ee 2013-09-23 0intro menu.item = items;
1071 6f4d00ee 2013-09-23 0intro menu.gen = 0;
1072 6f4d00ee 2013-09-23 0intro menu.lasthit = 0;
1073 6f4d00ee 2013-09-23 0intro if(fs->resizefd > 0){
1074 6f4d00ee 2013-09-23 0intro Eready = 1<<3;
1075 6f4d00ee 2013-09-23 0intro estart(Eready, fs->resizefd, 1);
1077 6f4d00ee 2013-09-23 0intro Eready = 0;
1079 6f4d00ee 2013-09-23 0intro for(;;){
1080 6f4d00ee 2013-09-23 0intro switch(n=eread(Emouse|Eready, &e)){
1081 6f4d00ee 2013-09-23 0intro default:
1082 6f4d00ee 2013-09-23 0intro if(Eready && n==Eready)
1083 6f4d00ee 2013-09-23 0intro eresized(0);
1085 6f4d00ee 2013-09-23 0intro case Emouse:
1086 6f4d00ee 2013-09-23 0intro m = e.mouse;
1087 6f4d00ee 2013-09-23 0intro switch(m.buttons){
1088 6f4d00ee 2013-09-23 0intro case Left:
1089 6f4d00ee 2013-09-23 0intro op = t.offset;
1090 6f4d00ee 2013-09-23 0intro p = m.xy;
1092 6f4d00ee 2013-09-23 0intro t.offset = addpt(t.offset, subpt(m.xy, p));
1093 6f4d00ee 2013-09-23 0intro p = m.xy;
1094 6f4d00ee 2013-09-23 0intro eresized(0);
1095 6f4d00ee 2013-09-23 0intro m = emouse();
1096 6f4d00ee 2013-09-23 0intro }while(m.buttons == Left);
1097 6f4d00ee 2013-09-23 0intro if(m.buttons){
1098 6f4d00ee 2013-09-23 0intro t.offset = op;
1099 6f4d00ee 2013-09-23 0intro eresized(0);
1102 6f4d00ee 2013-09-23 0intro case Middle:
1103 6f4d00ee 2013-09-23 0intro n = emenuhit(MMenu, &m, &menu);
1104 6f4d00ee 2013-09-23 0intro if(n == -1)
1106 6f4d00ee 2013-09-23 0intro switch(n){
1107 6f4d00ee 2013-09-23 0intro case IExit:
1108 4b576658 2013-09-23 0intro threadexitsall(nil);
1111 6f4d00ee 2013-09-23 0intro case Right:
1113 6f4d00ee 2013-09-23 0intro m = emouse();
1114 6f4d00ee 2013-09-23 0intro while(m.buttons == Right);
1115 6f4d00ee 2013-09-23 0intro if(m.buttons)
1117 6f4d00ee 2013-09-23 0intro tn = findnode(t.root, m.xy);
1119 6f4d00ee 2013-09-23 0intro tn->expanded = !tn->expanded;
1120 6f4d00ee 2013-09-23 0intro eresized(0);