Skip to content

Conversation

@Pecora0
Copy link
Contributor

@Pecora0 Pecora0 commented Aug 27, 2025

I figured it would be nice to append to a string builder the same way we do to a file with format strings and printf-type functions.
Because string builder are user-defined structure we need to use macros. I introduced two of them: arena_sb_append_format and arena_sb_append_vformat.

arena_sb_append_format enables us to do stuff like

arena_sb_append_format(&a, &sb, "\n%d", 5);
arena_sb_append_format(&a, &sb, " %s", "foo")

where sb is a predefined string builder (see example 001).

Note that arena_sb_append_format behaves differently to arena_sprintf:
arena_sprintf allocates a new buffer and copies the character data into it.
On the other hand, arena_sb_append_format appends into an existing string builder so it might not even do further allocations!

Furthermore note that we need to take into account that printf-type functions put a NULL character at the end of the string.
So the capacity of the string builder needs to be big enough to hold that extra zero but when updating the count we only count the characters before the terminating NULL.
That way we can run arena_sb_append_format repeatedly without having to deal with a zero between two calls.

The use case for arena_append_vformatis probably rare but I might as well include it.
One could imagine a function that behaves like arena_sb_append_format and uses arena_append_vformat:

void appendf(Arena *a, String_Builder *sb, const char *format, ...) {
    va_list args;
    va_start(args, format);
    arena_sb_append_vformat(a, sb, format, args);
    va_end(args);
}

Sadly I don't see a possibility to express arena_sb_append_format in terms of arena_sb_append_vformat nicely. We would need to convert a (preprocessing-time) macro argument list to a (compile-time) function argument list.

@Pecora0
Copy link
Contributor Author

Pecora0 commented Aug 28, 2025

(Of course arena_append_format and arena_append_vformat need stdio.h so I put them behind an ARENA_NOSTDIO guard)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant