mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-18 20:03:47 +00:00
Update to the latest sdb (2.0.0)
* Experiments to integrate the custom heap into r2 will be based on the sdb implementation
This commit is contained in:
parent
6d68fc18a6
commit
560d5efced
@ -11,6 +11,7 @@ EXTRA_PRE+=$(SDBLIB)
|
||||
SDB_OBJS=
|
||||
SDB_OBJS+=buffer.o
|
||||
SDB_OBJS+=cdb.o
|
||||
SDB_OBJS+=heap.o
|
||||
SDB_OBJS+=set.o
|
||||
SDB_OBJS+=cdb_make.o
|
||||
SDB_OBJS+=ht_uu.o
|
||||
|
@ -474,6 +474,8 @@ sdb_files = [
|
||||
'shlr/sdb/src/num.c',
|
||||
'shlr/sdb/src/query.c',
|
||||
'shlr/sdb/src/sdb.c',
|
||||
'shlr/sdb/src/main.c',
|
||||
'shlr/sdb/src/heap.c',
|
||||
'shlr/sdb/src/ht.c',
|
||||
'shlr/sdb/src/util.c',
|
||||
'shlr/sdb/src/text.c'
|
||||
@ -495,6 +497,7 @@ sdb_inc_files = [
|
||||
'shlr/sdb/include/sdb/buffer.h',
|
||||
'shlr/sdb/include/sdb/cdb.h',
|
||||
'shlr/sdb/include/sdb/set.h',
|
||||
'shlr/sdb/include/sdb/heap.h',
|
||||
'shlr/sdb/include/sdb/cdb_make.h',
|
||||
'shlr/sdb/include/sdb/config.h',
|
||||
'shlr/sdb/include/sdb/dict.h',
|
||||
@ -522,7 +525,7 @@ sdb_dep = declare_dependency(
|
||||
include_directories: sdb_inc
|
||||
)
|
||||
|
||||
sdb_exe = executable('sdb', ['shlr/sdb/src/main.c'] + sdb_files,
|
||||
sdb_exe = executable('sdb', ['shlr/sdb/src/entry.c'] + sdb_files,
|
||||
include_directories: [
|
||||
include_directories('shlr/sdb/include')
|
||||
],
|
||||
|
@ -44,6 +44,9 @@ wasi wasm: $(WASI_SDK)
|
||||
test:
|
||||
${MAKE} -C test
|
||||
|
||||
heap:
|
||||
CFLAGS=-DUSE_SDB_HEAP=1 $(MAKE) -C src all
|
||||
|
||||
asan:
|
||||
$(MAKE) include/sdb/version.h
|
||||
CC=gcc LDFLAGS="$(CFLAGS_ASAN)" CFLAGS="$(CFLAGS_ASAN)" ${MAKE} -C src all
|
||||
|
70
shlr/sdb/include/sdb/heap.h
Normal file
70
shlr/sdb/include/sdb/heap.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef SDB_HEAP_H
|
||||
#define SDB_HEAP_H 1
|
||||
|
||||
typedef void *(*SdbHeapRealloc)(void *data, void *ptr, size_t size);
|
||||
typedef void (*SdbHeapFini)(void *data);
|
||||
|
||||
// global heap apis
|
||||
typedef struct sdb_global_heap_t {
|
||||
SdbHeapRealloc realloc;
|
||||
// SdbHeapInit init;
|
||||
SdbHeapFini fini;
|
||||
void *data;
|
||||
} SdbGlobalHeap;
|
||||
|
||||
extern SdbGlobalHeap Gheap;
|
||||
extern const SdbGlobalHeap sdb_gh_custom; // custom heap allocator
|
||||
extern const SdbGlobalHeap sdb_gh_libc; // use libc's heap
|
||||
|
||||
static inline void sdb_gh_use(const SdbGlobalHeap *gh) {
|
||||
if (gh) {
|
||||
memcpy (&Gheap, gh, sizeof (SdbGlobalHeap));
|
||||
} else {
|
||||
memset (&Gheap, 0, sizeof (SdbGlobalHeap));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void sdb_gh_fini(void) {
|
||||
if (Gheap.fini) {
|
||||
Gheap.fini (Gheap.data);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void *sdb_gh_malloc(size_t size) {
|
||||
if (Gheap.realloc) {
|
||||
void *ptr = Gheap.realloc (Gheap.data, NULL, size);
|
||||
// eprintf ("malloc %p\n" , ptr);
|
||||
return ptr;
|
||||
}
|
||||
return malloc (size);
|
||||
}
|
||||
|
||||
static inline void *sdb_gh_realloc(void *ptr, size_t size) {
|
||||
if (Gheap.realloc) {
|
||||
return Gheap.realloc (Gheap.data, ptr, size);
|
||||
}
|
||||
return realloc (ptr, size);
|
||||
}
|
||||
|
||||
static inline void sdb_gh_free(void *ptr) {
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
if (Gheap.realloc) {
|
||||
// eprintf ("free ptr %p\n" , ptr);
|
||||
Gheap.realloc (Gheap.data, ptr, 0);
|
||||
} else {
|
||||
free (ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void *sdb_gh_calloc(size_t count, size_t size) {
|
||||
size_t total = count * size; // TODO: detect overflow
|
||||
void *res = sdb_gh_malloc (total);
|
||||
if (res) {
|
||||
memset (res, 0, total);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,7 +1,8 @@
|
||||
#ifndef __SDB_HT_H
|
||||
#define __SDB_HT_H
|
||||
#ifndef SDB_HT_H
|
||||
#define SDB_HT_H
|
||||
|
||||
#include "ht_pp.h"
|
||||
#include "heap.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -57,4 +58,4 @@ SDB_API SdbKv* sdb_ht_find_kvp(HtPP* ht, const char* key, bool* found);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __SDB_HT_H
|
||||
#endif // SDB_HT_H
|
||||
|
@ -18,6 +18,7 @@ extern "C" {
|
||||
#include "cdb_make.h"
|
||||
#include "version.h"
|
||||
#include "rangstr.h"
|
||||
#include "heap.h"
|
||||
|
||||
/* Key value sizes */
|
||||
#define SDB_MIN_VALUE 1
|
||||
@ -163,6 +164,7 @@ SDB_API SdbList *sdb_foreach_list(Sdb* s, bool sorted);
|
||||
SDB_API SdbList *sdb_foreach_list_filter(Sdb* s, SdbForeachCallback filter, bool sorted);
|
||||
SDB_API SdbList *sdb_foreach_match(Sdb* s, const char *expr, bool sorted);
|
||||
|
||||
SDB_API int sdb_main(int argc, const char **argv);
|
||||
SDB_API bool sdb_query(Sdb* s, const char *cmd);
|
||||
SDB_API int sdb_queryf(Sdb* s, const char *fmt, ...);
|
||||
SDB_API int sdb_query_lines(Sdb *s, const char *cmd);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
#ifndef SDB_TYPES_H
|
||||
#define SDB_TYPES_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
@ -96,13 +96,13 @@ extern "C" {
|
||||
// TODO: deprecate R_NEW
|
||||
#ifndef R_NEW
|
||||
//it means we are within sdb
|
||||
#define R_NEW(x) (x*)malloc(sizeof(x))
|
||||
#define R_NEW(x) (x*)sdb_gh_malloc(sizeof(x))
|
||||
#endif
|
||||
#ifndef R_NEW0
|
||||
#define R_NEW0(x) (x*)calloc(1, sizeof(x))
|
||||
#define R_NEW0(x) (x*)sdb_gh_calloc(1, sizeof(x))
|
||||
#endif
|
||||
#ifndef R_FREE
|
||||
#define R_FREE(x) { free (x); x = NULL; }
|
||||
#define R_FREE(x) { sdb_gh_free (x); x = NULL; }
|
||||
#endif
|
||||
#define UT32_MAX ((ut32)0xffffffff)
|
||||
#define UT64_MAX ((ut64)(0xffffffffffffffffLL))
|
||||
@ -153,6 +153,8 @@ static inline void ut32_unpack(char s[4], ut32 *u) {
|
||||
*u = result;
|
||||
}
|
||||
|
||||
SDB_API char *sdb_strdup(const char *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -52,6 +52,8 @@ libsdb_sources = [
|
||||
'src/diff.c',
|
||||
'src/disk.c',
|
||||
'src/fmt.c',
|
||||
'src/heap.c',
|
||||
'src/main.c',
|
||||
'src/ht_uu.c',
|
||||
'src/ht_up.c',
|
||||
'src/ht_pp.c',
|
||||
@ -70,7 +72,8 @@ libsdb_sources = [
|
||||
'src/text.c'
|
||||
]
|
||||
|
||||
sdb_inc = include_directories(['include'])
|
||||
# . = b/version.h
|
||||
sdb_inc = include_directories(['.', 'include'])
|
||||
rpath_lib = ''
|
||||
rpath_exe = ''
|
||||
if get_option('local') and get_option('default_library') == 'shared'
|
||||
@ -104,6 +107,7 @@ if not meson.is_subproject()
|
||||
'include/sdb/cdb_make.h',
|
||||
'include/sdb/config.h',
|
||||
'include/sdb/dict.h',
|
||||
'include/sdb/heap.h',
|
||||
'include/sdb/ht_inc.h',
|
||||
'include/sdb/ht_pp.h',
|
||||
'include/sdb/ht_up.h',
|
||||
@ -118,7 +122,7 @@ if not meson.is_subproject()
|
||||
install_headers(include_files, subdir: 'sdb')
|
||||
endif
|
||||
|
||||
sdb_exe = executable('sdb', join_paths('src','main.c'),
|
||||
sdb_exe = executable('sdb', join_paths('src','entry.c'),
|
||||
include_directories: sdb_inc,
|
||||
link_with: [link_with],
|
||||
install: not meson.is_subproject(),
|
||||
@ -127,7 +131,7 @@ sdb_exe = executable('sdb', join_paths('src','main.c'),
|
||||
)
|
||||
|
||||
if meson.is_cross_build()
|
||||
sdb_native_exe = executable('sdb_native', join_paths('src','main.c'),
|
||||
sdb_native_exe = executable('sdb_native', join_paths('src','entry.c'),
|
||||
include_directories: sdb_inc,
|
||||
link_with: [link_with],
|
||||
install: false,
|
||||
|
@ -3,7 +3,7 @@ include ../config.mk
|
||||
# CFLAGS:=-g $(CFLAGS)
|
||||
OBJ=cdb.o buffer.o cdb_make.o ls.o ht.o ht_uu.o sdb.o num.o base64.o match.o
|
||||
OBJ+=json.o ns.o lock.o util.o disk.o query.o array.o fmt.o journal.o text.o
|
||||
OBJ+=dict.o ht_pp.o ht_up.o ht_pu.o set.o diff.o
|
||||
OBJ+=dict.o ht_pp.o ht_up.o ht_pu.o set.o diff.o heap.o main.o
|
||||
SDB_CFLAGS+=-I../include
|
||||
SDB_CXXFLAGS+=-I../include
|
||||
SOBJ=$(subst .o,.o.o,${OBJ})
|
||||
@ -61,16 +61,16 @@ endif
|
||||
$(CC) ${LDFLAGS} $(LDFLAGS_SHARED) -o $@ ${SOBJ}
|
||||
|
||||
bin_deps: ../include/sdb/version.h
|
||||
$(MAKE) libsdb.a main.o
|
||||
$(MAKE) libsdb.a entry.o
|
||||
|
||||
bin $(BIN): bin_deps
|
||||
ifneq ($(SILENT),)
|
||||
@echo BIN ${BIN}
|
||||
endif
|
||||
$(CC) ${LDFLAGS} -o ${BIN} main.o ${OBJ}
|
||||
$(CC) ${LDFLAGS} -o ${BIN} entry.o ${OBJ}
|
||||
|
||||
mrproper clean:
|
||||
rm -rf ${OBJ} ${SOBJ} main.o libsdb.a a.out ${BIN} sdb.dSYM
|
||||
rm -rf ${OBJ} ${SOBJ} entry.o libsdb.a a.out ${BIN} sdb.dSYM
|
||||
rm -rf *.d *._d json/*.d json/*._d *.sdb *.db *.dylib *.dll *.so *.so.*
|
||||
|
||||
# rules #
|
||||
|
@ -98,10 +98,10 @@ SDB_API char *sdb_array_get(Sdb *s, const char *key, int idx, ut32 *cas) {
|
||||
if (!idx) {
|
||||
n = strchr ((char *)str, SDB_RS);
|
||||
if (!n) {
|
||||
return strdup (str);
|
||||
return sdb_strdup (str);
|
||||
}
|
||||
len = n - str;
|
||||
o = (char *)malloc (len + 1);
|
||||
o = (char *)sdb_gh_malloc (len + 1);
|
||||
if (!o) {
|
||||
return NULL;
|
||||
}
|
||||
@ -116,10 +116,10 @@ SDB_API char *sdb_array_get(Sdb *s, const char *key, int idx, ut32 *cas) {
|
||||
}
|
||||
n = strchr ((char *)p, SDB_RS);
|
||||
if (!n) {
|
||||
return strdup (p);
|
||||
return sdb_strdup (p);
|
||||
}
|
||||
len = n - p;
|
||||
o = (char *)malloc (len + 1);
|
||||
o = (char *)sdb_gh_malloc (len + 1);
|
||||
if (o) {
|
||||
memcpy (o, p, len);
|
||||
o[len] = 0;
|
||||
@ -155,7 +155,7 @@ SDB_API int sdb_array_insert(Sdb *s, const char *key, int idx, const char *val,
|
||||
if (SZT_ADD_OVFCHK (lval, lstr_tmp) || SZT_ADD_OVFCHK (lval + lstr_tmp, 2)) {
|
||||
return false;
|
||||
}
|
||||
x = (char *)malloc (lval + lstr_tmp + 2);
|
||||
x = (char *)sdb_gh_malloc (lval + lstr_tmp + 2);
|
||||
if (!x) {
|
||||
return false;
|
||||
}
|
||||
@ -169,9 +169,9 @@ SDB_API int sdb_array_insert(Sdb *s, const char *key, int idx, const char *val,
|
||||
x[lval] = SDB_RS;
|
||||
memcpy (x + lval + 1, str, lstr + 1);
|
||||
} else {
|
||||
char *nstr = (char *)malloc (lstr + 1);
|
||||
char *nstr = (char *)sdb_gh_malloc (lstr + 1);
|
||||
if (!nstr) {
|
||||
free (x);
|
||||
sdb_gh_free (x);
|
||||
return false;
|
||||
}
|
||||
memcpy (nstr, str, lstr + 1);
|
||||
@ -187,11 +187,11 @@ SDB_API int sdb_array_insert(Sdb *s, const char *key, int idx, const char *val,
|
||||
x[lnstr + lval + 1] = SDB_RS;
|
||||
// TODO: this strlen hurts performance
|
||||
memcpy (x + lval + 2 + lnstr, ptr, lptr); //strlen (ptr)+1);
|
||||
free (nstr);
|
||||
sdb_gh_free (nstr);
|
||||
} else {
|
||||
// this is not efficient
|
||||
free (nstr);
|
||||
free (x);
|
||||
sdb_gh_free (nstr);
|
||||
sdb_gh_free (x);
|
||||
// fallback for empty buckets
|
||||
return sdb_array_set (s, key, idx, val, cas);
|
||||
}
|
||||
@ -246,7 +246,7 @@ SDB_API int sdb_array_add_sorted(Sdb *s, const char *key, const char *val, ut32
|
||||
if (i > 1) {
|
||||
qsort (vals, i, sizeof (ut64*), cstring_cmp);
|
||||
}
|
||||
nstr_p = nstr = (char *)malloc (lstr + lval + 3);
|
||||
nstr_p = nstr = (char *)sdb_gh_malloc (lstr + lval + 3);
|
||||
if (!nstr) {
|
||||
return 1;
|
||||
}
|
||||
@ -279,7 +279,7 @@ SDB_API int sdb_array_add_sorted(Sdb *s, const char *key, const char *val, ut32
|
||||
*(--nstr_p) = '\0';
|
||||
}
|
||||
sdb_set_owned (s, key, nstr, cas);
|
||||
free (vals);
|
||||
sdb_gh_free (vals);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -318,7 +318,7 @@ SDB_API bool sdb_array_append(Sdb *s, const char *key, const char *val,
|
||||
cas = kas;
|
||||
if (str && *str && str_len > 0) {
|
||||
int val_len = strlen (val);
|
||||
char *newval = (char *)malloc (str_len + val_len + 2);
|
||||
char *newval = (char *)sdb_gh_malloc (str_len + val_len + 2);
|
||||
if (!newval) {
|
||||
return false;
|
||||
}
|
||||
@ -356,7 +356,7 @@ SDB_API int sdb_array_set(Sdb *s, const char *key, int idx, const char *val,
|
||||
lval = strlen (val);
|
||||
if (idx > len) {
|
||||
int ret, i, ilen = idx-len;
|
||||
char *newkey = (char *)malloc (ilen + lval + 1);
|
||||
char *newkey = (char *)sdb_gh_malloc (ilen + lval + 1);
|
||||
if (!newkey) {
|
||||
return 0;
|
||||
}
|
||||
@ -365,14 +365,14 @@ SDB_API int sdb_array_set(Sdb *s, const char *key, int idx, const char *val,
|
||||
}
|
||||
memcpy (newkey + i, val, lval + 1);
|
||||
ret = sdb_array_insert (s, key, -1, newkey, cas);
|
||||
free (newkey);
|
||||
sdb_gh_free (newkey);
|
||||
return ret;
|
||||
}
|
||||
//lstr = strlen (str);
|
||||
ptr = (char*)Aindexof (str, idx);
|
||||
if (ptr) {
|
||||
int diff = ptr - str;
|
||||
char *nstr = (char *)malloc (lstr + lval + 2);
|
||||
char *nstr = (char *)sdb_gh_malloc (lstr + lval + 2);
|
||||
if (!nstr) {
|
||||
return false;
|
||||
}
|
||||
@ -386,7 +386,7 @@ SDB_API int sdb_array_set(Sdb *s, const char *key, int idx, const char *val,
|
||||
strcpy (ptr + lval + 1, usr);
|
||||
}
|
||||
int ret = sdb_set (s, key, nstr, cas);
|
||||
free (nstr);
|
||||
sdb_gh_free (nstr);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
@ -458,7 +458,7 @@ SDB_API int sdb_array_delete(Sdb *s, const char *key, int idx, ut32 cas) {
|
||||
char *p, *n, *str = sdb_get (s, key, 0);
|
||||
p = str;
|
||||
if (!str || !*str) {
|
||||
free (str);
|
||||
sdb_gh_free (str);
|
||||
return 0;
|
||||
}
|
||||
if (idx < 0) {
|
||||
@ -469,7 +469,7 @@ SDB_API int sdb_array_delete(Sdb *s, const char *key, int idx, ut32 cas) {
|
||||
if ( (n = strchr (p, SDB_RS)) ) {
|
||||
p = n + 1;
|
||||
} else {
|
||||
free (str);
|
||||
sdb_gh_free (str);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -558,7 +558,7 @@ SDB_API bool sdb_array_prepend (Sdb *s, const char *key, const char *val, ut32 c
|
||||
cas = kas;
|
||||
if (str && *str) {
|
||||
int val_len = strlen (val);
|
||||
char *newval = (char *)malloc (str_len + val_len + 2);
|
||||
char *newval = (char *)sdb_gh_malloc (str_len + val_len + 2);
|
||||
if (!newval) {
|
||||
return false;
|
||||
}
|
||||
@ -587,7 +587,7 @@ SDB_API ut64 sdb_array_pop_num(Sdb *s, const char *key, ut32 *cas) {
|
||||
*cas = 0;
|
||||
}
|
||||
ret = sdb_atoi (a);
|
||||
free (a);
|
||||
sdb_gh_free (a);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -604,7 +604,7 @@ SDB_API char *sdb_array_pop_head(Sdb *s, const char *key, ut32 *cas) {
|
||||
ut32 kas;
|
||||
char *end, *str = sdb_get (s, key, &kas);
|
||||
if (!str || !*str) {
|
||||
free (str);
|
||||
sdb_gh_free (str);
|
||||
return NULL;
|
||||
}
|
||||
if (cas && *cas != kas) {
|
||||
@ -624,7 +624,7 @@ SDB_API char *sdb_array_pop_tail(Sdb *s, const char *key, ut32 *cas) {
|
||||
ut32 kas;
|
||||
char *end, *str = sdb_get (s, key, &kas);
|
||||
if (!str || !*str) {
|
||||
free (str);
|
||||
sdb_gh_free (str);
|
||||
return NULL;
|
||||
}
|
||||
if (cas && *cas != kas) {
|
||||
@ -638,7 +638,7 @@ SDB_API char *sdb_array_pop_tail(Sdb *s, const char *key, ut32 *cas) {
|
||||
}
|
||||
sdb_set_owned (s, key, str, 0);
|
||||
// XXX: probably wrong
|
||||
return strdup (end);
|
||||
return sdb_strdup (end);
|
||||
}
|
||||
|
||||
SDB_API void sdb_array_sort(Sdb *s, const char *key, ut32 cas) {
|
||||
@ -649,7 +649,7 @@ SDB_API void sdb_array_sort(Sdb *s, const char *key, ut32 cas) {
|
||||
return;
|
||||
}
|
||||
if (!*str) {
|
||||
free (str);
|
||||
sdb_gh_free (str);
|
||||
return;
|
||||
}
|
||||
strs = sdb_fmt_array (str);
|
||||
@ -670,7 +670,7 @@ SDB_API void sdb_array_sort(Sdb *s, const char *key, ut32 cas) {
|
||||
*nstr = '\0';
|
||||
}
|
||||
sdb_set_owned (s, key, str, cas);
|
||||
free (strs);
|
||||
sdb_gh_free (strs);
|
||||
}
|
||||
|
||||
SDB_API void sdb_array_sort_num(Sdb *s, const char *key, ut32 cas) {
|
||||
@ -681,20 +681,20 @@ SDB_API void sdb_array_sort_num(Sdb *s, const char *key, ut32 cas) {
|
||||
return;
|
||||
}
|
||||
if (!*str) {
|
||||
free (str);
|
||||
sdb_gh_free (str);
|
||||
return;
|
||||
}
|
||||
ut64 *nums = sdb_fmt_array_num (str);
|
||||
free (str);
|
||||
sdb_gh_free (str);
|
||||
if (!nums) {
|
||||
return;
|
||||
}
|
||||
|
||||
qsort (nums + 1, (int)*nums, sizeof (ut64), int_cmp);
|
||||
|
||||
nstr = (char *)malloc (*nums + 1);
|
||||
nstr = (char *)sdb_gh_malloc (*nums + 1);
|
||||
if (!nstr) {
|
||||
free (nums);
|
||||
sdb_gh_free (nums);
|
||||
return;
|
||||
}
|
||||
memset (nstr, 'q', *nums);
|
||||
@ -703,7 +703,7 @@ SDB_API void sdb_array_sort_num(Sdb *s, const char *key, ut32 cas) {
|
||||
ret = sdb_fmt_tostr (nums + 1, nstr);
|
||||
sdb_set_owned (s, key, ret, cas);
|
||||
|
||||
free (nstr);
|
||||
free (nums);
|
||||
sdb_gh_free (nstr);
|
||||
sdb_gh_free (nums);
|
||||
return;
|
||||
}
|
||||
|
@ -66,9 +66,9 @@ SDB_API char *sdb_encode(const ut8 *bin, int len) {
|
||||
len = strlen ((const char *)bin);
|
||||
}
|
||||
if (!len) {
|
||||
return strdup ("");
|
||||
return sdb_strdup ("");
|
||||
}
|
||||
out = (char *)calloc (8 + (len * 2), sizeof (char));
|
||||
out = (char *)sdb_gh_calloc (8 + (len * 2), sizeof (char));
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
@ -94,13 +94,13 @@ SDB_API ut8 *sdb_decode(const char *in, int *len) {
|
||||
if (size < (ut32)ilen) {
|
||||
return NULL;
|
||||
}
|
||||
out = (ut8 *)calloc (1, size);
|
||||
out = (ut8 *)sdb_gh_calloc (1, size);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
olen = sdb_decode_raw (out, in, ilen);
|
||||
if (!olen) {
|
||||
free (out);
|
||||
sdb_gh_free (out);
|
||||
return NULL;
|
||||
}
|
||||
out[olen] = 0;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include "sdb/cdb.h"
|
||||
#include "sdb/heap.h"
|
||||
#if USE_MMAN
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
@ -29,7 +30,7 @@ void cdb_free(struct cdb *c) {
|
||||
#if USE_MMAN
|
||||
(void)munmap (c->map, c->size);
|
||||
#else
|
||||
free (c->map);
|
||||
sdb_gh_free (c->map);
|
||||
#endif
|
||||
c->map = NULL;
|
||||
}
|
||||
@ -61,7 +62,7 @@ bool cdb_init(struct cdb *c, int fd) {
|
||||
munmap (c->map, c->size);
|
||||
}
|
||||
#else
|
||||
char *x = calloc (1, st.st_size);
|
||||
char *x = sdb_gh_calloc (1, st.st_size);
|
||||
if (!x) {
|
||||
// eprintf ("Cannot malloc %d\n", (int)st.st_size);
|
||||
return false;
|
||||
@ -70,7 +71,7 @@ bool cdb_init(struct cdb *c, int fd) {
|
||||
if (read (fd, x, st.st_size) != st.st_size) {
|
||||
/* handle read error */
|
||||
}
|
||||
free (c->map);
|
||||
sdb_gh_free (c->map);
|
||||
#endif
|
||||
c->map = x;
|
||||
c->size = st.st_size;
|
||||
|
@ -5,23 +5,32 @@
|
||||
#include "sdb/cdb_make.h"
|
||||
|
||||
#define ALIGNMENT sizeof (void*)
|
||||
#define USE_GHA 1
|
||||
|
||||
char *cdb_alloc(ut32 n) {
|
||||
static char *cdb_alloc(ut32 n) {
|
||||
#if USE_GHA
|
||||
return (char *)sdb_gh_malloc (n);
|
||||
#else
|
||||
#if __APPLE__ && !__POWERPC__
|
||||
void *ret = NULL;
|
||||
return (char *)(posix_memalign (&ret, ALIGNMENT, n)? NULL: ret);
|
||||
#elif __SDB_WINDOWS__ && !__CYGWIN__
|
||||
return (char *)_aligned_malloc (n, ALIGNMENT);
|
||||
#else
|
||||
return (char *)malloc (n);
|
||||
return (char *)sdb_gh_malloc (n);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void cdb_alloc_free(void *x) {
|
||||
static void cdb_alloc_free(void *x) {
|
||||
#if USE_GHA
|
||||
sdb_gh_free (x);
|
||||
#else
|
||||
#if __SDB_WINDOWS__ && !__CYGWIN__
|
||||
_aligned_free (x);
|
||||
#else
|
||||
free (x);
|
||||
sdb_gh_free (x);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -50,12 +59,12 @@ static inline int incpos(struct cdb_make *c, ut32 len) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define R_ANEW(x) (x*)cdb_alloc(sizeof(x))
|
||||
int cdb_make_addend(struct cdb_make *c, ut32 keylen, ut32 datalen, ut32 h) {
|
||||
ut32 u;
|
||||
struct cdb_hplist *head = c->head;
|
||||
if (!head || (head->num >= CDB_HPLIST)) {
|
||||
if (!(head = R_ANEW (struct cdb_hplist))) {
|
||||
head = (struct cdb_hplist*)cdb_alloc (sizeof (struct cdb_hplist));
|
||||
if (!head) {
|
||||
return 0;
|
||||
}
|
||||
head->num = 0;
|
||||
|
@ -3,9 +3,9 @@
|
||||
#include "sdb/sdb.h"
|
||||
|
||||
SDB_API dict *dict_new(ut32 size, dict_freecb f) {
|
||||
dict *m = (dict *)calloc (1, sizeof (dict));
|
||||
dict *m = (dict *)sdb_gh_calloc (1, sizeof (dict));
|
||||
if (!dict_init (m, R_MAX (size, 1), f)) {
|
||||
free (m);
|
||||
sdb_gh_free (m);
|
||||
m = NULL;
|
||||
}
|
||||
return m;
|
||||
@ -23,7 +23,7 @@ SDB_API bool dict_init(dict *m, ut32 size, dict_freecb f) {
|
||||
if (m) {
|
||||
memset (m, 0, sizeof (dict));
|
||||
if (size > 0) {
|
||||
m->table = (void **)calloc (size, sizeof (dictkv));
|
||||
m->table = (void **)sdb_gh_calloc (size, sizeof (dictkv));
|
||||
if (!m->table) {
|
||||
return false;
|
||||
}
|
||||
@ -46,14 +46,14 @@ SDB_API void dict_fini(dict *m) {
|
||||
kv++;
|
||||
}
|
||||
}
|
||||
free (m->table[i]);
|
||||
sdb_gh_free (m->table[i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < m->size; i++) {
|
||||
free (m->table[i]);
|
||||
sdb_gh_free (m->table[i]);
|
||||
}
|
||||
}
|
||||
free (m->table);
|
||||
sdb_gh_free (m->table);
|
||||
dict_init (m, 0, NULL);
|
||||
}
|
||||
}
|
||||
@ -61,7 +61,7 @@ SDB_API void dict_fini(dict *m) {
|
||||
SDB_API void dict_free(dict *m) {
|
||||
if (m) {
|
||||
dict_fini (m);
|
||||
free (m);
|
||||
sdb_gh_free (m);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ SDB_API bool dict_set(dict *m, dicti k, dicti v, void *u) {
|
||||
const int bucket = dict_bucket (m, k);
|
||||
dictkv *kv = (dictkv *)m->table[bucket];
|
||||
if (!kv) {
|
||||
kv = (dictkv *)calloc (sizeof (dictkv), 2);
|
||||
kv = (dictkv *)sdb_gh_calloc (sizeof (dictkv), 2);
|
||||
if (kv) {
|
||||
m->table[bucket] = kv;
|
||||
kv->k = 0;
|
||||
@ -97,7 +97,7 @@ SDB_API bool dict_set(dict *m, dicti k, dicti v, void *u) {
|
||||
kv++;
|
||||
}
|
||||
int curln = (kv - tmp);
|
||||
dictkv *newkv = (dictkv *)realloc (tmp, (curln + 2) * sizeof (dictkv));
|
||||
dictkv *newkv = (dictkv *)sdb_gh_realloc (tmp, (curln + 2) * sizeof (dictkv));
|
||||
if (newkv) {
|
||||
kv = newkv;
|
||||
m->table[bucket] = newkv;
|
||||
|
@ -18,7 +18,7 @@ static wchar_t *r_utf8_to_utf16_l (const char *cstring, int len) {
|
||||
|
||||
if ((wcsize = MultiByteToWideChar (CP_UTF8, 0, cstring, len, NULL, 0))) {
|
||||
wcsize += 1;
|
||||
if ((rutf16 = (wchar_t *) calloc (wcsize, sizeof (wchar_t)))) {
|
||||
if ((rutf16 = (wchar_t *) sdb_gh_calloc (wcsize, sizeof (wchar_t)))) {
|
||||
MultiByteToWideChar (CP_UTF8, 0, cstring, len, rutf16, wcsize);
|
||||
if (len != -1) {
|
||||
rutf16[wcsize - 1] = L'\0';
|
||||
@ -33,11 +33,11 @@ static wchar_t *r_utf8_to_utf16_l (const char *cstring, int len) {
|
||||
static bool r_sys_mkdir(const char *path) {
|
||||
LPTSTR path_ = r_sys_conv_utf8_to_utf16 (path);
|
||||
bool ret = CreateDirectory (path_, NULL);
|
||||
free (path_);
|
||||
sdb_gh_free (path_);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#define r_sys_conv_utf8_to_utf16(buf) strdup (buf)
|
||||
#define r_sys_conv_utf8_to_utf16(buf) sdb_strdup (buf)
|
||||
#define r_sys_mkdir(x) CreateDirectory (x, NULL)
|
||||
#endif
|
||||
#ifndef ERROR_ALREADY_EXISTS
|
||||
@ -83,12 +83,12 @@ SDB_API bool sdb_disk_create(Sdb* s) {
|
||||
return false; // cannot re-create
|
||||
}
|
||||
if (!s->dir && s->name) {
|
||||
s->dir = strdup (s->name);
|
||||
s->dir = sdb_strdup (s->name);
|
||||
}
|
||||
dir = s->dir ? s->dir : "./";
|
||||
R_FREE (s->ndump);
|
||||
nlen = strlen (dir);
|
||||
str = (char *)malloc (nlen + 5);
|
||||
str = (char *)sdb_gh_malloc (nlen + 5);
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
@ -102,7 +102,7 @@ SDB_API bool sdb_disk_create(Sdb* s) {
|
||||
wchar_t *wstr = r_sys_conv_utf8_to_utf16 (str);
|
||||
if (wstr) {
|
||||
s->fdump = _wopen (wstr, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, SDB_MODE);
|
||||
free (wstr);
|
||||
sdb_gh_free (wstr);
|
||||
} else {
|
||||
s->fdump = -1;
|
||||
}
|
||||
@ -111,7 +111,7 @@ SDB_API bool sdb_disk_create(Sdb* s) {
|
||||
#endif
|
||||
if (s->fdump == -1) {
|
||||
// eprintf ("sdb: Cannot open '%s' for writing.\n", str);
|
||||
free (str);
|
||||
sdb_gh_free (str);
|
||||
return false;
|
||||
}
|
||||
cdb_make_start (&s->m, s->fdump);
|
||||
@ -150,14 +150,14 @@ SDB_API bool sdb_disk_finish (Sdb* s) {
|
||||
if (MoveFileEx (ndump_, dir_, MOVEFILE_REPLACE_EXISTING)) {
|
||||
//eprintf ("Error 0x%02x\n", GetLastError ());
|
||||
}
|
||||
free (ndump_);
|
||||
free (dir_);
|
||||
sdb_gh_free (ndump_);
|
||||
sdb_gh_free (dir_);
|
||||
#else
|
||||
if (s->ndump && s->dir) {
|
||||
IFRET (rename (s->ndump, s->dir));
|
||||
}
|
||||
#endif
|
||||
free (s->ndump);
|
||||
sdb_gh_free (s->ndump);
|
||||
s->ndump = NULL;
|
||||
// reopen if was open before
|
||||
reopen = true; // always reopen if possible
|
||||
|
14
shlr/sdb/src/entry.c
Normal file
14
shlr/sdb/src/entry.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include <sdb/sdb.h>
|
||||
|
||||
#ifndef SDB_CUSTOM_HEAP
|
||||
#define SDB_CUSTOM_HEAP sdb_gh_custom
|
||||
#endif
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
#if USE_SDB_HEAP
|
||||
sdb_gh_use (&SDB_CUSTOM_HEAP);
|
||||
#else
|
||||
sdb_gh_use (&sdb_gh_libc);
|
||||
#endif
|
||||
return sdb_main (argc, argv);
|
||||
}
|
@ -8,14 +8,14 @@
|
||||
#define concat(x) if (x) { \
|
||||
int size = 2 + strlen (x? x: "")+(out? strlen (out) + 4: 0); \
|
||||
if (out) { \
|
||||
char *o = (char *)realloc (out, size); \
|
||||
char *o = (char *)sdb_gh_realloc (out, size); \
|
||||
if (o) { \
|
||||
strcat (o, ","); \
|
||||
strcat (o, x); \
|
||||
out = o; \
|
||||
} \
|
||||
} else { \
|
||||
out = strdup (x); \
|
||||
out = sdb_strdup (x); \
|
||||
} \
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ SDB_API char *sdb_fmt_tostr(void *p, const char *fmt) {
|
||||
case 's':
|
||||
e_str = sdb_encode ((const ut8*)*((char**)nbuf), -1);
|
||||
concat (e_str);
|
||||
free (e_str);
|
||||
sdb_gh_free (e_str);
|
||||
break;
|
||||
case 'p':
|
||||
concat (sdb_itoa ((ut64)*((size_t*)(nbuf)), 16, buf, sizeof (buf)));
|
||||
@ -68,7 +68,7 @@ SDB_API int sdb_fmt_tobin(const char *_str, const char *fmt, void *stru) {
|
||||
if (!_str || !*_str || !fmt) {
|
||||
return 0;
|
||||
}
|
||||
str = ptr = strdup (_str);
|
||||
str = ptr = sdb_strdup (_str);
|
||||
for (; *fmt; fmt++) {
|
||||
word = sdb_anext (ptr, &next);
|
||||
if (!word || !*word) {
|
||||
@ -83,10 +83,10 @@ SDB_API int sdb_fmt_tobin(const char *_str, const char *fmt, void *stru) {
|
||||
case 'h': *((short*)(stru8 + idx)) = (short)sdb_atoi (word); break;
|
||||
case 's':
|
||||
e_str = (char*)sdb_decode (word, 0);
|
||||
*((char**)(stru8 + idx)) = e_str? e_str: strdup (word);
|
||||
*((char**)(stru8 + idx)) = e_str? e_str: sdb_strdup (word);
|
||||
break;
|
||||
case 'z':
|
||||
*((char**)(stru8 + idx)) = (char*)strdup (word);
|
||||
*((char**)(stru8 + idx)) = (char*)sdb_strdup (word);
|
||||
break;
|
||||
case 'p':
|
||||
*((void**)(stru8 + idx)) = (void*)(size_t)sdb_atoi (word);
|
||||
@ -118,7 +118,7 @@ SDB_API void sdb_fmt_free (void *stru, const char *fmt) {
|
||||
break;
|
||||
case 'z':
|
||||
case 's':
|
||||
free ((void*)*((char**)((ut8*)stru + len)));
|
||||
sdb_gh_free ((void*)*((char**)((ut8*)stru + len)));
|
||||
break;
|
||||
}
|
||||
len += R_MAX ((long)sizeof (void*), n); // align
|
||||
@ -164,7 +164,7 @@ SDB_API ut64* sdb_fmt_array_num(const char *list) {
|
||||
if (size < len) {
|
||||
return NULL;
|
||||
}
|
||||
retp = ret = (ut64*) malloc (size);
|
||||
retp = ret = (ut64*) sdb_gh_malloc (size);
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
@ -184,7 +184,7 @@ SDB_API char** sdb_fmt_array(const char *list) {
|
||||
const char *next, *ptr = list;
|
||||
if (list && *list) {
|
||||
int len = sdb_alen (list);
|
||||
retp = ret = (char**) malloc (2 * strlen (list) +
|
||||
retp = ret = (char**) sdb_gh_malloc (2 * strlen (list) +
|
||||
((len + 1) * sizeof (char *)) + 1);
|
||||
_s = (char *)ret + ((len + 1) * sizeof (char *));
|
||||
if (!ret) {
|
||||
|
430
shlr/sdb/src/heap.c
Normal file
430
shlr/sdb/src/heap.c
Normal file
@ -0,0 +1,430 @@
|
||||
// https://github.com/YeonwooSung/MemoryAllocation
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include "sdb/sdb.h"
|
||||
#include "sdb/heap.h"
|
||||
|
||||
// generic global
|
||||
SdbGlobalHeap Gheap = {NULL, NULL};
|
||||
// local heap allocator api
|
||||
const SdbGlobalHeap sdb_gh_libc = { NULL, NULL, NULL };
|
||||
|
||||
SDB_API char *sdb_strdup(const char *s) {
|
||||
size_t sl = strlen (s) + 1;
|
||||
char *p = (char *)sdb_gh_malloc (sl);
|
||||
if (p) {
|
||||
memcpy (p, s, sl);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
#if __SDB_WINDOWS__
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
// Size 16
|
||||
typedef struct free_list {
|
||||
struct free_list *next;
|
||||
struct free_list *prev;
|
||||
} free_list;
|
||||
|
||||
typedef struct sdb_heap_t {
|
||||
// Globals
|
||||
int *last_address;
|
||||
free_list *free_list_start;
|
||||
// To reduce number of mmap calls.
|
||||
int last_mapped_size; // 1;
|
||||
} SdbHeap;
|
||||
|
||||
SDB_API void sdb_heap_fini(SdbHeap *heap);
|
||||
SDB_API void *sdb_heap_realloc(SdbHeap *heap, void *ptr, int size);
|
||||
|
||||
static SdbHeap sdb_gh_custom_data = { NULL, NULL, 1};
|
||||
const SdbGlobalHeap sdb_gh_custom = {
|
||||
(SdbHeapRealloc)sdb_heap_realloc,
|
||||
(SdbHeapFini)sdb_heap_fini,
|
||||
&sdb_gh_custom_data
|
||||
};
|
||||
|
||||
#define USED false
|
||||
#define FREE true
|
||||
|
||||
typedef struct Header {
|
||||
int size;
|
||||
bool free : 1;
|
||||
bool has_prev : 1;
|
||||
bool has_next : 1;
|
||||
} Header;
|
||||
|
||||
// Size field is not necessary in used blocks.
|
||||
typedef struct Footer {
|
||||
int size;
|
||||
bool free : 1;
|
||||
} Footer;
|
||||
|
||||
|
||||
#define ALIGNMENT 8
|
||||
#define ALIGN(size) (((size) + (ALIGNMENT - 1)) & ~(ALIGNMENT - 1))
|
||||
#define PAGE_SIZE sysconf(_SC_PAGESIZE)
|
||||
#define CEIL(X) ((X - (int)(X)) > 0 ? (int)(X + 1) : (int)(X))
|
||||
#define PAGES(size) (CEIL(size / (double)PAGE_SIZE))
|
||||
#define MIN_SIZE (ALIGN(sizeof(free_list) + META_SIZE))
|
||||
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
|
||||
|
||||
// Meta sizes.
|
||||
#define META_SIZE ALIGN(sizeof(Header) + sizeof(Footer))
|
||||
#define HEADER_SIZE ALIGN(sizeof(Header))
|
||||
#define FOOTER_SIZE ALIGN(sizeof(Footer))
|
||||
|
||||
// Get pointer to the payload (passing the pointer to the header).
|
||||
static void *add_offset(void *ptr) {
|
||||
return (void *)((const ut8*)ptr + HEADER_SIZE);
|
||||
}
|
||||
|
||||
// Get poiner to the header (passing pointer to the payload).
|
||||
static void *remove_offset(void *ptr) {
|
||||
return (void *)((const ut8*)ptr - HEADER_SIZE);
|
||||
}
|
||||
|
||||
static void *getFooter(void *header_ptr) {
|
||||
return (void*)((ut8*)header_ptr + ((Header *)header_ptr)->size - FOOTER_SIZE);
|
||||
}
|
||||
|
||||
static void setFree(void *ptr, int val) {
|
||||
((Header *)ptr)->free = val;
|
||||
Footer *footer = (Footer *)getFooter(ptr);
|
||||
footer->free = val;
|
||||
// Copy size to footer size field.
|
||||
footer->size = ((Header *)ptr)->size;
|
||||
}
|
||||
|
||||
// Set size in the header.
|
||||
static inline void setSizeHeader(void *ptr, int size) {
|
||||
((Header *)ptr)->size = size;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Set size in the header.
|
||||
static inline void setSizeFooter(void *ptr, int size) {
|
||||
((Footer *)getFooter(ptr))->size = size;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get size of the free list item.
|
||||
static inline int getSize(void *ptr) {
|
||||
return ((Header *)remove_offset (ptr))->size;
|
||||
}
|
||||
|
||||
static void remove_from_free_list(SdbHeap *heap, void *block) {
|
||||
setFree(block, USED);
|
||||
|
||||
free_list *free_block = (free_list *)add_offset(block);
|
||||
free_list *next = free_block->next;
|
||||
free_list *prev = free_block->prev;
|
||||
if (!prev) {
|
||||
if (!next) {
|
||||
// free_block is the only block in the free list.
|
||||
heap->free_list_start = NULL;
|
||||
} else {
|
||||
// Remove first element in the free list.
|
||||
heap->free_list_start = next;
|
||||
next->prev = NULL;
|
||||
}
|
||||
} else {
|
||||
if (!next) {
|
||||
// Remove last element of the free list.
|
||||
prev->next = NULL;
|
||||
} else {
|
||||
// Remove element in the middle.
|
||||
prev->next = next;
|
||||
next->prev = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void append_to_free_list(SdbHeap *heap, void *ptr) {
|
||||
setFree (ptr, FREE);
|
||||
|
||||
free_list eew = {};
|
||||
free_list *new_ptr = (free_list *)add_offset (ptr);
|
||||
*new_ptr = eew;
|
||||
|
||||
if (heap->free_list_start) {
|
||||
// Insert in the beginning.
|
||||
new_ptr->next = heap->free_list_start;
|
||||
new_ptr->prev = NULL;
|
||||
heap->free_list_start->prev = new_ptr;
|
||||
heap->free_list_start = new_ptr;
|
||||
} else {
|
||||
// No elements in the free list
|
||||
heap->free_list_start = new_ptr;
|
||||
new_ptr->prev = NULL;
|
||||
new_ptr->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Find a free block that is large enough to store 'size' bytes.
|
||||
// Returns NULL if not found.
|
||||
static free_list *find_free_block(SdbHeap *heap, int size) {
|
||||
free_list *current = heap->free_list_start;
|
||||
while (current) {
|
||||
if (getSize (current) >= size) {
|
||||
// Return a pointer to the free block.
|
||||
return current;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Split memory into multiple blocks after some part of it was requested
|
||||
// (requested + the rest).
|
||||
static void split(SdbHeap *heap, void *start_ptr, int total, int requested) {
|
||||
void *new_block_ptr = (void*)((ut8*)start_ptr + requested);
|
||||
int block_size = total - requested;
|
||||
|
||||
// Size that was left after allocating memory.
|
||||
// Needs to be large enough to store another block (min size is needed in order
|
||||
// to store free list element there after it is freed).
|
||||
if (block_size < (int)MIN_SIZE) {
|
||||
// Not enough size to split.
|
||||
return;
|
||||
}
|
||||
// Change size of the prev (recently allocated) block.
|
||||
setSizeHeader(start_ptr, requested);
|
||||
((Header *)start_ptr)->has_next = true;
|
||||
|
||||
// Add a header for newly created block (right block).
|
||||
Header header = {block_size, FREE, true, ((Header *)start_ptr)->has_next};
|
||||
Header *new_block_header = (Header *)new_block_ptr;
|
||||
*new_block_header = header;
|
||||
Footer footer = {block_size, FREE};
|
||||
*((Footer *)getFooter(new_block_header)) = footer;
|
||||
append_to_free_list (heap, new_block_header);
|
||||
}
|
||||
|
||||
static void *sdb_heap_malloc(SdbHeap *heap, int size) {
|
||||
if (size <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
// Size of the block can't be smaller than MIN_SIZE, as we need to store
|
||||
// free list in the body + header and footer on each side respectively.
|
||||
int required_size = MAX (ALIGN (size + META_SIZE), MIN_SIZE);
|
||||
// Try to find a block big enough in already allocated memory.
|
||||
free_list *free_block = find_free_block (heap, required_size);
|
||||
|
||||
if (free_block) {
|
||||
// Header ptr
|
||||
void *address = remove_offset (free_block);
|
||||
// Mark block as used.
|
||||
setFree(address, USED);
|
||||
// Split the block into two, where the second is free.
|
||||
split (heap, address, ((Header *)address)->size, required_size);
|
||||
remove_from_free_list (heap, address);
|
||||
return add_offset (address);
|
||||
}
|
||||
|
||||
// No free block was found. Allocate size requested + header (in full pages).
|
||||
// Each next allocation will be doubled in size from the previous one
|
||||
// (to decrease the number of mmap sys calls we make).
|
||||
// int bytes = MAX (PAGES (required_size), heap->last_mapped_size) * PAGE_SIZE;
|
||||
size_t bytes = PAGES(MAX (PAGES (required_size), heap->last_mapped_size)) * PAGE_SIZE;
|
||||
heap->last_mapped_size *= 2;
|
||||
|
||||
// last_address my not be returned by mmap, but makes it more efficient if it happens.
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS 0
|
||||
#endif
|
||||
void *new_region = mmap (heap->last_address, bytes, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
if (new_region == MAP_FAILED) {
|
||||
perror ("mmap");
|
||||
return NULL;
|
||||
}
|
||||
// Create a header/footer for new block.
|
||||
Header header = {(int)bytes, USED, false, false};
|
||||
Header *header_ptr = (Header *)new_region;
|
||||
*header_ptr = header;
|
||||
Footer footer = {};
|
||||
footer.free = USED;
|
||||
*((Footer *)getFooter(new_region)) = footer;
|
||||
|
||||
if (new_region == heap->last_address && heap->last_address != 0) {
|
||||
// if we got a block of memory after the last block, as we requested.
|
||||
header_ptr->has_prev = true;
|
||||
// change has_next of the prev block
|
||||
Footer *prev_footer = (Footer *)(header_ptr - FOOTER_SIZE);
|
||||
((Header *)header_ptr - (prev_footer->size))->has_next = true;
|
||||
}
|
||||
// Split new region.
|
||||
split (heap, new_region, bytes, required_size);
|
||||
// Update last_address for the next allocation.
|
||||
heap->last_address = (int*)((ut8*)new_region + bytes);
|
||||
// Return address behind the header (i.e. header is hidden).
|
||||
return add_offset (new_region);
|
||||
}
|
||||
|
||||
static void coalesce(SdbHeap *heap, void *ptr) {
|
||||
Header *current_header = (Header *)ptr;
|
||||
Footer *current_footer = (Footer *)getFooter(ptr);
|
||||
if (current_header->has_prev && ((Footer *)((ut8*)ptr - FOOTER_SIZE))->free) {
|
||||
int prev_size = ((Footer *)((ut8*)ptr - FOOTER_SIZE))->size;
|
||||
Header *prev_header = (Header *)((ut8*)ptr - prev_size);
|
||||
Footer *prev_footer = (Footer *)((Footer *)((ut8*)ptr - FOOTER_SIZE));
|
||||
|
||||
// Merge with previous block.
|
||||
remove_from_free_list (heap, current_header);
|
||||
// Add size of prev block to the size of current block
|
||||
prev_header->size += current_header->size;
|
||||
prev_footer->size = prev_header->size;
|
||||
current_header = prev_header;
|
||||
}
|
||||
void *next = (void*)((ut8*)ptr + current_header->size);
|
||||
if (current_header->has_next && ((Header *)next)->free) {
|
||||
int size = ((Header *)next)->size;
|
||||
// merge with next block.
|
||||
remove_from_free_list (heap, (ut8*)ptr + current_header->size);
|
||||
// Add size of next block to the size of current block.
|
||||
current_header->size += size;
|
||||
current_footer->size = current_header->size;
|
||||
}
|
||||
}
|
||||
|
||||
static int unmap(SdbHeap *heap, void *start_address, int size) {
|
||||
remove_from_free_list (heap, start_address);
|
||||
// Reset has_next, has_prev of neighbours.
|
||||
Header *header = (Header *)start_address;
|
||||
if (header->has_prev) {
|
||||
// Get prev header, set has_next to false.
|
||||
int prev_size = ((Footer *)((ut8*)start_address - FOOTER_SIZE))->size;
|
||||
Header *prev_header = (Header *)((ut8*)start_address - prev_size);
|
||||
prev_header->has_next = false;
|
||||
}
|
||||
if (header->has_next) {
|
||||
// Get next header, set has_prev to false.
|
||||
int this_size = header->size;
|
||||
Header *next_header = (Header *)((ut8*)start_address + this_size);
|
||||
next_header->has_prev = false;
|
||||
}
|
||||
|
||||
// If this is the last block we've allocated using mmap, need to change last_address.
|
||||
if (heap->last_address == start_address) {
|
||||
heap->last_address = (int *)((ut8*)start_address - size);
|
||||
}
|
||||
return munmap (start_address, (size_t)size);
|
||||
}
|
||||
|
||||
static void sdb_heap_free(SdbHeap *heap, void *ptr) {
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
void *start_address = remove_offset (ptr);
|
||||
|
||||
// Check if it has already been freed.
|
||||
// Does not handle case when start_address passed was never allocated.
|
||||
if (((Header *)start_address)->free) {
|
||||
return;
|
||||
}
|
||||
|
||||
Header *header = (Header *)start_address;
|
||||
int size = header->size;
|
||||
uintptr_t addr = (uintptr_t)header;
|
||||
if (size % PAGE_SIZE == 0 && addr % PAGE_SIZE == 0) {
|
||||
// if: full page is free (or multiple consecutive pages), page-aligned -> can munmap it.
|
||||
unmap (heap, start_address, size);
|
||||
} else {
|
||||
append_to_free_list (heap, start_address);
|
||||
coalesce (heap, start_address);
|
||||
// if we are left with a free block of size bigger than PAGE_SIZE that is
|
||||
// page-aligned, munmap that part.
|
||||
if (size >= PAGE_SIZE && addr % PAGE_SIZE == 0) {
|
||||
split (heap, start_address, size, (size / PAGE_SIZE) * PAGE_SIZE);
|
||||
unmap (heap, start_address, (size / PAGE_SIZE) * PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void copy_block(int *src, int *dst, int size) {
|
||||
// bettter do memcpy here
|
||||
int i;
|
||||
// Know that it is 8-bit aligned, so can copy whole ints.
|
||||
for (i = 0; i * sizeof(int) < size; i++) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SDB_API void sdb_heap_init(SdbHeap *heap) {
|
||||
heap->last_address = NULL;
|
||||
heap->free_list_start = NULL;
|
||||
heap->last_mapped_size = 1;
|
||||
}
|
||||
|
||||
SDB_API void sdb_heap_fini(SdbHeap *heap) {
|
||||
#if 1
|
||||
free_list *current = heap->free_list_start;
|
||||
while (current) {
|
||||
free_list *next = current->next;
|
||||
sdb_heap_free (heap, current);
|
||||
current = next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SDB_API void *sdb_heap_realloc(SdbHeap *heap, void *ptr, int size) {
|
||||
// If ptr is NULL, realloc() is identical to a call to malloc() for size bytes.
|
||||
if (!ptr) {
|
||||
return sdb_heap_malloc (heap, size);
|
||||
}
|
||||
// If size is zero and ptr is not NULL, a new, minimum sized object (MIN_SIZE) is
|
||||
// allocated and the original object is freed.
|
||||
if (size == 0 && ptr) {
|
||||
sdb_heap_free (heap, ptr);
|
||||
return sdb_heap_malloc (heap, 1);
|
||||
}
|
||||
|
||||
int required_size = META_SIZE + size;
|
||||
// If there is enough space, expand the block.
|
||||
int current_size = getSize (ptr);
|
||||
|
||||
// if user requests to shorten the block.
|
||||
if (size < current_size) {
|
||||
return ptr;
|
||||
}
|
||||
Header *current_header = (Header *)ptr;
|
||||
Footer *current_footer = (Footer *)getFooter(ptr);
|
||||
// Next block exists and is free.
|
||||
if (current_header->has_next && ((Header *)ptr + current_size)->free) {
|
||||
int available_size = current_size + getSize ((ut8*)ptr + current_size);
|
||||
// Size is enough.
|
||||
if (available_size >= required_size) {
|
||||
Header *next_header = (Header *)((ut8*)ptr + current_size);
|
||||
remove_from_free_list (heap, next_header);
|
||||
// Add size of next block to the size of current block.
|
||||
current_header->size += size;
|
||||
current_footer->size = current_header->size;
|
||||
|
||||
// split if possible.
|
||||
split (heap, current_header, available_size, required_size);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Not enough room to enlarge -> allocate new region.
|
||||
void *new_ptr = sdb_heap_malloc (heap, size);
|
||||
// Copy old data.
|
||||
// copy_block(ptr, new_ptr, current_size);
|
||||
memcpy (ptr, new_ptr, current_size);
|
||||
|
||||
// Free old location.
|
||||
sdb_heap_free (heap, ptr);
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
#endif
|
@ -3,12 +3,12 @@
|
||||
#include "sdb/ht.h"
|
||||
|
||||
void sdbkv_fini(SdbKv *kv) {
|
||||
free (kv->base.key);
|
||||
free (kv->base.value);
|
||||
sdb_gh_free (kv->base.key);
|
||||
sdb_gh_free (kv->base.value);
|
||||
}
|
||||
|
||||
SDB_API HtPP* sdb_ht_new(void) {
|
||||
HtPP *ht = ht_pp_new ((HtPPDupValue)strdup, (HtPPKvFreeFunc)sdbkv_fini, (HtPPCalcSizeV)strlen);
|
||||
HtPP *ht = ht_pp_new ((HtPPDupValue)sdb_strdup, (HtPPKvFreeFunc)sdbkv_fini, (HtPPCalcSizeV)strlen);
|
||||
if (ht) {
|
||||
ht->opt.elem_size = sizeof (SdbKv);
|
||||
}
|
||||
@ -20,11 +20,11 @@ static bool sdb_ht_internal_insert(HtPP* ht, const char* key, const char* value,
|
||||
return false;
|
||||
}
|
||||
SdbKv kvp = {{ 0 }};
|
||||
kvp.base.key = strdup (key);
|
||||
kvp.base.key = sdb_strdup (key);
|
||||
if (!kvp.base.key) {
|
||||
goto err;
|
||||
}
|
||||
kvp.base.value = strdup (value);
|
||||
kvp.base.value = sdb_strdup (value);
|
||||
if (!kvp.base.value) {
|
||||
goto err;
|
||||
}
|
||||
@ -34,8 +34,8 @@ static bool sdb_ht_internal_insert(HtPP* ht, const char* key, const char* value,
|
||||
return ht_pp_insert_kv (ht, (HtPPKv*)&kvp, update);
|
||||
|
||||
err:
|
||||
free (kvp.base.key);
|
||||
free (kvp.base.value);
|
||||
sdb_gh_free (kvp.base.key);
|
||||
sdb_gh_free (kvp.base.value);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -94,19 +94,19 @@ static inline HT_(Kv) *next_kv(HtName_(Ht) *ht, HT_(Kv) *kv) {
|
||||
// hashfunction - the function that does the hashing, must not be null.
|
||||
// comparator - the function to check if values are equal, if NULL, just checks
|
||||
// == (for storing ints).
|
||||
// keydup - function to duplicate to key (eg strdup), if NULL just does strup.
|
||||
// keydup - function to duplicate to key (eg sdb_strdup), if NULL just does strup.
|
||||
// valdup - same as keydup, but for values but if NULL just assign
|
||||
// pair_free - function for freeing a keyvaluepair - if NULL just does free.
|
||||
// calcsize - function to calculate the size of a value. if NULL, just stores 0.
|
||||
static HtName_(Ht)* internal_ht_new(ut32 size, ut32 prime_idx, HT_(Options) *opt) {
|
||||
HtName_(Ht)* ht = (HtName_(Ht)*)calloc (1, sizeof (*ht));
|
||||
HtName_(Ht)* ht = (HtName_(Ht)*)sdb_gh_calloc (1, sizeof (*ht));
|
||||
if (SDB_LIKELY (ht)) {
|
||||
ht->size = size;
|
||||
ht->count = 0;
|
||||
ht->prime_idx = prime_idx;
|
||||
ht->table = (HT_(Bucket)*)calloc (ht->size, sizeof (*ht->table));
|
||||
ht->table = (HT_(Bucket)*)sdb_gh_calloc (ht->size, sizeof (*ht->table));
|
||||
if (!ht->table) {
|
||||
free (ht);
|
||||
sdb_gh_free (ht);
|
||||
return NULL;
|
||||
}
|
||||
ht->opt = *opt;
|
||||
@ -136,10 +136,10 @@ SDB_API void Ht_(free)(HtName_(Ht)* ht) {
|
||||
ht->opt.freefn (kv);
|
||||
}
|
||||
}
|
||||
free (bt->arr);
|
||||
sdb_gh_free (bt->arr);
|
||||
}
|
||||
free (ht->table);
|
||||
free (ht);
|
||||
sdb_gh_free (ht->table);
|
||||
sdb_gh_free (ht);
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,7 +199,7 @@ static HT_(Kv) *reserve_kv(HtName_(Ht) *ht, const KEY_TYPE key, const int key_le
|
||||
|
||||
if (bt->count + 1 >= bt->size) {
|
||||
bt->size = (bt->count + 5) * 2;
|
||||
HT_(Kv) *newkvarr = (HT_(Kv)*)realloc (bt->arr, (bt->size) * ht->opt.elem_size);
|
||||
HT_(Kv) *newkvarr = (HT_(Kv)*)sdb_gh_realloc (bt->arr, (bt->size) * ht->opt.elem_size);
|
||||
if (SDB_LIKELY (newkvarr)) {
|
||||
bt->arr = newkvarr;
|
||||
} else {
|
||||
|
@ -8,7 +8,7 @@ static HtName_(Ht)* internal_ht_default_new(ut32 size, ut32 prime_idx, HT_(DupVa
|
||||
HT_(Options) opt = {
|
||||
.cmp = (HT_(ListComparator))strcmp,
|
||||
.hashfn = (HT_(HashFunction))sdb_hash,
|
||||
.dupkey = (HT_(DupKey))strdup,
|
||||
.dupkey = (HT_(DupKey))sdb_strdup,
|
||||
.dupvalue = valdup,
|
||||
.calcsizeK = (HT_(CalcSizeK))strlen,
|
||||
.calcsizeV = calcsizeV,
|
||||
@ -24,7 +24,7 @@ SDB_API HtName_(Ht)* Ht_(new)(HT_(DupValue) valdup, HT_(KvFreeFunc) pair_free, H
|
||||
}
|
||||
|
||||
static void free_kv_key(HT_(Kv) *kv) {
|
||||
free (kv->key);
|
||||
sdb_gh_free (kv->key);
|
||||
}
|
||||
|
||||
// creates a default HtPP that has strings as keys but does not dup, nor free the values
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "ht.inc"
|
||||
|
||||
static void free_kv_key(HT_(Kv) *kv) {
|
||||
free (kv->key);
|
||||
sdb_gh_free (kv->key);
|
||||
}
|
||||
|
||||
// creates a default HtPU that has strings as keys
|
||||
@ -13,7 +13,7 @@ SDB_API HtName_(Ht)* Ht_(new0)(void) {
|
||||
HT_(Options) opt = {
|
||||
.cmp = (HT_(ListComparator))strcmp,
|
||||
.hashfn = (HT_(HashFunction))sdb_hash,
|
||||
.dupkey = (HT_(DupKey))strdup,
|
||||
.dupkey = (HT_(DupKey))sdb_strdup,
|
||||
.dupvalue = NULL,
|
||||
.calcsizeK = (HT_(CalcSizeK))strlen,
|
||||
.calcsizeV = NULL,
|
||||
|
@ -62,13 +62,13 @@ SDB_API int sdb_journal_load(Sdb *s) {
|
||||
return 0;
|
||||
}
|
||||
lseek (fd, 0, SEEK_SET);
|
||||
str = (char *)malloc (sz + 1);
|
||||
str = (char *)sdb_gh_malloc (sz + 1);
|
||||
if (!str) {
|
||||
return 0;
|
||||
}
|
||||
rr = read (fd, str, sz);
|
||||
if (rr < 0) {
|
||||
free (str);
|
||||
sdb_gh_free (str);
|
||||
return 0;
|
||||
}
|
||||
str[sz] = 0;
|
||||
@ -86,7 +86,7 @@ SDB_API int sdb_journal_load(Sdb *s) {
|
||||
}
|
||||
cur = ptr + 1;
|
||||
}
|
||||
free (str);
|
||||
sdb_gh_free (str);
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ SDB_API char *sdb_json_get(Sdb *s, const char *k, const char *p, ut32 *cas) {
|
||||
}
|
||||
rs = json_get (v, p);
|
||||
u = rangstr_dup (&rs);
|
||||
free (v);
|
||||
sdb_gh_free (v);
|
||||
return u;
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ SDB_API int sdb_json_num_get(Sdb *s, const char *k, const char *p, ut32 *cas) {
|
||||
if (v) {
|
||||
Rangstr rs = json_get (v, p);
|
||||
int ret = rangstr_int (&rs);
|
||||
free (v);
|
||||
sdb_gh_free (v);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
@ -121,7 +121,7 @@ SDB_API bool sdb_json_set(Sdb *s, const char *k, const char *p, const char *v, u
|
||||
if (!js) {
|
||||
const int v_len = strlen (v);
|
||||
const int p_len = strlen (p);
|
||||
b = (char *)malloc (p_len + v_len + 8);
|
||||
b = (char *)sdb_gh_malloc (p_len + v_len + 8);
|
||||
if (b) {
|
||||
int is_str = isstring (v);
|
||||
const char *q = is_str? "\"": "";
|
||||
@ -131,7 +131,7 @@ SDB_API bool sdb_json_set(Sdb *s, const char *k, const char *p, const char *v, u
|
||||
sdb_set_owned (s, k, b, cas);
|
||||
#else
|
||||
sdb_set (s, k, b, cas);
|
||||
free (b);
|
||||
sdb_gh_free (b);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@ -147,7 +147,7 @@ SDB_API bool sdb_json_set(Sdb *s, const char *k, const char *p, const char *v, u
|
||||
// ensured to be positive by sdb_const_get_len
|
||||
// 7 corresponds to the length of '{"":"",'
|
||||
size_t buf_len = jslen + strlen (p) + strlen (v) + 7;
|
||||
char *buf = (char *)malloc (buf_len);
|
||||
char *buf = (char *)sdb_gh_malloc (buf_len);
|
||||
if (buf) {
|
||||
int curlen, is_str = isstring (v);
|
||||
const char *quote = is_str ? "\"" : "";
|
||||
@ -189,7 +189,7 @@ SDB_API bool sdb_json_set(Sdb *s, const char *k, const char *p, const char *v, u
|
||||
if (msz < 1) {
|
||||
return false;
|
||||
}
|
||||
str = (char *)malloc (msz);
|
||||
str = (char *)sdb_gh_malloc (msz);
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
@ -243,7 +243,7 @@ SDB_API bool sdb_json_set(Sdb *s, const char *k, const char *p, const char *v, u
|
||||
len[2]--;
|
||||
}
|
||||
|
||||
str = (char *)malloc (len[0] + len[2] + 1);
|
||||
str = (char *)sdb_gh_malloc (len[0] + len[2] + 1);
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
@ -265,7 +265,7 @@ SDB_API const char *sdb_json_format(SdbJsonString *s, const char *fmt, ...) {
|
||||
#define JSONSTR_ALLOCATE(y)\
|
||||
if (s->len + y > s->blen) {\
|
||||
s->blen *= 2;\
|
||||
x = (char *)realloc (s->buf, s->blen);\
|
||||
x = (char *)sdb_gh_realloc (s->buf, s->blen);\
|
||||
if (!x) {\
|
||||
va_end (ap);\
|
||||
return NULL;\
|
||||
@ -277,7 +277,7 @@ SDB_API const char *sdb_json_format(SdbJsonString *s, const char *fmt, ...) {
|
||||
}
|
||||
if (!s->buf) {
|
||||
s->blen = 1024;
|
||||
s->buf = (char *)malloc (s->blen);
|
||||
s->buf = (char *)sdb_gh_malloc (s->blen);
|
||||
if (!s->buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ char *api_json_set (const char *s, const char *k, const char *v) {
|
||||
end[2] = s + strlen (s);
|
||||
len[2] = WLEN (2);
|
||||
|
||||
str = (char *)malloc (len[0]+len[1]+len[2]+1);
|
||||
str = (char *)sdb_gh_malloc (len[0]+len[1]+len[2]+1);
|
||||
if (!str) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ SDB_API char *sdb_json_indent(const char *s, const char *tab) {
|
||||
o_size += 2;
|
||||
indent = 0;
|
||||
|
||||
O = (char *)malloc (o_size + 1);
|
||||
O = (char *)sdb_gh_malloc (o_size + 1);
|
||||
if (!O) {
|
||||
return NULL;
|
||||
}
|
||||
@ -110,7 +110,7 @@ SDB_API char *sdb_json_indent(const char *s, const char *tab) {
|
||||
SDB_API char *sdb_json_unindent(const char *s) {
|
||||
int instr = 0;
|
||||
int len = strlen (s);
|
||||
char *o, *O = (char *)malloc (len + 1);
|
||||
char *o, *O = (char *)sdb_gh_malloc (len + 1);
|
||||
if (!O) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ int test_glossary(char *buf) {
|
||||
char *s= api_json_set (buf, path, "patata");
|
||||
if (s) {
|
||||
printf ("%s\n", s);
|
||||
free (s);
|
||||
sdb_gh_free (s);
|
||||
} else printf ("set failed\n");
|
||||
}
|
||||
{
|
||||
@ -38,7 +38,7 @@ int test_glossary(char *buf) {
|
||||
char *s= api_json_get (buf, path);
|
||||
if (s) {
|
||||
printf ("%s\n", s);
|
||||
free (s);
|
||||
sdb_gh_free (s);
|
||||
} else printf ("set failed\n");
|
||||
}
|
||||
{
|
||||
@ -46,7 +46,7 @@ int test_glossary(char *buf) {
|
||||
char *s= api_json_get (buf, path);
|
||||
if (s) {
|
||||
printf ("%s\n", s);
|
||||
free (s);
|
||||
sdb_gh_free (s);
|
||||
} else printf ("set failed\n");
|
||||
}
|
||||
return 0;
|
||||
@ -69,7 +69,7 @@ int main(int argc, char **argv) {
|
||||
char *s = api_json_set (buf, path, "patata");
|
||||
if (s) {
|
||||
printf ("%s\n", s);
|
||||
free (s);
|
||||
sdb_gh_free (s);
|
||||
} else printf ("set failed\n");
|
||||
#endif
|
||||
//printf ("%s\n", str); return 0;
|
||||
|
@ -69,7 +69,7 @@ int json_foreach(const char *s, JSONCallback cb UNUSED) {
|
||||
int i, len, ret;
|
||||
unsigned short *res = NULL;
|
||||
len = strlen (s);
|
||||
res = malloc (len);
|
||||
res = sdb_gh_malloc (len);
|
||||
ret = sdb_js0n ((const unsigned char *)s, len, res);
|
||||
if (!ret) return 0;
|
||||
if (*s=='[') {
|
||||
@ -90,10 +90,10 @@ int json_foreach(const char *s, JSONCallback cb UNUSED) {
|
||||
SDB_IPI int json_walk (const char *s) {
|
||||
RangstrType *res;
|
||||
int i, ret, len = strlen (s);
|
||||
res = malloc (len+1);
|
||||
res = sdb_gh_malloc (len+1);
|
||||
ret = sdb_js0n ((const unsigned char *)s, len, res);
|
||||
if (!ret) {
|
||||
free (res);
|
||||
sdb_gh_free (res);
|
||||
return 0;
|
||||
}
|
||||
if (*s=='[' || *s=='{') {
|
||||
@ -106,7 +106,7 @@ SDB_IPI int json_walk (const char *s) {
|
||||
printf ("%.*s\n", res[i+3], s+res[i+2]);
|
||||
}
|
||||
}
|
||||
free (res);
|
||||
sdb_gh_free (res);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@ -124,7 +124,7 @@ SDB_IPI Rangstr json_find (const char *s, Rangstr *rs) {
|
||||
|
||||
len = strlen (s);
|
||||
if (len > RESFIXSZ) {
|
||||
res = (RangstrType *)calloc (len + 1, sizeof (RangstrType));
|
||||
res = (RangstrType *)sdb_gh_calloc (len + 1, sizeof (RangstrType));
|
||||
if (!res) {
|
||||
// eprintf ("Cannot allocate %d byte%s\n", len + 1, (len > 1)? "s": "");
|
||||
return rangstr_null ();
|
||||
@ -132,7 +132,7 @@ SDB_IPI Rangstr json_find (const char *s, Rangstr *rs) {
|
||||
}
|
||||
|
||||
ret = sdb_js0n ((const unsigned char *)s, len, res);
|
||||
#define PFREE(x) if (x && x != resfix) free (x)
|
||||
#define PFREE(x) if (x && x != resfix) sdb_gh_free (x)
|
||||
if (ret > 0) {
|
||||
PFREE (res);
|
||||
return rangstr_null ();
|
||||
|
@ -66,7 +66,7 @@ SDB_IPI char *rangstr_dup(Rangstr *rs) {
|
||||
return NULL;
|
||||
}
|
||||
int len = rangstr_length (rs);
|
||||
char *p = (char *)malloc (len + 1);
|
||||
char *p = (char *)sdb_gh_malloc (len + 1);
|
||||
if (p) {
|
||||
memcpy (p, rs->p + rs->f, len);
|
||||
p[len] = 0;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "sdb/ls.h"
|
||||
#include "sdb/heap.h"
|
||||
|
||||
#if 0
|
||||
1 128= 7s / 32
|
||||
@ -154,7 +155,7 @@ SDB_API void ls_delete(SdbList *list, SdbListIter *iter) {
|
||||
list->free (iter->data);
|
||||
iter->data = NULL;
|
||||
}
|
||||
free (iter);
|
||||
sdb_gh_free (iter);
|
||||
}
|
||||
|
||||
SDB_API bool ls_delete_data(SdbList *list, void *ptr) {
|
||||
@ -209,7 +210,7 @@ SDB_API void ls_free(SdbList *list) {
|
||||
}
|
||||
ls_destroy (list);
|
||||
list->free = NULL;
|
||||
free (list);
|
||||
sdb_gh_free (list);
|
||||
}
|
||||
|
||||
SDB_API SdbListIter *ls_append(SdbList *list, void *data) {
|
||||
@ -269,7 +270,7 @@ SDB_API void *ls_pop(SdbList *list) {
|
||||
list->tail->n = NULL;
|
||||
}
|
||||
data = iter->data;
|
||||
free (iter);
|
||||
sdb_gh_free (iter);
|
||||
list->length--;
|
||||
}
|
||||
return data;
|
||||
@ -359,7 +360,7 @@ SDB_API void *ls_pop_head(SdbList *list) {
|
||||
list->head->p = NULL;
|
||||
}
|
||||
data = iter->data;
|
||||
free (iter);
|
||||
sdb_gh_free (iter);
|
||||
}
|
||||
list->length--;
|
||||
return data;
|
||||
@ -388,7 +389,7 @@ SDB_API int ls_del_n(SdbList *list, int n) {
|
||||
it->p->n = it->n;
|
||||
it->n->p = it->p;
|
||||
}
|
||||
free (it);
|
||||
sdb_gh_free (it);
|
||||
list->length--;
|
||||
return true;
|
||||
}
|
||||
|
@ -5,11 +5,16 @@
|
||||
#ifndef HAVE_SYSTEM
|
||||
#define HAVE_SYSTEM 1
|
||||
#endif
|
||||
#include <sdb/sdb.h>
|
||||
#if USE_DLSYSTEM
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#include "sdb/sdb.h"
|
||||
|
||||
#if __SDB_WINDOWS__
|
||||
#define ftruncate _chsize
|
||||
#endif
|
||||
|
||||
// TODO: enums must be uppercase
|
||||
typedef enum {
|
||||
text,
|
||||
zero,
|
||||
@ -19,6 +24,7 @@ typedef enum {
|
||||
perf
|
||||
} MainFormat;
|
||||
|
||||
// TODO: enums must be uppercase
|
||||
typedef enum {
|
||||
nope = 0,
|
||||
dash,
|
||||
@ -55,7 +61,8 @@ static void terminate(int sig UNUSED) {
|
||||
s = NULL;
|
||||
exit (1);
|
||||
}
|
||||
sdb_free (s);
|
||||
sdb_gh_fini ();
|
||||
//sdb_free (s);
|
||||
exit (sig < 2? sig: 0);
|
||||
}
|
||||
|
||||
@ -84,17 +91,17 @@ static char *slurp(FILE *f, size_t *sz) {
|
||||
/* run test/add10k.sh script to benchmark */
|
||||
const int buf_size = 96096;
|
||||
|
||||
buf = (char *)calloc (1, buf_size);
|
||||
buf = (char *)sdb_gh_calloc (1, buf_size);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!fgets (buf, buf_size, f)) {
|
||||
free (buf);
|
||||
sdb_gh_free (buf);
|
||||
return NULL;
|
||||
}
|
||||
if (feof (f)) {
|
||||
free (buf);
|
||||
sdb_gh_free (buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -103,15 +110,11 @@ static char *slurp(FILE *f, size_t *sz) {
|
||||
buf[buf_len - 1] = '\0';
|
||||
}
|
||||
|
||||
char *newbuf = (char *)realloc (buf, buf_len + 1);
|
||||
// realloc behaves like free if buf_len is 0
|
||||
if (!newbuf) {
|
||||
return buf;
|
||||
}
|
||||
return newbuf;
|
||||
char *newbuf = (char *)sdb_gh_realloc (buf, buf_len + 1);
|
||||
return newbuf? newbuf: buf;
|
||||
}
|
||||
#endif
|
||||
buf = (char *)calloc (BS + 1, 1);
|
||||
buf = (char *)sdb_gh_calloc (BS + 1, 1);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
@ -119,7 +122,7 @@ static char *slurp(FILE *f, size_t *sz) {
|
||||
len = 0;
|
||||
for (;;) {
|
||||
if (next) {
|
||||
free (buf);
|
||||
sdb_gh_free (buf);
|
||||
buf = next;
|
||||
bufsize = nextlen + blocksize;
|
||||
//len = nextlen;
|
||||
@ -149,7 +152,7 @@ static char *slurp(FILE *f, size_t *sz) {
|
||||
int nlen = nl - buf;
|
||||
nextlen = len - nlen;
|
||||
if (nextlen > 0) {
|
||||
next = (char *)malloc (nextlen + blocksize + 1);
|
||||
next = (char *)sdb_gh_malloc (nextlen + blocksize + 1);
|
||||
if (!next) {
|
||||
eprintf ("Cannot malloc %d\n", nextlen);
|
||||
break;
|
||||
@ -169,7 +172,7 @@ static char *slurp(FILE *f, size_t *sz) {
|
||||
}
|
||||
#endif
|
||||
bufsize += blocksize;
|
||||
tmp = (char *)realloc (buf, bufsize + 1);
|
||||
tmp = (char *)sdb_gh_realloc (buf, bufsize + 1);
|
||||
if (!tmp) {
|
||||
bufsize -= blocksize;
|
||||
break;
|
||||
@ -181,7 +184,7 @@ static char *slurp(FILE *f, size_t *sz) {
|
||||
*sz = len;
|
||||
}
|
||||
if (len < 1) {
|
||||
free (buf);
|
||||
sdb_gh_free (buf);
|
||||
return buf = NULL;
|
||||
}
|
||||
buf[len] = 0;
|
||||
@ -213,7 +216,7 @@ static char* get_name(const char*name) {
|
||||
}
|
||||
l--;
|
||||
}
|
||||
char *n = strdup (name);
|
||||
char *n = sdb_strdup (name);
|
||||
char *v, *d = n;
|
||||
for (v = (char*)n; *v; v++) {
|
||||
if (*v == '.') {
|
||||
@ -237,7 +240,7 @@ static char* get_cname(const char*name) {
|
||||
}
|
||||
l--;
|
||||
}
|
||||
char *n = strdup (name);
|
||||
char *n = sdb_strdup (name);
|
||||
char *v, *d = n;
|
||||
for (v = (char*)n; *v; v++) {
|
||||
if (*v == '/' || *v == '-') {
|
||||
@ -254,7 +257,7 @@ static char* get_cname(const char*name) {
|
||||
}
|
||||
|
||||
static char *escape(const char *b, int ch) {
|
||||
char *a = (char *)calloc ((1 + strlen (b)), 4);
|
||||
char *a = (char *)sdb_gh_calloc ((1 + strlen (b)), 4);
|
||||
char *c = a;
|
||||
while (*b) {
|
||||
if (*b == ch) {
|
||||
@ -310,8 +313,8 @@ static void sdb_dump_cb(MainOptions *mo, const char *k, const char *v, const cha
|
||||
} else {
|
||||
printf ("%s,\"%s\"\n", a, b);
|
||||
}
|
||||
free (a);
|
||||
free (b);
|
||||
sdb_gh_free (a);
|
||||
sdb_gh_free (b);
|
||||
}
|
||||
break;
|
||||
case zero:
|
||||
@ -433,7 +436,7 @@ static void cgen_footer(MainOptions *mo, const char *name, const char *cname) {
|
||||
" char *comma = strchr (line, ',');\n"
|
||||
" if (comma) {\n"
|
||||
" *comma = 0;\n"
|
||||
" char *up = strdup (line);\n"
|
||||
" char *up = sdb_strdup (line);\n"
|
||||
" char *p = up; while (*p) { *p = toupper (*p); p++; }\n"
|
||||
" printf (\"#define GPERF_%s_%%s %%d\\n\",\n"
|
||||
" line, sdb_hash_c_%s (line, comma - line));\n"
|
||||
@ -486,8 +489,8 @@ static int sdb_dump(MainOptions *mo) {
|
||||
if (!mo->textmode && mo->format == cgen && ls_length (l) > SDB_MAX_GPERF_KEYS) {
|
||||
ls_free (l);
|
||||
eprintf ("Error: gperf doesn't work with datasets with more than 15.000 keys.\n");
|
||||
free (name);
|
||||
free (cname);
|
||||
sdb_gh_free (name);
|
||||
sdb_gh_free (cname);
|
||||
return -1;
|
||||
}
|
||||
SdbKv *kv;
|
||||
@ -506,12 +509,12 @@ static int sdb_dump(MainOptions *mo) {
|
||||
int count = 0;
|
||||
while (sdb_dump_dupnext (db, k, &v, NULL)) {
|
||||
if (v && *v && grep && !strstr (k, expgrep) && !strstr (v, expgrep)) {
|
||||
free (v);
|
||||
sdb_gh_free (v);
|
||||
continue;
|
||||
}
|
||||
sdb_dump_cb (mo, k, v, comma);
|
||||
comma = ",";
|
||||
free (v);
|
||||
sdb_gh_free (v);
|
||||
if (!mo->textmode && mo->format == cgen && count++ > SDB_MAX_GPERF_KEYS) {
|
||||
eprintf ("Error: gperf doesn't work with datasets with more than 15.000 keys.\n");
|
||||
ret = -1;
|
||||
@ -535,9 +538,9 @@ static int sdb_dump(MainOptions *mo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
sdb_free (db);
|
||||
free (cname);
|
||||
free (name);
|
||||
// sdb_free (db);
|
||||
sdb_gh_free (cname);
|
||||
sdb_gh_free (name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -554,13 +557,13 @@ static int insertkeys(Sdb *db, const char **args, int nargs, int mode) {
|
||||
break;
|
||||
case '=':
|
||||
if (strchr (args[i], '=')) {
|
||||
char *v, *kv = (char *) strdup (args[i]);
|
||||
char *v, *kv = (char *) sdb_strdup (args[i]);
|
||||
v = strchr (kv, '=');
|
||||
if (v) {
|
||||
*v++ = 0;
|
||||
sdb_disk_insert (db, kv, v);
|
||||
}
|
||||
free (kv);
|
||||
sdb_gh_free (kv);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -593,7 +596,7 @@ static int createdb(const char *f, const char **args, int nargs) {
|
||||
if (!sdb_text_load_buf (s, in, len)) {
|
||||
eprintf ("Failed to read text sdb from stdin\n");
|
||||
}
|
||||
free (in);
|
||||
sdb_gh_free (in);
|
||||
}
|
||||
sdb_sync (s);
|
||||
return ret;
|
||||
@ -637,12 +640,12 @@ static int jsonIndent(void) {
|
||||
}
|
||||
out = sdb_json_indent (in, " ");
|
||||
if (!out) {
|
||||
free (in);
|
||||
sdb_gh_free (in);
|
||||
return 1;
|
||||
}
|
||||
puts (out);
|
||||
free (out);
|
||||
free (in);
|
||||
sdb_gh_free (out);
|
||||
sdb_gh_free (in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -655,12 +658,12 @@ static int base64encode(void) {
|
||||
}
|
||||
out = sdb_encode (in, (int)len);
|
||||
if (!out) {
|
||||
free (in);
|
||||
sdb_gh_free (in);
|
||||
return 1;
|
||||
}
|
||||
puts (out);
|
||||
free (out);
|
||||
free (in);
|
||||
sdb_gh_free (out);
|
||||
sdb_gh_free (in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -674,8 +677,8 @@ static int base64decode(void) {
|
||||
if (out && declen >= 0) {
|
||||
ret = (write (1, out, declen) == declen)? 0: 1;
|
||||
}
|
||||
free (out);
|
||||
free (in);
|
||||
sdb_gh_free (out);
|
||||
sdb_gh_free (in);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -689,7 +692,7 @@ static void dbdiff_cb(const SdbDiff *diff, void *user) {
|
||||
char *buf = sbuf;
|
||||
char *hbuf = NULL;
|
||||
if ((size_t)r >= sizeof (sbuf)) {
|
||||
hbuf = (char *)malloc (r + 1);
|
||||
hbuf = (char *)sdb_gh_malloc (r + 1);
|
||||
if (!hbuf) {
|
||||
return;
|
||||
}
|
||||
@ -700,7 +703,7 @@ static void dbdiff_cb(const SdbDiff *diff, void *user) {
|
||||
}
|
||||
printf ("\x1b[%sm%s\x1b[0m\n", diff->add ? "32" : "31", buf);
|
||||
beach:
|
||||
free (hbuf);
|
||||
sdb_gh_free (hbuf);
|
||||
}
|
||||
|
||||
static bool dbdiff(const char *a, const char *b) {
|
||||
@ -743,14 +746,14 @@ static int sdb_system(const char *cmd) {
|
||||
|
||||
static int gen_gperf(MainOptions *mo, const char *file, const char *name) {
|
||||
const size_t buf_size = 4096;
|
||||
char *buf = (char *)malloc (buf_size);
|
||||
char *buf = (char *)sdb_gh_malloc (buf_size);
|
||||
if (!buf) {
|
||||
return -1;
|
||||
}
|
||||
size_t out_size = strlen (file) + 32;
|
||||
char *out = (char *)malloc (out_size);
|
||||
char *out = (char *)sdb_gh_malloc (out_size);
|
||||
if (!out) {
|
||||
free (buf);
|
||||
sdb_gh_free (buf);
|
||||
return -1;
|
||||
}
|
||||
if (mo->outfile) {
|
||||
@ -763,8 +766,8 @@ static int gen_gperf(MainOptions *mo, const char *file, const char *name) {
|
||||
wd = open (out, O_RDWR | O_CREAT, 0644);
|
||||
} else {
|
||||
if (ftruncate (wd, 0) == -1) {
|
||||
free (out);
|
||||
free (buf);
|
||||
sdb_gh_free (out);
|
||||
sdb_gh_free (buf);
|
||||
close (wd);
|
||||
return -1;
|
||||
}
|
||||
@ -795,7 +798,7 @@ static int gen_gperf(MainOptions *mo, const char *file, const char *name) {
|
||||
}
|
||||
snprintf (buf, buf_size, "gperf -aclEDCIG --null-strings -H sdb_hash_c_%s"
|
||||
" -N sdb_get_c_%s -t %s.gperf > %s.c\n", cname, cname, name, name);
|
||||
free (cname);
|
||||
sdb_gh_free (cname);
|
||||
rc = sdb_system (buf);
|
||||
if (rc == 0) {
|
||||
snprintf (buf, buf_size, "gcc -DMAIN=1 %s.c ; ./a.out > %s.h\n", name, name);
|
||||
@ -810,8 +813,8 @@ static int gen_gperf(MainOptions *mo, const char *file, const char *name) {
|
||||
eprintf ("Outdated sdb binary in PATH?\n");
|
||||
}
|
||||
}
|
||||
free (out);
|
||||
free (buf);
|
||||
sdb_gh_free (out);
|
||||
sdb_gh_free (buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -947,7 +950,7 @@ static MainOptions *main_argparse(MainOptions *mo, int argc, const char **argv)
|
||||
return mo;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
SDB_API int sdb_main(int argc, const char **argv) {
|
||||
char *line;
|
||||
int i;
|
||||
|
||||
@ -955,7 +958,6 @@ int main(int argc, const char **argv) {
|
||||
if (argc < 2) {
|
||||
return showusage (1);
|
||||
}
|
||||
|
||||
MainOptions _mo = {0};
|
||||
MainOptions *mo = &_mo;
|
||||
main_argparse (mo, argc, argv);
|
||||
@ -977,13 +979,13 @@ int main(int argc, const char **argv) {
|
||||
return showusage (1);
|
||||
}
|
||||
const char *file = mo->argv[mo->db0];
|
||||
char *name = strdup (file);
|
||||
char *name = sdb_strdup (file);
|
||||
char *p = strchr (name, '.');
|
||||
if (p) {
|
||||
*p = 0;
|
||||
}
|
||||
int rc = gen_gperf (mo, file, name);
|
||||
free (name);
|
||||
sdb_gh_free (name);
|
||||
return rc;
|
||||
}
|
||||
default:
|
||||
@ -1033,9 +1035,11 @@ int main(int argc, const char **argv) {
|
||||
fflush (stdout);
|
||||
ret = write_null ();
|
||||
}
|
||||
free (line);
|
||||
sdb_gh_free (line);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eprintf ("Cannot create database\n");
|
||||
}
|
||||
break;
|
||||
case eqeq: // "="
|
||||
|
@ -79,7 +79,7 @@ static inline bool compareString(const char *a, const char *b, int blen, int fla
|
||||
else ret = strstr2 (a, b, blen);
|
||||
}
|
||||
}
|
||||
free (aa);
|
||||
sdb_gh_free (aa);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -99,29 +99,29 @@ static SdbNs *sdb_ns_new (Sdb *s, const char *name, ut32 hash) {
|
||||
} else {
|
||||
dir[0] = 0;
|
||||
}
|
||||
ns = (SdbNs *)malloc (sizeof (SdbNs));
|
||||
ns = (SdbNs *)sdb_gh_malloc (sizeof (SdbNs));
|
||||
if (!ns) {
|
||||
return NULL;
|
||||
}
|
||||
ns->hash = hash;
|
||||
ns->name = name? strdup (name): NULL;
|
||||
ns->name = name? sdb_strdup (name): NULL;
|
||||
//ns->sdb = sdb_new (dir, ns->name, 0);
|
||||
ns->sdb = sdb_new0 ();
|
||||
// TODO: generate path
|
||||
|
||||
if (ns->sdb) {
|
||||
free (ns->sdb->path);
|
||||
sdb_gh_free (ns->sdb->path);
|
||||
ns->sdb->path = NULL;
|
||||
if (*dir) {
|
||||
ns->sdb->path = strdup (dir);
|
||||
ns->sdb->path = sdb_strdup (dir);
|
||||
}
|
||||
free (ns->sdb->name);
|
||||
sdb_gh_free (ns->sdb->name);
|
||||
if (name && *name) {
|
||||
ns->sdb->name = strdup (name);
|
||||
ns->sdb->name = sdb_strdup (name);
|
||||
}
|
||||
} else {
|
||||
free (ns->name);
|
||||
free (ns);
|
||||
sdb_gh_free (ns->name);
|
||||
sdb_gh_free (ns);
|
||||
ns = NULL;
|
||||
}
|
||||
return ns;
|
||||
@ -170,9 +170,9 @@ SDB_API int sdb_ns_set(Sdb *s, const char *name, Sdb *r) {
|
||||
if (!ns) {
|
||||
return 0;
|
||||
}
|
||||
ns->name = strdup (name);
|
||||
ns->name = sdb_strdup (name);
|
||||
if (!ns->name) {
|
||||
free (ns);
|
||||
sdb_gh_free (ns);
|
||||
return 0;
|
||||
}
|
||||
ns->hash = hash;
|
||||
@ -216,7 +216,7 @@ SDB_API Sdb *sdb_ns_path(Sdb *s, const char *path, int create) {
|
||||
if (!s || !path || !*path) {
|
||||
return s;
|
||||
}
|
||||
ptr = str = strdup (path);
|
||||
ptr = str = sdb_strdup (path);
|
||||
do {
|
||||
slash = strchr (ptr, '/');
|
||||
if (slash)
|
||||
@ -226,7 +226,7 @@ SDB_API Sdb *sdb_ns_path(Sdb *s, const char *path, int create) {
|
||||
if (slash)
|
||||
ptr = slash+1;
|
||||
} while (slash);
|
||||
free (str);
|
||||
sdb_gh_free (str);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ typedef struct {
|
||||
} StrBuf;
|
||||
|
||||
static StrBuf* strbuf_new(void) {
|
||||
return (StrBuf*) calloc (sizeof (StrBuf), 1);
|
||||
return (StrBuf*) sdb_gh_calloc (sizeof (StrBuf), 1);
|
||||
}
|
||||
|
||||
#define NEWLINE_AFTER_QUERY 1
|
||||
@ -23,8 +23,8 @@ static StrBuf* strbuf_append(StrBuf *sb, const char *str, const int nl) {
|
||||
}
|
||||
int len = strlen (str);
|
||||
if ((sb->len + len + 2) >= sb->size) {
|
||||
int newsize = sb->size + len + 256;
|
||||
char *b = (char *)realloc (sb->buf, newsize);
|
||||
size_t newsize = sb->size + len + 256;
|
||||
char *b = (char *)sdb_gh_realloc (sb->buf, newsize);
|
||||
/// TODO perform free and force all callers to update the ref?
|
||||
if (!b) {
|
||||
return NULL;
|
||||
@ -49,8 +49,8 @@ static StrBuf* strbuf_append(StrBuf *sb, const char *str, const int nl) {
|
||||
}
|
||||
|
||||
static StrBuf *strbuf_free(StrBuf *sb) {
|
||||
free (sb->buf);
|
||||
free (sb);
|
||||
sdb_gh_free (sb->buf);
|
||||
sdb_gh_free (sb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -106,9 +106,9 @@ static bool foreach_list_cb(void *user, const char *k, const char *v) {
|
||||
vlen = strlen (v);
|
||||
if (root) {
|
||||
rlen = strlen (root);
|
||||
line = (char *)malloc (klen + vlen + rlen + 3);
|
||||
line = (char *)sdb_gh_malloc (klen + vlen + rlen + 3);
|
||||
if (!line) {
|
||||
free (v2);
|
||||
sdb_gh_free (v2);
|
||||
return false;
|
||||
}
|
||||
memcpy (line, root, rlen);
|
||||
@ -117,9 +117,9 @@ static bool foreach_list_cb(void *user, const char *k, const char *v) {
|
||||
line[rlen + klen + 1] = '=';
|
||||
memcpy (line + rlen + klen + 2, v, vlen + 1);
|
||||
} else {
|
||||
line = (char *)malloc (klen + vlen + 2);
|
||||
line = (char *)sdb_gh_malloc (klen + vlen + 2);
|
||||
if (!line) {
|
||||
free (v2);
|
||||
sdb_gh_free (v2);
|
||||
return false;
|
||||
}
|
||||
memcpy (line, k, klen);
|
||||
@ -127,8 +127,8 @@ static bool foreach_list_cb(void *user, const char *k, const char *v) {
|
||||
memcpy (line + klen + 1, v, vlen + 1);
|
||||
}
|
||||
strbuf_append (rlu->out, line, 1);
|
||||
free (v2);
|
||||
free (line);
|
||||
sdb_gh_free (v2);
|
||||
sdb_gh_free (line);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -175,18 +175,18 @@ SDB_API char *sdb_querys(Sdb *r, char *buf, size_t len, const char *_cmd) {
|
||||
if ((int)len < 1 || !buf) {
|
||||
bufset = true;
|
||||
len = 64;
|
||||
buf = (char *)calloc (1, len);
|
||||
buf = (char *)sdb_gh_calloc (1, len);
|
||||
if (!buf) {
|
||||
strbuf_free (out);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (_cmd) {
|
||||
cmd = original_cmd = strdup (_cmd);
|
||||
cmd = original_cmd = sdb_strdup (_cmd);
|
||||
if (!cmd) {
|
||||
strbuf_free (out);
|
||||
if (bufset) {
|
||||
free (buf);
|
||||
sdb_gh_free (buf);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -345,9 +345,9 @@ next_quote:
|
||||
p = cmd;
|
||||
}
|
||||
if (*cmd == '$') {
|
||||
free (newcmd);
|
||||
sdb_gh_free (newcmd);
|
||||
char *nc = sdb_get (s, cmd + 1, 0);
|
||||
cmd = newcmd = (nc) ? nc : strdup ("");
|
||||
cmd = newcmd = (nc) ? nc : sdb_strdup ("");
|
||||
}
|
||||
// cmd = val
|
||||
// cmd is key and val is value
|
||||
@ -378,7 +378,7 @@ next_quote:
|
||||
} else if (*cmd == '+' || *cmd == '-') {
|
||||
d = 1;
|
||||
if (!buf) {
|
||||
buf = (char *)calloc (1, len);
|
||||
buf = (char *)sdb_gh_calloc (1, len);
|
||||
if (!buf) {
|
||||
goto fail;
|
||||
}
|
||||
@ -466,8 +466,8 @@ next_quote:
|
||||
w = snprintf (buf, len - 1, "0x%" PRIx64, n);
|
||||
if (w < 0 || (size_t)w > len) {
|
||||
if (bufset && len < 0xff) {
|
||||
free (buf);
|
||||
buf = (char *)malloc (len = 0xff);
|
||||
sdb_gh_free (buf);
|
||||
buf = (char *)sdb_gh_malloc (len = 0xff);
|
||||
if (!buf) {
|
||||
goto fail;
|
||||
}
|
||||
@ -479,8 +479,8 @@ next_quote:
|
||||
w = snprintf (buf, len-1, "%" PRId64, n);
|
||||
if (w < 0 || (size_t)w > len) {
|
||||
if (bufset && len < 0xff) {
|
||||
free (buf);
|
||||
buf = (char *)malloc (len = 0xff);
|
||||
sdb_gh_free (buf);
|
||||
buf = (char *)sdb_gh_malloc (len = 0xff);
|
||||
if (!buf) {
|
||||
goto fail;
|
||||
}
|
||||
@ -497,7 +497,7 @@ next_quote:
|
||||
// if (!eq) ...
|
||||
alength = sdb_array_length (s, p);
|
||||
if (!buf) {
|
||||
buf = (char *)malloc (++len);
|
||||
buf = (char *)sdb_gh_malloc (++len);
|
||||
if (!buf) {
|
||||
goto fail;
|
||||
}
|
||||
@ -506,9 +506,9 @@ next_quote:
|
||||
w = snprintf (buf, len, "%d", alength);
|
||||
if (w < 0 || (size_t)w > len) {
|
||||
if (bufset) {
|
||||
free (buf);
|
||||
sdb_gh_free (buf);
|
||||
}
|
||||
buf = (char *)malloc (len = 32);
|
||||
buf = (char *)sdb_gh_malloc (len = 32);
|
||||
bufset = 1;
|
||||
snprintf (buf, 31, "%d", alength);
|
||||
}
|
||||
@ -548,7 +548,7 @@ next_quote:
|
||||
} else {
|
||||
char *ret = sdb_array_pop (s, p, 0);
|
||||
out_concat (ret);
|
||||
free (ret);
|
||||
sdb_gh_free (ret);
|
||||
}
|
||||
}
|
||||
} else
|
||||
@ -587,7 +587,7 @@ next_quote:
|
||||
// (-)foo :: remove last element
|
||||
sdb_array_delete (s, p, -1, 0);
|
||||
}
|
||||
free (ret);
|
||||
sdb_gh_free (ret);
|
||||
}
|
||||
} else {
|
||||
// get/set specific element in array
|
||||
@ -602,13 +602,13 @@ next_quote:
|
||||
if (!newtmp) {
|
||||
goto fail;
|
||||
}
|
||||
free (arr);
|
||||
sdb_gh_free (arr);
|
||||
arr = newtmp;
|
||||
}
|
||||
ok = 0;
|
||||
out_concat (arr);
|
||||
sdb_array_delete (s, p, -i, 0);
|
||||
free (arr);
|
||||
sdb_gh_free (arr);
|
||||
} else goto fail;
|
||||
} else {
|
||||
if (encode) {
|
||||
@ -619,7 +619,7 @@ next_quote:
|
||||
sdb_array_set (s, p, i, val, 0)
|
||||
): sdb_array_delete (s, p, i, 0);
|
||||
if (encode) {
|
||||
free ((void*)val);
|
||||
sdb_gh_free ((void*)val);
|
||||
val = NULL;
|
||||
}
|
||||
}
|
||||
@ -644,14 +644,14 @@ next_quote:
|
||||
out_concat (arr);
|
||||
sdb_array_delete (s, p, -i, 0);
|
||||
}
|
||||
free (arr);
|
||||
sdb_gh_free (arr);
|
||||
} else {
|
||||
/* [+3]foo */
|
||||
char *arr = sdb_array_get (s, p, i, NULL);
|
||||
if (arr && *arr) {
|
||||
out_concat (arr);
|
||||
}
|
||||
free (arr);
|
||||
sdb_gh_free (arr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -667,7 +667,7 @@ next_quote:
|
||||
ok = sdb_array_set (s, p, idx, sval, 0);
|
||||
// TODO: handle when idx > sdb_alen
|
||||
if (encode)
|
||||
free (sval);
|
||||
sdb_gh_free (sval);
|
||||
} else {
|
||||
if (encode) {
|
||||
ok = sdb_set_owned (s, p, sval, 0);
|
||||
@ -692,7 +692,7 @@ next_quote:
|
||||
if (encode) {
|
||||
char *newbuf = (char*)sdb_decode (buf, NULL);
|
||||
if (newbuf) {
|
||||
free (buf);
|
||||
sdb_gh_free (buf);
|
||||
buf = newbuf;
|
||||
len = strlen(buf) + 1;
|
||||
}
|
||||
@ -704,9 +704,9 @@ next_quote:
|
||||
}
|
||||
wl = strlen (sval);
|
||||
if (!buf || wl >= len) {
|
||||
buf = (char *)malloc (wl + 2);
|
||||
buf = (char *)sdb_gh_malloc (wl + 2);
|
||||
if (!buf) {
|
||||
free (out->buf);
|
||||
sdb_gh_free (out->buf);
|
||||
out->buf = NULL;
|
||||
goto fail;
|
||||
}
|
||||
@ -726,7 +726,7 @@ next_quote:
|
||||
char *newbuf = (char*)sdb_decode (buf, NULL);
|
||||
if (newbuf) {
|
||||
if (bufset) {
|
||||
free (buf);
|
||||
sdb_gh_free (buf);
|
||||
}
|
||||
buf = newbuf;
|
||||
len = strlen (buf) + 1;
|
||||
@ -764,7 +764,7 @@ next_quote:
|
||||
}
|
||||
}
|
||||
if (encode) {
|
||||
free ((void*)val);
|
||||
sdb_gh_free ((void*)val);
|
||||
val = NULL;
|
||||
}
|
||||
if (ok && buf) {
|
||||
@ -782,17 +782,17 @@ next_quote:
|
||||
char *newtmp = (char*)sdb_decode (tmp, NULL);
|
||||
if (!newtmp)
|
||||
goto fail;
|
||||
free (tmp);
|
||||
sdb_gh_free (tmp);
|
||||
tmp = newtmp;
|
||||
}
|
||||
out_concat (tmp);
|
||||
free (tmp);
|
||||
sdb_gh_free (tmp);
|
||||
}
|
||||
} else {
|
||||
// kvpath: -> show indented json
|
||||
char *o = sdb_json_indent (sdb_const_get (s, cmd, 0), " ");
|
||||
out_concat (o);
|
||||
free (o);
|
||||
sdb_gh_free (o);
|
||||
}
|
||||
} else {
|
||||
// sdbget
|
||||
@ -802,7 +802,7 @@ next_quote:
|
||||
}
|
||||
out_concat (q);
|
||||
if (encode) {
|
||||
free ((void*)q);
|
||||
sdb_gh_free ((void*)q);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -811,7 +811,7 @@ next_quote:
|
||||
runNext:
|
||||
if (next) {
|
||||
if (bufset) {
|
||||
free (buf);
|
||||
sdb_gh_free (buf);
|
||||
buf = NULL;
|
||||
bufset = false;
|
||||
}
|
||||
@ -824,17 +824,17 @@ runNext:
|
||||
}
|
||||
fail:
|
||||
if (bufset) {
|
||||
free (buf);
|
||||
sdb_gh_free (buf);
|
||||
}
|
||||
if (out) {
|
||||
res = out->buf;
|
||||
free (out);
|
||||
sdb_gh_free (out);
|
||||
} else {
|
||||
free (res);
|
||||
sdb_gh_free (res);
|
||||
res = NULL;
|
||||
}
|
||||
free (original_cmd);
|
||||
free (newcmd);
|
||||
sdb_gh_free (original_cmd);
|
||||
sdb_gh_free (newcmd);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -848,7 +848,7 @@ SDB_API bool sdb_query(Sdb *s, const char *cmd) {
|
||||
fputs (out, stdout);
|
||||
}
|
||||
if (out != buf) {
|
||||
free (out);
|
||||
sdb_gh_free (out);
|
||||
}
|
||||
}
|
||||
return must_save;
|
||||
@ -859,7 +859,7 @@ SDB_API int sdb_query_lines(Sdb *s, const char *cmd) {
|
||||
if (!s || !cmd) {
|
||||
return 0;
|
||||
}
|
||||
op = strdup (cmd);
|
||||
op = sdb_strdup (cmd);
|
||||
if (!op) {
|
||||
return 0;
|
||||
}
|
||||
@ -874,7 +874,7 @@ SDB_API int sdb_query_lines(Sdb *s, const char *cmd) {
|
||||
p = o + 1;
|
||||
}
|
||||
} while (o);
|
||||
free (op);
|
||||
sdb_gh_free (op);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -892,14 +892,14 @@ static char *slurp(const char *file) {
|
||||
return NULL;
|
||||
}
|
||||
lseek (fd, 0, SEEK_SET);
|
||||
char *text = (char *)malloc (sz + 1);
|
||||
char *text = (char *)sdb_gh_malloc (sz + 1);
|
||||
if (!text) {
|
||||
close (fd);
|
||||
return NULL;
|
||||
}
|
||||
int ret = read (fd, text, sz);
|
||||
if (ret != sz) {
|
||||
free (text);
|
||||
sdb_gh_free (text);
|
||||
text = NULL;
|
||||
} else {
|
||||
text[sz] = 0;
|
||||
@ -913,7 +913,7 @@ SDB_API int sdb_query_file(Sdb *s, const char* file) {
|
||||
char *txt = slurp (file);
|
||||
if (txt) {
|
||||
ret = sdb_query_lines (s, txt);
|
||||
free (txt);
|
||||
sdb_gh_free (txt);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -5,16 +5,6 @@
|
||||
#include <sys/stat.h>
|
||||
#include "sdb/sdb.h"
|
||||
|
||||
#if 0
|
||||
static inline SdbKv *kv_at(HtPP *ht, HtPPBucket *bt, ut32 i) {
|
||||
return (SdbKv *)((char *)bt->arr + i * ht->opt.elem_size);
|
||||
}
|
||||
|
||||
static inline SdbKv *prev_kv(HtPP *ht, SdbKv *kv) {
|
||||
return (SdbKv *)((char *)kv - ht->opt.elem_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline SdbKv *next_kv(HtPP *ht, SdbKv *kv) {
|
||||
return (SdbKv *)((char *)kv + ht->opt.elem_size);
|
||||
}
|
||||
@ -35,13 +25,12 @@ static inline int nextcas(SdbKv const *kv) {
|
||||
return kv->cas + 1;
|
||||
}
|
||||
|
||||
// TODO: use mmap instead of read.. much faster!
|
||||
SDB_API Sdb* sdb_new0(void) {
|
||||
return sdb_new (NULL, NULL, 0);
|
||||
}
|
||||
|
||||
SDB_API Sdb* sdb_new(const char *path, const char *name, int lock) {
|
||||
Sdb* s = R_NEW0 (Sdb);
|
||||
Sdb* s = (Sdb*)sdb_gh_calloc (1, sizeof (Sdb));
|
||||
if (!s) {
|
||||
return NULL;
|
||||
}
|
||||
@ -59,17 +48,17 @@ SDB_API Sdb* sdb_new(const char *path, const char *name, int lock) {
|
||||
if (path && *path) {
|
||||
size_t plen = strlen (path);
|
||||
size_t nlen = strlen (name);
|
||||
s->dir = (char *)malloc (plen + nlen + 2);
|
||||
s->dir = (char *)sdb_gh_malloc (plen + nlen + 2);
|
||||
if (!s->dir) {
|
||||
free (s);
|
||||
sdb_gh_free (s);
|
||||
return NULL;
|
||||
}
|
||||
memcpy (s->dir, path, plen);
|
||||
s->dir[plen] = '/';
|
||||
memcpy (s->dir + plen + 1, name, nlen + 1);
|
||||
s->path = strdup (path);
|
||||
s->path = sdb_strdup (path);
|
||||
} else {
|
||||
s->dir = strdup (name);
|
||||
s->dir = sdb_strdup (name);
|
||||
}
|
||||
switch (lock) {
|
||||
case 1:
|
||||
@ -93,7 +82,7 @@ SDB_API Sdb* sdb_new(const char *path, const char *name, int lock) {
|
||||
s->last = s->timestamped? sdb_now (): 0LL;
|
||||
// TODO: must fail if we cant open for write in sync
|
||||
}
|
||||
s->name = strdup (name);
|
||||
s->name = sdb_strdup (name);
|
||||
} else {
|
||||
s->last = s->timestamped? sdb_now (): 0LL;
|
||||
s->fd = -1;
|
||||
@ -118,10 +107,10 @@ fail:
|
||||
close (s->fd);
|
||||
s->fd = -1;
|
||||
}
|
||||
free (s->dir);
|
||||
free (s->name);
|
||||
free (s->path);
|
||||
free (s);
|
||||
sdb_gh_free (s->dir);
|
||||
sdb_gh_free (s->name);
|
||||
sdb_gh_free (s->path);
|
||||
sdb_gh_free (s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -132,8 +121,8 @@ SDB_API void sdb_file(Sdb* s, const char *dir) {
|
||||
sdb_lock_file (s->dir, buf, sizeof (buf));
|
||||
sdb_unlock (buf);
|
||||
}
|
||||
free (s->dir);
|
||||
s->dir = (dir && *dir)? strdup (dir): NULL;
|
||||
sdb_gh_free (s->dir);
|
||||
s->dir = (dir && *dir)? sdb_strdup (dir): NULL;
|
||||
if (s->lock) {
|
||||
sdb_lock_file (s->dir, buf, sizeof (buf));
|
||||
sdb_lock (buf);
|
||||
@ -193,8 +182,8 @@ static void sdb_fini(Sdb* s, bool donull) {
|
||||
}
|
||||
sdb_ns_free (s);
|
||||
s->refs = 0;
|
||||
free (s->name);
|
||||
free (s->path);
|
||||
sdb_gh_free (s->name);
|
||||
sdb_gh_free (s->path);
|
||||
ls_free (s->ns);
|
||||
sdb_ht_free (s->ht);
|
||||
sdb_journal_close (s);
|
||||
@ -202,9 +191,9 @@ static void sdb_fini(Sdb* s, bool donull) {
|
||||
close (s->fd);
|
||||
s->fd = -1;
|
||||
}
|
||||
free (s->ndump);
|
||||
free (s->dir);
|
||||
free (sdbkv_value (&s->tmpkv));
|
||||
sdb_gh_free (s->ndump);
|
||||
sdb_gh_free (s->dir);
|
||||
sdb_gh_free (sdbkv_value (&s->tmpkv));
|
||||
s->tmpkv.base.value_len = 0;
|
||||
if (donull) {
|
||||
memset (s, 0, sizeof (Sdb));
|
||||
@ -218,7 +207,7 @@ SDB_API bool sdb_free(Sdb* s) {
|
||||
s->refs = 0;
|
||||
sdb_fini (s, false);
|
||||
s->ht = NULL;
|
||||
free (s);
|
||||
sdb_gh_free (s);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -298,7 +287,7 @@ SDB_API const char *sdb_const_get(Sdb* s, const char *key, ut32 *cas) {
|
||||
|
||||
SDB_API char *sdb_get_len(Sdb* s, const char *key, int *vlen, ut32 *cas) {
|
||||
const char *value = sdb_const_get_len (s, key, vlen, cas);
|
||||
return value ? strdup (value) : NULL;
|
||||
return value ? sdb_strdup (value) : NULL;
|
||||
}
|
||||
|
||||
SDB_API char *sdb_get(Sdb* s, const char *key, ut32 *cas) {
|
||||
@ -332,7 +321,7 @@ SDB_API int sdb_uncat(Sdb *s, const char *key, const char *value, ut32 cas) {
|
||||
char *p, *v = sdb_get_len (s, key, &vlen, NULL);
|
||||
int mod = 0;
|
||||
if (!v || !key || !value) {
|
||||
free (v);
|
||||
sdb_gh_free (v);
|
||||
return 0;
|
||||
}
|
||||
valen = strlen (value);
|
||||
@ -345,7 +334,7 @@ SDB_API int sdb_uncat(Sdb *s, const char *key, const char *value, ut32 cas) {
|
||||
if (mod) {
|
||||
sdb_set_owned (s, key, v, 0);
|
||||
} else {
|
||||
free (v);
|
||||
sdb_gh_free (v);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -362,7 +351,7 @@ SDB_API int sdb_concat(Sdb *s, const char *key, const char *value, ut32 cas) {
|
||||
return sdb_set (s, key, value, cas);
|
||||
}
|
||||
vl = strlen (value);
|
||||
o = (char *)malloc (kl + vl + 1);
|
||||
o = (char *)sdb_gh_malloc (kl + vl + 1);
|
||||
if (o) {
|
||||
memcpy (o, p, kl);
|
||||
memcpy (o + kl, value, vl + 1);
|
||||
@ -440,15 +429,14 @@ SDB_API int sdb_open(Sdb *s, const char *file) {
|
||||
}
|
||||
s->fd = open (file, O_RDONLY | O_BINARY);
|
||||
if (file != s->dir) {
|
||||
free (s->dir);
|
||||
s->dir = strdup (file);
|
||||
sdb_gh_free (s->dir);
|
||||
s->dir = sdb_strdup (file);
|
||||
s->path = NULL; // TODO: path is important
|
||||
}
|
||||
}
|
||||
s->last = 0LL;
|
||||
if (s->fd != -1 && fstat (s->fd, &st) != -1) {
|
||||
if ((S_IFREG & st.st_mode) != S_IFREG) {
|
||||
// eprintf ("Database must be a file\n");
|
||||
close (s->fd);
|
||||
s->fd = -1;
|
||||
return -1;
|
||||
@ -472,7 +460,7 @@ SDB_API void sdb_close(Sdb *s) {
|
||||
s->fd = -1;
|
||||
}
|
||||
if (s->dir) {
|
||||
free (s->dir);
|
||||
sdb_gh_free (s->dir);
|
||||
s->dir = NULL;
|
||||
}
|
||||
s->gp = NULL;
|
||||
@ -524,12 +512,12 @@ SDB_API bool sdbkv_match(SdbKv *kv, const char *expr) {
|
||||
// [^]str[$]=[^]str[$]
|
||||
const char *eq = strchr (expr, '=');
|
||||
if (eq) {
|
||||
char *e = strdup (expr);
|
||||
char *e = sdb_strdup (expr);
|
||||
char *ep = e + (eq - expr);
|
||||
*ep++ = 0;
|
||||
bool res = !*e || match (sdbkv_key (kv), e);
|
||||
bool res2 = !*ep || match (sdbkv_value (kv), ep);
|
||||
free (e);
|
||||
sdb_gh_free (e);
|
||||
return res && res2;
|
||||
}
|
||||
return match (sdbkv_key (kv), expr);
|
||||
@ -556,18 +544,18 @@ SDB_API SdbKv* sdbkv_new2(const char *k, int kl, const char *v, int vl) {
|
||||
return NULL;
|
||||
}
|
||||
kv->base.key_len = kl;
|
||||
kv->base.key = malloc (kv->base.key_len + 1);
|
||||
kv->base.key = sdb_gh_malloc (kv->base.key_len + 1);
|
||||
if (!kv->base.key) {
|
||||
free (kv);
|
||||
sdb_gh_free (kv);
|
||||
return NULL;
|
||||
}
|
||||
memcpy (kv->base.key, k, kv->base.key_len + 1);
|
||||
kv->base.value_len = vl;
|
||||
if (vl) {
|
||||
kv->base.value = malloc (vl + 1);
|
||||
kv->base.value = sdb_gh_malloc (vl + 1);
|
||||
if (!kv->base.value) {
|
||||
free (kv->base.key);
|
||||
free (kv);
|
||||
sdb_gh_free (kv->base.key);
|
||||
sdb_gh_free (kv);
|
||||
return NULL;
|
||||
}
|
||||
memcpy (kv->base.value, v, vl + 1);
|
||||
@ -582,22 +570,21 @@ SDB_API SdbKv* sdbkv_new2(const char *k, int kl, const char *v, int vl) {
|
||||
|
||||
SDB_API void sdbkv_free(SdbKv *kv) {
|
||||
if (kv) {
|
||||
free (sdbkv_key (kv));
|
||||
free (sdbkv_value (kv));
|
||||
sdb_gh_free (sdbkv_key (kv));
|
||||
sdb_gh_free (sdbkv_value (kv));
|
||||
R_FREE (kv);
|
||||
}
|
||||
}
|
||||
|
||||
static ut32 sdb_set_internal(Sdb* s, const char *key, char *val, bool owned, ut32 cas) {
|
||||
ut32 vlen, klen;
|
||||
SdbKv *kv;
|
||||
bool found;
|
||||
if (!s || !key) {
|
||||
return 0;
|
||||
}
|
||||
if (!val) {
|
||||
if (owned) {
|
||||
val = strdup ("");
|
||||
val = sdb_strdup ("");
|
||||
} else {
|
||||
val = (char *)"";
|
||||
}
|
||||
@ -607,7 +594,7 @@ static ut32 sdb_set_internal(Sdb* s, const char *key, char *val, bool owned, ut3
|
||||
vlen = strlen (val);
|
||||
if (klen >= SDB_KSZ || vlen >= SDB_VSZ) {
|
||||
if (owned) {
|
||||
free (val);
|
||||
sdb_gh_free (val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -615,12 +602,12 @@ static ut32 sdb_set_internal(Sdb* s, const char *key, char *val, bool owned, ut3
|
||||
sdb_journal_log (s, key, val);
|
||||
}
|
||||
cdb_findstart (&s->db);
|
||||
kv = sdb_ht_find_kvp (s->ht, key, &found);
|
||||
SdbKv *kv = sdb_ht_find_kvp (s->ht, key, &found);
|
||||
if (found && sdbkv_value (kv)) {
|
||||
if (cdb_findnext (&s->db, sdb_hash (key), key, klen)) {
|
||||
if (cas && kv->cas != cas) {
|
||||
if (owned) {
|
||||
free (val);
|
||||
sdb_gh_free (val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -631,12 +618,12 @@ static ut32 sdb_set_internal(Sdb* s, const char *key, char *val, bool owned, ut3
|
||||
kv->cas = cas = nextcas (kv);
|
||||
if (owned) {
|
||||
kv->base.value_len = vlen;
|
||||
free (kv->base.value);
|
||||
sdb_gh_free (kv->base.value);
|
||||
kv->base.value = val; // owned
|
||||
} else {
|
||||
if ((ut32)vlen > kv->base.value_len) {
|
||||
free (kv->base.value);
|
||||
kv->base.value = malloc (vlen + 1);
|
||||
sdb_gh_free (kv->base.value);
|
||||
kv->base.value = sdb_gh_malloc (vlen + 1);
|
||||
}
|
||||
memcpy (kv->base.value, val, vlen + 1);
|
||||
kv->base.value_len = vlen;
|
||||
@ -661,8 +648,8 @@ static ut32 sdb_set_internal(Sdb* s, const char *key, char *val, bool owned, ut3
|
||||
if (kv) {
|
||||
cas = kv->cas = nextcas (kv);
|
||||
sdb_ht_insert_kvp (s->ht, kv, true /*update*/);
|
||||
free (kv);
|
||||
sdb_hook_call (s, key, val);
|
||||
sdb_gh_free (kv);
|
||||
return cas;
|
||||
}
|
||||
// kv set failed, no need to callback sdb_hook_call (s, key, val);
|
||||
@ -700,8 +687,8 @@ static bool sdb_foreach_list_cb(void *user, const char *k, const char *v) {
|
||||
SdbKv *kv = R_NEW0 (SdbKv);
|
||||
if (kv) {
|
||||
/* seems like some k/v are constructed in the stack and cant be used after returning */
|
||||
kv->base.key = strdup (k);
|
||||
kv->base.value = strdup (v);
|
||||
kv->base.key = sdb_strdup (k);
|
||||
kv->base.value = sdb_strdup (v);
|
||||
ls_append (list, kv);
|
||||
return true;
|
||||
}
|
||||
@ -738,8 +725,8 @@ static bool sdb_foreach_list_filter_cb(void *user, const char *k, const char *v)
|
||||
if (!kv) {
|
||||
goto err;
|
||||
}
|
||||
kv->base.key = strdup (k);
|
||||
kv->base.value = strdup (v);
|
||||
kv->base.key = sdb_strdup (k);
|
||||
kv->base.value = sdb_strdup (v);
|
||||
if (!kv->base.key || !kv->base.value) {
|
||||
goto err;
|
||||
}
|
||||
@ -783,8 +770,8 @@ static bool sdb_foreach_match_cb(void *user, const char *k, const char *v) {
|
||||
if (!kv) {
|
||||
return false;
|
||||
}
|
||||
kv->base.key = strdup (k);
|
||||
kv->base.value = strdup (v);
|
||||
kv->base.key = sdb_strdup (k);
|
||||
kv->base.value = sdb_strdup (v);
|
||||
ls_append (o->list, kv);
|
||||
if (o->single) {
|
||||
return false;
|
||||
@ -821,7 +808,7 @@ static bool sdb_foreach_cdb(Sdb *s, SdbForeachCallback cb, SdbForeachCallback cb
|
||||
while (sdb_dump_dupnext (s, k, &v, NULL)) {
|
||||
SdbKv *kv = sdb_ht_find_kvp (s->ht, k, &found);
|
||||
if (found) {
|
||||
free (v);
|
||||
sdb_gh_free (v);
|
||||
if (kv && sdbkv_key (kv) && sdbkv_value (kv)) {
|
||||
if (!cb (user, sdbkv_key (kv), sdbkv_value (kv))) {
|
||||
return false;
|
||||
@ -832,10 +819,10 @@ static bool sdb_foreach_cdb(Sdb *s, SdbForeachCallback cb, SdbForeachCallback cb
|
||||
}
|
||||
} else {
|
||||
if (!cb (user, k, v)) {
|
||||
free (v);
|
||||
sdb_gh_free (v);
|
||||
return false;
|
||||
}
|
||||
free (v);
|
||||
sdb_gh_free (v);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -940,7 +927,7 @@ SDB_API SdbKv *sdb_dump_next(Sdb* s) {
|
||||
}
|
||||
vl--;
|
||||
snprintf (sdbkv_key (&s->tmpkv), SDB_KSZ, "%s", k);
|
||||
free (sdbkv_value (&s->tmpkv));
|
||||
sdb_gh_free (sdbkv_value (&s->tmpkv));
|
||||
s->tmpkv.base.value = v;
|
||||
s->tmpkv.base.value_len = vl;
|
||||
return &s->tmpkv;
|
||||
@ -1009,12 +996,12 @@ SDB_API bool sdb_dump_dupnext(Sdb* s, char *key, char **value, int *_vlen) {
|
||||
if (value) {
|
||||
*value = 0;
|
||||
if (vlen < SDB_MAX_VALUE) {
|
||||
*value = (char *)malloc (vlen + 10);
|
||||
*value = (char *)sdb_gh_malloc (vlen + 10);
|
||||
if (!*value) {
|
||||
return false;
|
||||
}
|
||||
if (getbytes (s, *value, vlen) == -1) {
|
||||
free (*value);
|
||||
sdb_gh_free (*value);
|
||||
*value = NULL;
|
||||
return false;
|
||||
}
|
||||
@ -1064,7 +1051,7 @@ SDB_API bool sdb_expire_set(Sdb* s, const char *key, ut64 expire, ut32 cas) {
|
||||
if (len < 1 || len >= INT32_MAX) {
|
||||
return false;
|
||||
}
|
||||
if (!(buf = (char *)calloc (1, len + 1))) {
|
||||
if (!(buf = (char *)sdb_gh_calloc (1, len + 1))) {
|
||||
return false;
|
||||
}
|
||||
cdb_read (&s->db, buf, len, pos);
|
||||
@ -1176,7 +1163,7 @@ SDB_API void sdb_drain(Sdb *s, Sdb *f) {
|
||||
f->refs = s->refs;
|
||||
sdb_fini (s, true);
|
||||
*s = *f;
|
||||
free (f);
|
||||
sdb_gh_free (f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1237,7 +1224,7 @@ static bool like_cb(void *user, const char *k, const char *v) {
|
||||
if (lcd->array) {
|
||||
int idx = lcd->array_index;
|
||||
int newsize = lcd->array_size + sizeof (char*) * 2;
|
||||
const char **newarray = (const char **)realloc ((void*)lcd->array, newsize);
|
||||
const char **newarray = (const char **)sdb_gh_realloc ((void*)lcd->array, newsize);
|
||||
if (!newarray) {
|
||||
return false;
|
||||
}
|
||||
@ -1270,14 +1257,14 @@ SDB_API char** sdb_like(Sdb *s, const char *k, const char *v, SdbForeachCallback
|
||||
lcd.val = NULL;
|
||||
}
|
||||
lcd.array_size = sizeof (char*) * 2;
|
||||
lcd.array = (const char **)calloc (lcd.array_size, 1); // XXX shouldnt be const
|
||||
lcd.array = (const char **)sdb_gh_calloc (lcd.array_size, 1); // XXX shouldnt be const
|
||||
if (!lcd.array) {
|
||||
return NULL;
|
||||
}
|
||||
lcd.array_index = 0;
|
||||
sdb_foreach (s, like_cb, &lcd);
|
||||
if (lcd.array_index == 0) {
|
||||
free ((void*)lcd.array);
|
||||
sdb_gh_free ((void*)lcd.array);
|
||||
return NULL;
|
||||
}
|
||||
return (char**)lcd.array;
|
||||
|
@ -351,7 +351,7 @@ static bool load_process_final_line(LoadCtx *ctx) {
|
||||
// load_process_line needs ctx.buf[ctx.pos] to be allocated!
|
||||
// so we need room for one additional byte after the buffer.
|
||||
size_t linesz = ctx->bufsz - ctx->line_begin;
|
||||
char *linebuf = (char *)malloc (linesz + 1);
|
||||
char *linebuf = (char *)sdb_gh_malloc (linesz + 1);
|
||||
if (!linebuf) {
|
||||
return false;
|
||||
}
|
||||
@ -433,12 +433,12 @@ SDB_API bool sdb_text_load(Sdb *s, const char *file) {
|
||||
goto beach;
|
||||
}
|
||||
#else
|
||||
x = (char *)calloc (1, st.st_size);
|
||||
x = (char *)sdb_gh_calloc (1, st.st_size);
|
||||
if (!x) {
|
||||
goto beach;
|
||||
}
|
||||
if (read (fd, x, st.st_size) != st.st_size) {
|
||||
free (x);
|
||||
sdb_gh_free (x);
|
||||
goto beach;
|
||||
}
|
||||
#endif
|
||||
@ -446,7 +446,7 @@ SDB_API bool sdb_text_load(Sdb *s, const char *file) {
|
||||
#if USE_MMAN
|
||||
munmap (x, st.st_size);
|
||||
#else
|
||||
free (x);
|
||||
sdb_gh_free (x);
|
||||
#endif
|
||||
beach:
|
||||
close (fd);
|
||||
|
@ -121,7 +121,7 @@ SDB_API char *sdb_itoa(ut64 n, int base, char *os, int oslen) {
|
||||
}
|
||||
if (!n) {
|
||||
if (!os) {
|
||||
return strdup ("0");
|
||||
return sdb_strdup ("0");
|
||||
}
|
||||
if (sl > 1) {
|
||||
memcpy (os, "0", 2);
|
||||
@ -145,7 +145,7 @@ SDB_API char *sdb_itoa(ut64 n, int base, char *os, int oslen) {
|
||||
s[i--] = '0';
|
||||
}
|
||||
if (!os) {
|
||||
return strdup (s + i + 1);
|
||||
return sdb_strdup (s + i + 1);
|
||||
}
|
||||
if (copy_string) {
|
||||
// unnecessary memmove in case we use the return value
|
||||
|
Loading…
x
Reference in New Issue
Block a user