#include <limits.h>
#endif
-#include "ralloc.h"
-
-#ifdef __GNUC__
-#define likely(x) __builtin_expect(!!(x),1)
-#define unlikely(x) __builtin_expect(!!(x),0)
-#else
-#define likely(x) !!(x)
-#define unlikely(x) !!(x)
+/* Some versions of MinGW are missing _vscprintf's declaration, although they
+ * still provide the symbol in the import library. */
+#ifdef __MINGW32__
+_CRTIMP int _vscprintf(const char *format, va_list argptr);
#endif
+#include "ralloc.h"
+
#ifndef va_copy
#ifdef __va_copy
#define va_copy(dest, src) __va_copy((dest), (src))
struct ralloc_header
{
+#ifdef DEBUG
/* A canary value used to determine whether a pointer is ralloc'd. */
unsigned canary;
+#endif
struct ralloc_header *parent;
{
ralloc_header *info = (ralloc_header *) (((char *) ptr) -
sizeof(ralloc_header));
+#ifdef DEBUG
assert(info->canary == CANARY);
+#endif
return info;
}
ralloc_size(const void *ctx, size_t size)
{
void *block = calloc(1, size + sizeof(ralloc_header));
+ ralloc_header *info;
+ ralloc_header *parent;
- ralloc_header *info = (ralloc_header *) block;
- ralloc_header *parent = ctx != NULL ? get_header(ctx) : NULL;
+ if (unlikely(block == NULL))
+ return NULL;
+ info = (ralloc_header *) block;
+ parent = ctx != NULL ? get_header(ctx) : NULL;
add_child(parent, info);
+#ifdef DEBUG
info->canary = CANARY;
+#endif
return PTR_FROM_HEADER(info);
}
return NULL;
info = get_header(ptr);
- return PTR_FROM_HEADER(info->parent);
+ return info->parent ? PTR_FROM_HEADER(info->parent) : NULL;
}
static void *autofree_context = NULL;
va_list args;
va_copy(args, untouched_args);
-#ifdef _MSC_VER
+#ifdef _WIN32
/* We need to use _vcsprintf to calculate the size as vsnprintf returns -1
* if the number of characters to write is greater than count.
*/
bool
ralloc_vasprintf_append(char **str, const char *fmt, va_list args)
{
- size_t existing_length, new_length;
+ size_t existing_length;
+ assert(str != NULL);
+ existing_length = *str ? strlen(*str) : 0;
+ return ralloc_vasprintf_rewrite_tail(str, &existing_length, fmt, args);
+}
+
+bool
+ralloc_asprintf_rewrite_tail(char **str, size_t *start, const char *fmt, ...)
+{
+ bool success;
+ va_list args;
+ va_start(args, fmt);
+ success = ralloc_vasprintf_rewrite_tail(str, start, fmt, args);
+ va_end(args);
+ return success;
+}
+
+bool
+ralloc_vasprintf_rewrite_tail(char **str, size_t *start, const char *fmt,
+ va_list args)
+{
+ size_t new_length;
char *ptr;
assert(str != NULL);
return true;
}
- existing_length = strlen(*str);
new_length = printf_length(fmt, args);
- ptr = resize(*str, existing_length + new_length + 1);
+ ptr = resize(*str, *start + new_length + 1);
if (unlikely(ptr == NULL))
return false;
- vsnprintf(ptr + existing_length, new_length + 1, fmt, args);
+ vsnprintf(ptr + *start, new_length + 1, fmt, args);
*str = ptr;
+ *start += new_length;
return true;
}