From 39232280d1871eebaf9f4cc72ea0e1a632540e4e Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Tue, 24 Mar 2015 10:53:29 +0100 Subject: [PATCH] util: buffer: Add support for adding text blocks with indentation The current auto-indentation buffer code applies indentation only on complete strings. To allow adding a string containing newlines and having it properly indented this patch adds virBufferAddStr. (cherry picked from commit 6ff59cbc8367856f12f4eef5755eeccade36d8cf) --- src/libvirt_private.syms | 1 + src/util/virbuffer.c | 29 ++++++++++++++++++++++++ src/util/virbuffer.h | 1 + tests/virbuftest.c | 49 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5d54861120..6674c679dc 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1083,6 +1083,7 @@ virBitmapToData; virBufferAdd; virBufferAddBuffer; virBufferAddChar; +virBufferAddStr; virBufferAdjustIndent; virBufferAsprintf; virBufferCheckErrorInternal; diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c index 96a0f16d57..b5639a83d2 100644 --- a/src/util/virbuffer.c +++ b/src/util/virbuffer.c @@ -752,3 +752,32 @@ virBufferTrim(virBufferPtr buf, const char *str, int len) buf->use -= len < 0 ? len2 : len; buf->content[buf->use] = '\0'; } + + +/** + * virBufferAddStr: + * @buf: the buffer to append to + * @str: string to append + * + * Appends @str to @buffer. Applies autoindentation on the separate lines of + * @str. + */ +void +virBufferAddStr(virBufferPtr buf, + const char *str) +{ + const char *end; + + if (!buf || !str || buf->error) + return; + + while (*str) { + if ((end = strchr(str, '\n'))) { + virBufferAdd(buf, str, (end - str) + 1); + str = end + 1; + } else { + virBufferAdd(buf, str, -1); + break; + } + } +} diff --git a/src/util/virbuffer.h b/src/util/virbuffer.h index 24e81c766c..144a1ba06e 100644 --- a/src/util/virbuffer.h +++ b/src/util/virbuffer.h @@ -96,5 +96,6 @@ void virBufferAdjustIndent(virBufferPtr buf, int indent); int virBufferGetIndent(const virBuffer *buf, bool dynamic); void virBufferTrim(virBufferPtr buf, const char *trim, int len); +void virBufferAddStr(virBufferPtr buf, const char *str); #endif /* __VIR_BUFFER_H__ */ diff --git a/tests/virbuftest.c b/tests/virbuftest.c index f964febd27..21cb18b4aa 100644 --- a/tests/virbuftest.c +++ b/tests/virbuftest.c @@ -310,6 +310,43 @@ static int testBufAddBuffer(const void *data ATTRIBUTE_UNUSED) return ret; } +struct testBufAddStrData { + const char *data; + const char *expect; +}; + +static int +testBufAddStr(const void *opaque ATTRIBUTE_UNUSED) +{ + const struct testBufAddStrData *data = opaque; + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *actual; + int ret = -1; + + virBufferAddLit(&buf, "\n"); + virBufferAdjustIndent(&buf, 2); + virBufferAddStr(&buf, data->data); + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, ""); + + if (!(actual = virBufferContentAndReset(&buf))) { + TEST_ERROR("buf is empty"); + goto cleanup; + } + + if (STRNEQ_NULLABLE(actual, data->expect)) { + TEST_ERROR("testBufAddStr(): Strings don't match:\n"); + virtTestDifference(stderr, data->expect, actual); + goto cleanup; + } + + ret = 0; + + cleanup: + VIR_FREE(actual); + return ret; +} + static int mymain(void) @@ -330,6 +367,18 @@ mymain(void) DO_TEST("Trim", testBufTrim, 0); DO_TEST("AddBuffer", testBufAddBuffer, 0); +#define DO_TEST_ADD_STR(DATA, EXPECT) \ + do { \ + struct testBufAddStrData info = { DATA, EXPECT }; \ + if (virtTestRun("Buf: AddStr", testBufAddStr, &info) < 0) \ + ret = -1; \ + } while (0) + + DO_TEST_ADD_STR("", "\n"); + DO_TEST_ADD_STR("", "\n "); + DO_TEST_ADD_STR("\n", "\n \n"); + DO_TEST_ADD_STR("\n \n\n", "\n \n \n \n"); + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }