Skip to content

Instantly share code, notes, and snippets.

@nanokatze
Last active October 18, 2021 12:37
Show Gist options
  • Save nanokatze/1798ecbca2526ab9d30d0bf5357c2033 to your computer and use it in GitHub Desktop.
Save nanokatze/1798ecbca2526ab9d30d0bf5357c2033 to your computer and use it in GitHub Desktop.
typedef struct StringBuilder StringBuilder;
struct StringBuilder {
char *data;
size_t len;
size_t cap;
};
static void sbprintf(StringBuilder*, const char*, ...) __attribute__((format(printf, 2, 3)));
int
sbprintf(StringBuilder *b, const char *format, ...)
{
assert(b->len <= b->cap);
again:;
char *data = NULL;
if (b->cap > 0)
data = b->data + b->len;
va_list arg;
va_start(arg, format);
int r = vsnprintf(data, b->cap-b->len, format, arg);
va_end(arg);
if (r <= 0)
return r;
size_t n = (size_t)r;
size_t newcap = b->cap;
while (newcap-b->len < n+1) {
newcap = 2*newcap + (newcap == 0);
assert(newcap >= b->cap); // ensure we don't wrap around
}
if (b->cap < newcap) {
b->data = erealloc(b->data, newcap);
b->cap = newcap;
goto again;
}
b->len += n;
b->data[b->len] = '\0';
return r;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment