vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
commit a114c4be0d67986adedde955ff44edc85449152b parent 8855c7e1f6c2a816459ff173e16ec8b71b048eb4 Author: Marc André Tanner <mat@brain-dump.org> Date: Tue, 20 Dec 2016 19:02:54 +0100 buffer: implement buffer_appendf to append formatted content Diffstat:
| M | buffer.c | | | 36 | +++++++++++++++++++++++------------- |
| M | buffer.h | | | 5 | +++-- |
2 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/buffer.c b/buffer.c @@ -109,29 +109,39 @@ bool buffer_prepend0(Buffer *buf, const char *data) { return buffer_prepend(buf, data, strlen(data) + (buf->len == 0)); } -bool buffer_printf(Buffer *buf, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - bool ret = buffer_vprintf(buf, fmt, ap); - va_end(ap); - return ret; -} - -bool buffer_vprintf(Buffer *buf, const char *fmt, va_list ap) { +static bool buffer_vappendf(Buffer *buf, const char *fmt, va_list ap) { va_list ap_save; va_copy(ap_save, ap); int len = vsnprintf(NULL, 0, fmt, ap); - if (len == -1 || !buffer_grow(buf, len+1)) { + if (len == -1 || !buffer_grow(buf, buf->len+len+1)) { va_end(ap_save); return false; } - bool ret = vsnprintf(buf->data, len+1, fmt, ap_save) == len; - if (ret) - buf->len = len+1; + size_t nul = (buf->len > 0 && buf->data[buf->len-1] == '\0') ? 1 : 0; + buf->len -= nul; + bool ret = vsnprintf(buf->data+buf->len, len+1, fmt, ap_save) == len; + buf->len += ret ? (size_t)len+1 : nul; va_end(ap_save); return ret; } +bool buffer_appendf(Buffer *buf, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + bool ret = buffer_vappendf(buf, fmt, ap); + va_end(ap); + return ret; +} + +bool buffer_printf(Buffer *buf, const char *fmt, ...) { + buffer_clear(buf); + va_list ap; + va_start(ap, fmt); + bool ret = buffer_vappendf(buf, fmt, ap); + va_end(ap); + return ret; +} + size_t buffer_length0(Buffer *buf) { size_t len = buf->len; if (len > 0 && buf->data[len-1] == '\0') diff --git a/buffer.h b/buffer.h @@ -42,9 +42,10 @@ bool buffer_append0(Buffer*, const char *data); bool buffer_prepend(Buffer*, const void *data, size_t len); /* prepend NUL-terminated data */ bool buffer_prepend0(Buffer*, const char *data); - +/* set formatted buffer content, ensures NUL termination on success */ bool buffer_printf(Buffer*, const char *fmt, ...); -bool buffer_vprintf(Buffer*, const char *fmt, va_list); +/* append formatted buffer content, ensures NUL termination on success */ +bool buffer_appendf(Buffer*, const char *fmt, ...); /* return length of a buffer without trailing NUL byte */ size_t buffer_length0(Buffer*); /* return length of a buffer including possible NUL byte */