From d0602319e882c94fa8eb0223cb53664664f17d7a Mon Sep 17 00:00:00 2001 From: cancel Date: Tue, 7 Jan 2020 09:25:15 +0900 Subject: [PATCH] Cleanup --- thirdparty/gbstring.c | 61 +++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/thirdparty/gbstring.c b/thirdparty/gbstring.c index badffaa..a67b1b7 100644 --- a/thirdparty/gbstring.c +++ b/thirdparty/gbstring.c @@ -1,4 +1,5 @@ #include "gbstring.h" +#include #include #include #include @@ -49,6 +50,14 @@ typedef struct gbStringHeader { #define GB_STRING_HEADER(s) ((gbStringHeader *)s - 1) +#if defined(__GNUC__) || defined(__clang__) +#define GB_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +#define GB_NOINLINE __declspec(noinline) +#else +#define GB_NOINLINE +#endif + static void gbs_setlen(gbs str, size_t len) { GB_STRING_HEADER(str)->len = len; } @@ -57,6 +66,26 @@ static void gbs_setcap(gbs str, size_t cap) { GB_STRING_HEADER(str)->cap = cap; } +static GB_NOINLINE gbs gbs_impl_catvprintf(gbs s, const char *fmt, va_list ap) { + size_t old_len; + int required; + va_list cpy; + va_copy(cpy, ap); + required = vsnprintf(NULL, 0, fmt, cpy); + va_end(cpy); + if (s) { + old_len = GB_STRING_HEADER(s)->len; + s = gbs_makeroomfor(s, (size_t)required); + } else { + old_len = 0; + s = gbs_newcap((size_t)required); + } + if (s == NULL) + return NULL; + vsnprintf(s + old_len, (size_t)required + 1, fmt, ap); + return s; +} + gbs gbs_newcap(size_t cap) { gbStringHeader *header; char *str; @@ -90,15 +119,13 @@ gbs gbs_new(char const *str) { return gbs_newlen(str, len); } gbs gbs_newvprintf(const char *fmt, va_list ap) { - gbs s; - s = gbs_catvprintf(NULL, fmt, ap); - return s; + return gbs_impl_catvprintf(NULL, fmt, ap); } gbs gbs_newprintf(char const *fmt, ...) { gbs s; va_list ap; va_start(ap, fmt); - s = gbs_catvprintf(NULL, fmt, ap); + s = gbs_impl_catvprintf(NULL, fmt, ap); va_end(ap); return s; } @@ -224,31 +251,21 @@ gbs gbs_trim(gbs str, char const *cut_set) { } gbs gbs_catvprintf(gbs s, const char *fmt, va_list ap) { - size_t old_len; - int required; - va_list cpy; - va_copy(cpy, ap); - required = vsnprintf(NULL, 0, fmt, cpy); - va_end(cpy); - if (s) { - old_len = GB_STRING_HEADER(s)->len; - s = gbs_makeroomfor(s, (size_t)required); - } else { - old_len = 0; - s = gbs_newcap((size_t)required); - } - if (s == NULL) - return NULL; - vsnprintf(s + old_len, (size_t)required + 1, fmt, ap); - return s; + // not sure if we should make exception for cat_* functions to allow cat'ing + // to null pointer. we should see if it ends up being useful in code, or if + // we should just match the existing behavior of sds/gb_string. + assert(s != NULL); + return gbs_impl_catvprintf(s, fmt, ap); } gbs gbs_catprintf(gbs s, char const *fmt, ...) { + assert(s != NULL); va_list ap; va_start(ap, fmt); - s = gbs_catvprintf(s, fmt, ap); + s = gbs_impl_catvprintf(s, fmt, ap); va_end(ap); return s; } #undef GB_STRING_HEADER +#undef GB_NOINLINE