From e67e03acebe7b00abd416bf29ed545e869a5ed1e Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 4 Feb 2011 17:18:21 +0100 Subject: [PATCH] strbuf: added strbuf_avail and strbuf_appendf. --- Makefile.include | 2 +- docs/technical/strbuf.txt | 8 ++++++++ src/strbuf.c | 34 ++++++++++++++++++++++++++++++++++ src/strbuf.h | 4 ++++ test/t_strbuf.c | 12 ++++++++++++ 5 files changed, 59 insertions(+), 1 deletion(-) diff --git a/Makefile.include b/Makefile.include index 84a7c56..3792125 100644 --- a/Makefile.include +++ b/Makefile.include @@ -20,7 +20,7 @@ ifdef NO_MEMRCHR endif obj-xalloc = src/xalloc.o src/die.o obj-str-list = src/str-list.o $(obj-xalloc) -obj-strbuf = src/strbuf.o $(obj-xalloc) +obj-strbuf = src/strbuf.o $(obj-xalloc) src/die.o obj-path = src/path.o $(obj-strbuf) obj-rbtree = src/rbtree.o $(obj-xalloc) obj-fscrawl = src/fscrawl.o $(obj-strbuf) $(obj-path) $(obj-log) diff --git a/docs/technical/strbuf.txt b/docs/technical/strbuf.txt index efb374b..6b712cb 100644 --- a/docs/technical/strbuf.txt +++ b/docs/technical/strbuf.txt @@ -30,11 +30,19 @@ Functions This function will not allocate memory, it only sets ->len and assure that the string is null-terminated at the new position. +`strbuf_avail()`:: + + Returns the number of characters that are allocated but not used in the buffer. + `strbuf_append()`:: This function will append the buffer with the contents of 'ptr' and will always copy exactly 'len' bytes. (if memory can be obtained ofcourse) +`strbuf_appendf()`:: + + Adds the formated-string 'fmt' to the end of ->buf. + `strbuf_append_str()`:: Will add the 'str' C-string to the end of ->buf diff --git a/src/strbuf.c b/src/strbuf.c index 61229d4..57be4ee 100644 --- a/src/strbuf.c +++ b/src/strbuf.c @@ -9,7 +9,10 @@ */ #include +#include +#include #include "compat/string.h" +#include "util.h" #include "xalloc.h" #include "strbuf.h" @@ -23,6 +26,11 @@ void strbuf_init(strbuf_t *s) { s->alloc_size = s->len = 0; } +size_t strbuf_avail(strbuf_t *s) { + + return s->alloc_size ? s->alloc_size - (s->len + 1) : 0; +} + void strbuf_expand(strbuf_t *s, size_t len) { if (s->len + len + 1 < s->alloc_size) @@ -112,6 +120,32 @@ void strbuf_append(strbuf_t *s, const void *ptr, size_t len) { s->buf[s->len] = '\0'; } +void strbuf_appendf(strbuf_t *s, const char *fmt, ...) { + + va_list vl; + int len; + + if (!strbuf_avail(s)) + strbuf_expand(s, CHNK_SIZE-1); + + va_start(vl, fmt); + len = vsnprintf(s->buf + s->len, s->alloc_size - s->len, fmt, vl); + va_end(vl); + + if (len < 0) + die_errno("vsnprintf"); + if (len > strbuf_avail(s)) { + strbuf_expand(s, len); + va_start(vl, fmt); + len = vsnprintf(s->buf + s->len, s->alloc_size - s->len, fmt, vl); + va_end(vl); + if (len > strbuf_avail(s)) + die_errno("vsnprintf"); + } + s->len += len; + s->buf[len] = '\0'; +} + void strbuf_append_str(strbuf_t *s, const char *str) { strbuf_append(s, str, strlen(str)); diff --git a/src/strbuf.h b/src/strbuf.h index bf29f50..919eaeb 100644 --- a/src/strbuf.h +++ b/src/strbuf.h @@ -25,6 +25,8 @@ extern char strbuf_null; void strbuf_init(strbuf_t *s); +size_t strbuf_avail(strbuf_t *s); + void strbuf_expand(strbuf_t *s, size_t len); void strbuf_reduce(strbuf_t *s, size_t len); @@ -41,6 +43,8 @@ void strbuf_attach(strbuf_t *s, void *str, size_t len, size_t alloc_size); void strbuf_append(strbuf_t *s, const void *ptr, size_t len); +void strbuf_appendf(strbuf_t *s, const char *fmt, ...); + void strbuf_append_str(strbuf_t *s, const char *str); void strbuf_append_ch(strbuf_t *s, char ch); diff --git a/test/t_strbuf.c b/test/t_strbuf.c index 514335a..2e94612 100644 --- a/test/t_strbuf.c +++ b/test/t_strbuf.c @@ -39,6 +39,17 @@ void test_setlen() { strbuf_free(&b); } +void test_appendf() { + + strbuf_t b = STRBUF_INIT; + + strbuf_appendf(&b, "%s %i", "string", 32); + + print_strbuf(&b); + + strbuf_free(&b); +} + void test_release() { strbuf_t b = STRBUF_INIT; @@ -216,6 +227,7 @@ void test_free_empty() { int main() { + test_appendf(); test_release_empty(); test_release(); test_setlen();