diff --git a/xs.h b/xs.h index d30b26f..6f3a0ed 100644 --- a/xs.h +++ b/xs.h @@ -34,6 +34,9 @@ typedef char d_char; /* auto-destroyable strings */ #define xs __attribute__ ((__cleanup__ (_xs_destroy))) d_char +void *xs_free(void *ptr); +void *_xs_realloc(void *ptr, size_t size, const char *file, int line); +#define xs_realloc(ptr, size) _xs_realloc(ptr, size, __FILE__, __LINE__) int _xs_blk_size(int sz); void _xs_destroy(char **var); #define xs_debug() raise(SIGTRAP) @@ -41,7 +44,6 @@ xstype xs_type(const char *data); int xs_size(const char *data); int xs_is_null(const char *data); d_char *xs_dup(const char *data); -void *xs_realloc(void *ptr, size_t size); d_char *xs_expand(d_char *data, int offset, int size); d_char *xs_collapse(d_char *data, int offset, int size); d_char *xs_insert_m(d_char *data, int offset, const char *mem, int size); @@ -80,19 +82,56 @@ d_char *xs_number_new(double f); double xs_number_get(const char *v); const char *xs_number_str(const char *v); -extern int _xs_debug; - #ifdef XS_IMPLEMENTATION -int _xs_debug = 0; +void *_xs_realloc(void *ptr, size_t size, const char *file, int line) +{ + d_char *ndata = realloc(ptr, size); + + if (ndata == NULL) { + fprintf(stderr, "**OUT OF MEMORY**\n"); + abort(); + } + +#ifdef XS_DEBUG + if (ndata != ptr) { + FILE *f = fopen("xs_memory.out", "a"); + + if (ptr != NULL) + fprintf(f, "%p b\n", ptr); + + fprintf(f, "%p a %ld %s %d\n", ndata, size, file, line); + fclose(f); + } +#endif + + return ndata; +} + + +void *xs_free(void *ptr) +{ +#ifdef XS_DEBUG + if (ptr != NULL) { + FILE *f = fopen("xs_memory.out", "a"); + fprintf(f, "%p b\n", ptr); + fclose(f); + } +#endif + + free(ptr); + return NULL; +} + void _xs_destroy(char **var) { +/* if (_xs_debug) printf("_xs_destroy %p\n", var); - - free(*var); +*/ + xs_free(*var); } @@ -222,19 +261,6 @@ d_char *xs_dup(const char *data) } -void *xs_realloc(void *ptr, size_t size) -{ - d_char *ndata = realloc(ptr, size); - - if (ndata == NULL) { - fprintf(stderr, "**OUT OF MEMORY**\n"); - abort(); - } - - return ndata; -} - - d_char *xs_expand(d_char *data, int offset, int size) /* opens a hole in data */ { @@ -325,11 +351,10 @@ d_char *xs_fmt(const char *fmt, ...) va_end(ap); if (n > 0) { - n = _xs_blk_size(n + 1); - s = calloc(n, 1); + s = xs_realloc(NULL, _xs_blk_size(n + 1)); va_start(ap, fmt); - vsnprintf(s, n, fmt, ap); + vsnprintf(s, n + 1, fmt, ap); va_end(ap); } diff --git a/xs_curl.h b/xs_curl.h index 0dd1afc..5223a4e 100644 --- a/xs_curl.h +++ b/xs_curl.h @@ -54,7 +54,7 @@ static int _data_callback(void *buffer, size_t size, /* open space */ pd->size += sz; - pd->data = realloc(pd->data, pd->size + 1); + pd->data = xs_realloc(pd->data, pd->size + 1); /* copy data */ memcpy(pd->data + pd->offset, buffer, sz); @@ -166,7 +166,7 @@ d_char *xs_http_request(char *method, char *url, d_char *headers, ipd.data[ipd.size] = '\0'; } else - free(ipd.data); + xs_free(ipd.data); return response; } diff --git a/xs_encdec.h b/xs_encdec.h index b093eca..334f995 100644 --- a/xs_encdec.h +++ b/xs_encdec.h @@ -50,8 +50,7 @@ d_char *xs_hex_dec(const char *hex, int *size) int i; if (sscanf(&hex[n], "%02x", &i) == 0) { /* decoding error */ - free(s); - return NULL; + return xs_free(s); } else *p = i; @@ -137,8 +136,7 @@ d_char *xs_base64_dec(const char *data, int *size) if (ss == NULL) { /* not a base64 char */ - free(s); - return NULL; + return xs_free(s); } cs[n] = ss - b64_tbl; diff --git a/xs_httpd.h b/xs_httpd.h index 2fb5057..09dce0d 100644 --- a/xs_httpd.h +++ b/xs_httpd.h @@ -252,10 +252,8 @@ d_char *xs_httpd_request(FILE *f, d_char **payload, int *p_size) req = xs_dict_append(req, "q_vars", q_vars); req = xs_dict_append(req, "p_vars", p_vars); - if (errno) { - free(req); - req = NULL; - } + if (errno) + req = xs_free(req); return req; } diff --git a/xs_json.h b/xs_json.h index 13c3ebb..d992494 100644 --- a/xs_json.h +++ b/xs_json.h @@ -368,7 +368,7 @@ d_char *_xs_json_loads_array(const char **json, js_type *t) l = xs_list_append(l, v); while (*t == JS_INCOMPLETE) { - free(_xs_json_loads_lexer(&s, &tt)); + xs_free(_xs_json_loads_lexer(&s, &tt)); if (tt == JS_CBRACK) *t = JS_ARRAY; @@ -392,10 +392,8 @@ d_char *_xs_json_loads_array(const char **json, js_type *t) *t = JS_ERROR; } - if (*t == JS_ERROR) { - free(l); - l = NULL; - } + if (*t == JS_ERROR) + l = xs_free(l); *json = s; @@ -421,7 +419,7 @@ d_char *_xs_json_loads_object(const char **json, js_type *t) *t = JS_OBJECT; else if (tt == JS_STRING) { - free(_xs_json_loads_lexer(&s, &tt)); + xs_free(_xs_json_loads_lexer(&s, &tt)); if (tt == JS_COLON) { xs *v1; @@ -433,7 +431,7 @@ d_char *_xs_json_loads_object(const char **json, js_type *t) d = xs_dict_append(d, k1, v1); while (*t == JS_INCOMPLETE) { - free(_xs_json_loads_lexer(&s, &tt)); + xs_free(_xs_json_loads_lexer(&s, &tt)); if (tt == JS_CCURLY) *t = JS_OBJECT; @@ -442,7 +440,7 @@ d_char *_xs_json_loads_object(const char **json, js_type *t) xs *k = _xs_json_loads_lexer(&s, &tt); if (tt == JS_STRING) { - free(_xs_json_loads_lexer(&s, &tt)); + xs_free(_xs_json_loads_lexer(&s, &tt)); if (tt == JS_COLON) { xs *v; @@ -474,10 +472,8 @@ d_char *_xs_json_loads_object(const char **json, js_type *t) else *t = JS_ERROR; - if (*t == JS_ERROR) { - free(d); - d = NULL; - } + if (*t == JS_ERROR) + d = xs_free(d); *json = s; @@ -491,7 +487,7 @@ d_char *xs_json_loads(const char *json) d_char *v = NULL; js_type t; - free(_xs_json_loads_lexer(&json, &t)); + xs_free(_xs_json_loads_lexer(&json, &t)); if (t == JS_OBRACK) v = _xs_json_loads_array(&json, &t); diff --git a/xs_openssl.h b/xs_openssl.h index 0652637..5e3d03c 100644 --- a/xs_openssl.h +++ b/xs_openssl.h @@ -140,7 +140,7 @@ d_char *xs_rsa_sign(const char *secret, const char *mem, int size) BIO_free(b); RSA_free(rsa); - free(sig); + xs_free(sig); return signature; } @@ -211,7 +211,7 @@ d_char *xs_evp_sign(const char *secret, const char *mem, int size) EVP_MD_CTX_free(mdctx); EVP_PKEY_free(pkey); BIO_free(b); - free(sig); + xs_free(sig); return signature; } diff --git a/xs_set.h b/xs_set.h index 2beb454..0d76bed 100644 --- a/xs_set.h +++ b/xs_set.h @@ -22,7 +22,9 @@ xs_set *xs_set_new(int elems) /* creates a new set with a maximum of size hashed data */ { int sz = sizeof(struct _xs_set) + sizeof(int) * elems; - xs_set *s = calloc(sz, 1); + xs_set *s = xs_realloc(NULL, sz); + + memset(s, '\0', sz); /* initialize */ s->elems = elems; @@ -35,8 +37,8 @@ xs_set *xs_set_new(int elems) void xs_set_free(xs_set *s) /* frees a set */ { - free(s->list); - free(s); + xs_free(s->list); + xs_free(s); } diff --git a/xs_version.h b/xs_version.h index 300ab44..fc3a46e 100644 --- a/xs_version.h +++ b/xs_version.h @@ -1 +1 @@ -/* 9f90d5958755ec33c6c4946427f71de37af7500e */ +/* 223ebe7a241f24ba043b32cb30d0428ac0d1dd5f */