diff --git a/buffer.c b/buffer.c index f5d8efe..94819f5 100644 --- a/buffer.c +++ b/buffer.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -139,6 +140,35 @@ buffer_resize(buffer_t *self, size_t n) { return 0; } +/* + * Append a printf-style formatted string to the buffer. + */ +int buffer_appendf(buffer_t *self, const char *format, ...) { + va_list ap; + va_start(ap, format); + const int initial_len = buffer_length(self); + + // First, we compute how many bytes are needed for the formatted string + // and allocate that much more space in the buffer. + va_list tmpa; + va_copy(tmpa, ap); + const int space_required = vsnprintf(NULL, 0, format, tmpa); + va_end(tmpa); + const int resized = buffer_resize(self, initial_len + space_required); + if (resized == -1) { + va_end(ap); + return -1; + } + + // Next format the string into the space that we have made room for. + char* dst = self->data + initial_len; + const int bytes_formatted = vsnprintf(dst, 1+space_required, format, ap); + + printf("Result '%s'\n", self->data); + va_end(ap); + return (bytes_formatted < 0) ? -1 : 0; +} + /* * Append `str` to `self` and return 0 on success, -1 on failure. */ diff --git a/buffer.h b/buffer.h index 5826b56..5cecbb0 100644 --- a/buffer.h +++ b/buffer.h @@ -60,6 +60,9 @@ buffer_prepend(buffer_t *self, char *str); int buffer_append(buffer_t *self, const char *str); +int +buffer_appendf(buffer_t *self, const char *format, ...); + int buffer_append_n(buffer_t *self, const char *str, size_t len); diff --git a/test.c b/test.c index 0c750dd..cb6299d 100644 --- a/test.c +++ b/test.c @@ -148,6 +148,17 @@ test_buffer_equals() { buffer_free(b); } +void test_buffer_formatting() { + buffer_t *buf = buffer_new(); + int result = buffer_appendf(buf, "%d %s", 3, "cow"); + assert(0 == result); + equal("3 cow", buffer_string(buf)); + result = buffer_appendf(buf, " - 0x%08X", 0xdeadbeef); + assert(0 == result); + equal("3 cow - 0xDEADBEEF", buffer_string(buf)); + buffer_free(buf); +} + void test_buffer_indexof() { buffer_t *buf = buffer_new_with_copy("Tobi is a ferret"); @@ -231,6 +242,7 @@ main(){ test_buffer_slice__end(); test_buffer_slice__end_overflow(); test_buffer_equals(); + test_buffer_formatting(); test_buffer_indexof(); test_buffer_fill(); test_buffer_clear();