diff --git a/gb_string.h b/gb_string.h index a0058a5..bb665b2 100644 --- a/gb_string.h +++ b/gb_string.h @@ -198,6 +198,11 @@ int main(int argc, char **argv) { #ifndef GB_STRING_INCLUDE_GB_STRING_H #define GB_STRING_INCLUDE_GB_STRING_H +#if !defined(GB_HAS_SNPRINTF) && \ + (__STDC_VERSION__ >= 199101L || __cplusplus >= 201103L) +#define GB_HAS_SNPRINTF +#endif + #ifndef GB_ALLOC #define GB_ALLOC(sz) malloc(sz) #define GB_FREE(ptr) free(ptr) @@ -276,6 +281,10 @@ gbBool gb_strings_are_equal(gbString const lhs, gbString const rhs); gbString gb_trim_string(gbString str, char const *cut_set); +#ifdef GB_HAS_SNPRINTF +gbString gb_printf(gbString str, char const *fmt, ...); +gbString gb_vprintf(gbString str, char const *fmt, va_list va); +#endif #ifdef __cplusplus } @@ -308,10 +317,22 @@ gb_inline void string_make_space_for(String& str, usize add_len) { str = gb_stri gb_inline usize string_allocation_size(const String str) { return gb_string_allocation_size(str); } gb_inline bool strings_are_equal(const String lhs, const String rhs) { return gb_strings_are_equal(lhs, rhs) == GB_TRUE; } gb_inline void trim_string(String& str, char const *cut_set) { str = gb_trim_string(str, cut_set); } + +#ifdef GB_HAS_SNPRINTF +gb_inline void ref_vprintf(String& str, char const *fmt, va_list va) { str = gb_vprintf(str, fmt, va); } +gb_inline void ref_printf(String& str, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + ref_vprintf(str, fmt, va); + va_end(va); +} +#endif + } /* namespace gb */ #endif /* GB_STRING_CPP */ #endif /* GB_STRING_H */ #ifdef GB_STRING_IMPLEMENTATION + static void gb_set_string_length(gbString str, gbUsize len) { GB_STRING_HEADER(str)->len = len; } @@ -320,6 +341,39 @@ static void gb_set_string_capacity(gbString str, gbUsize cap) { GB_STRING_HEADER(str)->cap = cap; } +#ifdef GB_HAS_SNPRINTF +#include +#include + +gbString gb_vprintf(gbString s, char const *fmt, va_list va) { + va_list va2; + int nl; + gbUsize clen = gb_string_length(s); + + va_copy(va2, va); + nl = vsnprintf(NULL, 0, fmt, va2); + va_end(va2); + + if (nl < 0 || nl == INT_MAX) { + gb_free_string(s); + return GB_NULLPTR; + } + + s = gb_string_make_space_for(s, nl + 1); + if (s == GB_NULLPTR) + return GB_NULLPTR; + vsnprintf(s + clen, nl + 1, fmt, va); + return s; +} + +gbString gb_printf(gbString s, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + s = gb_vprintf(s, fmt, va); + va_end(va); + return s; +} +#endif gbString gb_make_string_length(void const *init_str, gbUsize len) { gbString str;