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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#include "strmap.h"
#include "util_ct.h"
#include "util_rt.h"
#include <string.h>
#include <errno.h>
static int strmap_cmp_f (const void *a, const void *b) {
return strcmp(
((const prne_strmap_tuple_t *)a)->key,
((const prne_strmap_tuple_t *)b)->key);
}
void prne_init_strmap (prne_strmap_t *map) {
prne_memzero(map, sizeof(prne_strmap_t));
}
void prne_free_strmap (prne_strmap_t *map) {
if (map == NULL) {
return;
}
prne_strmap_clear(map);
}
void prne_strmap_clear (prne_strmap_t *map) {
for (size_t i = 0; i < map->size; i += 1) {
prne_free((void*)map->tbl[i].key);
}
prne_free(map->tbl);
prne_memzero(map, sizeof(prne_strmap_t));
}
const prne_strmap_tuple_t *prne_strmap_insert (
prne_strmap_t *map,
const char* key,
const prne_strmap_val_t val)
{
prne_strmap_tuple_t *ret;
prne_strmap_tuple_t t;
t.key = key;
t.val = val;
ret = (prne_strmap_tuple_t*)bsearch(
&t,
map->tbl,
map->size,
sizeof(prne_strmap_tuple_t),
strmap_cmp_f);
if (ret == NULL) {
const size_t sl = strlen(key);
void *ny_tbl;
t.key = prne_alloc_str(sl);
if (t.key == NULL) {
return NULL;
}
memcpy((void*)t.key, key, sl + 1);
ny_tbl = (prne_strmap_tuple_t*)prne_realloc(
map->tbl,
sizeof(prne_strmap_tuple_t),
map->size + 1);
if (ny_tbl == NULL) {
prne_free((void*)t.key);
return NULL;
}
map->tbl = (prne_strmap_tuple_t*)ny_tbl;
map->tbl[map->size] = t;
map->size += 1;
qsort(map->tbl, map->size, sizeof(prne_strmap_tuple_t), strmap_cmp_f);
ret = (prne_strmap_tuple_t*)prne_strmap_lookup(map, key);
prne_dbgast(ret != NULL);
}
else {
ret->val = t.val;
}
return ret;
}
void prne_strmap_erase (prne_strmap_t *map, const char* key) {
prne_strmap_tuple_t t, *e;
t.key = key;
t.val = 0;
e = (prne_strmap_tuple_t*)bsearch(
&t,
map->tbl,
map->size,
sizeof(prne_strmap_tuple_t),
strmap_cmp_f);
if (e == NULL) {
return;
}
prne_free((void*)e->key);
e->key = NULL;
if (map->size == 1) {
prne_strmap_clear(map);
}
else {
void *ny;
memmove(
e,
e + 1,
sizeof(prne_strmap_tuple_t) * (map->size - 1 - (e - map->tbl)));
map->size -= 1;
ny = prne_realloc(map->tbl, sizeof(prne_strmap_tuple_t), map->size);
if (ny != NULL) {
map->tbl = (prne_strmap_tuple_t*)ny;
}
}
}
const prne_strmap_tuple_t *prne_strmap_lookup (
prne_strmap_t *map,
const char* key)
{
prne_strmap_tuple_t t;
t.key = key;
t.val = 0;
return (const prne_strmap_tuple_t*)bsearch(
&t,
map->tbl,
map->size,
sizeof(prne_strmap_tuple_t),
strmap_cmp_f);
}
|