diff --git a/arena.h b/arena.h index 7ec4c8f..225c141 100644 --- a/arena.h +++ b/arena.h @@ -141,6 +141,51 @@ void arena_trim(Arena *a); // use it a NULL-terminated C string #define arena_sb_append_null(a, sb) arena_da_append(a, sb, 0) +#ifndef ARENA_NOSTDIO +// Append a formatted string to a string builder using a va_list. +// The terminating NULL character is NOT included in the builder. +// So that you can use it repeatedly without having annoying zeros in between. +#define arena_sb_append_vformat(a, sb, format, va_args) \ + do { \ + va_list args_copy; \ + va_copy(args_copy, va_args); \ + int n = vsnprintf(NULL, 0, format, args_copy); \ + va_end(args_copy); \ + if ((sb)->count + n+1 > (sb)->capacity) { \ + size_t new_capacity = (sb)->capacity; \ + if (new_capacity == 0) new_capacity = ARENA_DA_INIT_CAP; \ + while ((sb)->count + n+1 > new_capacity) new_capacity *= 2; \ + (sb)->items = cast_ptr((sb)->items)arena_realloc( \ + (a), (sb)->items, \ + (sb)->capacity*sizeof(*(sb)->items), \ + new_capacity*sizeof(*(sb)->items)); \ + (sb)->capacity = new_capacity; \ + } \ + vsnprintf((sb)->items + (sb)->count, n+1, format, va_args); \ + (sb)->count += n; \ + } while(0) + +// Append a formatted string to a string builder using a variable number of macro arguments. +// The terminating NULL character is NOT included in the builder. +// So that you can use it repeatedly without having annoying zeros in between. +#define arena_sb_append_format(a, sb, format, ...) \ + do { \ + int n = snprintf(NULL, 0, format, __VA_ARGS__); \ + if ((sb)->count + n+1 > (sb)->capacity) { \ + size_t new_capacity = (sb)->capacity; \ + if (new_capacity == 0) new_capacity = ARENA_DA_INIT_CAP; \ + while ((sb)->count + n+1 > new_capacity) new_capacity *= 2; \ + (sb)->items = cast_ptr((sb)->items)arena_realloc( \ + (a), (sb)->items, \ + (sb)->capacity*sizeof(*(sb)->items), \ + new_capacity*sizeof(*(sb)->items)); \ + (sb)->capacity = new_capacity; \ + } \ + snprintf((sb)->items + (sb)->count, n+1, format, __VA_ARGS__); \ + (sb)->count += n; \ + } while(0) +#endif // ARENA_NOSTDIO + #endif // ARENA_H_ #ifdef ARENA_IMPLEMENTATION diff --git a/examples/001_basic_usage/main.c b/examples/001_basic_usage/main.c index 9ce98d2..96b501c 100644 --- a/examples/001_basic_usage/main.c +++ b/examples/001_basic_usage/main.c @@ -39,6 +39,10 @@ int main() // Append sized buffer arena_sb_append_buf(&a, &sb, name, sizeof(name)); + // Append using format strings + arena_sb_append_format(&a, &sb, "\n%d", 5); + arena_sb_append_format(&a, &sb, " %s", "foo"); + // Append '\0' to make the built string NULL-terminated arena_sb_append_null(&a, &sb);