/* * Similar core function to LGPL licensed talloc from Samba */ #ifndef _HIERALLOC_H_ #define _HIERALLOC_H_ #include <stdio.h> #include <stdarg.h> // allow __LINE__ to be stringified #ifndef __location__ #define __HIERALLOC_STRING_0__(s) #s #define __HIERALLOC_STRING_1__(s) __HIERALLOC_STRING_0__(s) #define __HIERALLOC_STRING_2__ __HIERALLOC_STRING_1__(__LINE__) #define __location__ __FILE__ ":" __HIERALLOC_STRING_2__ #endif #define hieralloc(ctx, type) (type *)hieralloc_allocate(ctx, sizeof(type), #type) #define hieralloc_size(ctx, size) hieralloc_allocate(ctx, size, "sz:"__location__) #define hieralloc_new(ctx) hieralloc_allocate(ctx, 0, "nw:" __location__) #define hieralloc_zero(ctx, type) (type *)_hieralloc_zero(ctx, sizeof(type), "zr:"#type) #define hieralloc_zero_size(ctx, size) _hieralloc_zero(ctx, size, "zrsz:"__location__) #define hieralloc_array(ctx, type, count) (type *)hieralloc_allocate(ctx, sizeof(type) * count, "ar:"#type) #define hieralloc_realloc(ctx, p, type, count) (type *)hieralloc_reallocate(ctx, p, sizeof(type) * count, "re:"#type) #ifdef __cplusplus extern "C" { #endif // allocate memory and attach to parent context and siblings void * hieralloc_allocate(const void * context, unsigned size, const char * name); // (re)allocate memory and attach to parent context and siblings void * hieralloc_reallocate(const void * context, void * ptr, unsigned size, const char * name); // calls destructor if set, and frees children. // if destructor returns -1, then do nothing and return -1. int hieralloc_free(void * ptr); // creates 0 allocation to be used as parent context void * hieralloc_init(const char * name); // returns global context void * hieralloc_autofree_context(); // sets destructor to be called before freeing; dctor return -1 aborts free void hieralloc_set_destructor(const void * ptr, int (* destructor)(void *)); // gets parent context of allocated memory void * hieralloc_parent(const void * ptr); // moves allocation to new parent context; maintain children but update siblings // returns ptr on success void * hieralloc_steal(const void * new_ctx, const void * ptr); // not implemented from talloc_reference void * hieralloc_reference(const void * ref_ctx, const void * ptr); // not implemented from talloc_unlink int hieralloc_unlink(const void * ctx, void * ptr); // allocate and zero memory void * _hieralloc_zero(const void * ctx, unsigned size, const char * name); // allocate and copy char * hieralloc_strdup(const void * ctx, const char * str); // allocate and copy char * hieralloc_strndup(const void * ctx, const char * str, unsigned len); // reallocate and append char * hieralloc_strdup_append(char * str, const char * append); // reallocate and append char * hieralloc_strndup_append(char * str, const char * append, unsigned len); // allocate and vsprintf char * hieralloc_vasprintf(const void * ctx, const char * fmt, va_list va); // allocate and sprintf char * hieralloc_asprintf(const void * ctx, const char * fmt, ...); // reallocate and append vsprintf char * hieralloc_vasprintf_append(char * str, const char * fmt, va_list va); // reallocate and append sprintf char * hieralloc_asprintf_append(char * str, const char * fmt, ...); // report self and child allocations void hieralloc_report(const void * ptr, FILE * file); void hieralloc_report_brief(const void * ptr, FILE * file); void hieralloc_report_lineage(const void * ptr, FILE * file, int tab); int hieralloc_find(const void * top, const void * ptr, FILE * file, int tab); #ifdef __cplusplus } #endif #endif