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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
/* ISC license. */
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <skalibs/gensetdyn.h>
#include <skalibs/avltree.h>
#include <skalibs/cdbmake.h>
#include <skalibs/strerr.h>
#include "tipidee-config-internal.h"
#define dienomem() strerr_diefu1sys(111, "stralloc_catb")
static void *confnode_dtok (uint32_t d, void *data)
{
return g.storage.s + GENSETDYN_P(confnode, (gensetdyn *)data, d)->key ;
}
static int confnode_cmp (void const *a, void const *b, void *data)
{
(void)data ;
return strcmp((char const *)a, (char const *)b) ;
}
struct nodestore_s
{
gensetdyn set ;
avltree tree ;
} ;
static struct nodestore_s nodestore = \
{ \
.set = GENSETDYN_INIT(confnode, 8, 3, 8), \
.tree = AVLTREE_INIT(8, 3, 8, &confnode_dtok, &confnode_cmp, &nodestore.set) \
} ;
confnode const *conftree_search (char const *key)
{
uint32_t i ;
return avltree_search(&nodestore.tree, key, &i) ? GENSETDYN_P(confnode const, &nodestore.set, i) : 0 ;
}
void conftree_add (confnode const *node)
{
uint32_t i ;
if (!gensetdyn_new(&nodestore.set, &i)) dienomem() ;
*GENSETDYN_P(confnode, &nodestore.set, i) = *node ;
if (!avltree_insert(&nodestore.tree, i)) dienomem() ;
}
void conftree_update (confnode const *node)
{
uint32_t i ;
if (avltree_search(&nodestore.tree, g.storage.s + node->key, &i))
{
if (!avltree_delete(&nodestore.tree, g.storage.s + node->key)) dienomem() ;
*GENSETDYN_P(confnode, &nodestore.set, i) = *node ;
if (!avltree_insert(&nodestore.tree, i)) dienomem() ;
}
else return conftree_add(node) ;
}
static int confnode_write (uint32_t d, unsigned int h, void *data)
{
confnode *node = GENSETDYN_P(confnode, &nodestore.set, d) ;
cdbmaker *cm = data ;
(void)h ;
if ((g.storage.s[node->key] & ~0x20) == 'A')
{
g.storage.s[++node->data] |= '@' ;
node->datalen-- ;
}
return cdbmake_add(cm, g.storage.s + node->key, node->keylen, g.storage.s + node->data, node->datalen) ;
}
int conftree_write (cdbmaker *cm)
{
return avltree_iter(&nodestore.tree, &confnode_write, cm) ;
}
|