aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/fossil/walk.c
blob: 632e3e5e5201c96941b3ecfdbe8c7d6416368c90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
 * Generic traversal routines.
 */

#include "stdinc.h"
#include "dat.h"
#include "fns.h"

static uint
etype(Entry *e)
{
	uint t;

	if(e->flags&_VtEntryDir)
		t = BtDir;
	else
		t = BtData;
	return t+e->depth;
}

void
initWalk(WalkPtr *w, Block *b, uint size)
{
	memset(w, 0, sizeof *w);
	switch(b->l.type){
	case BtData:
		return;

	case BtDir:
		w->data = b->data;
		w->m = size / VtEntrySize;
		w->isEntry = 1;
		return;

	default:
		w->data = b->data;
		w->m = size / VtScoreSize;
		w->type = b->l.type;
		w->tag = b->l.tag;
		return;
	}
}

int
nextWalk(WalkPtr *w, uchar score[VtScoreSize], uchar *type, u32int *tag, Entry **e)
{
	if(w->n >= w->m)
		return 0;

	if(w->isEntry){
		*e = &w->e;
		entryUnpack(&w->e, w->data, w->n);
		memmove(score, w->e.score, VtScoreSize);
		*type = etype(&w->e);
		*tag = w->e.tag;
	}else{
		*e = nil;
		memmove(score, w->data+w->n*VtScoreSize, VtScoreSize);
		*type = w->type-1;
		*tag = w->tag;
	}
	w->n++;
	return 1;
}