
On 09/30/2011 12:22 AM, Eric Blake wrote:
Rather than having to adjust all callers in a chain to deal with indentation, it is nicer to have virBuffer do auto-indentation.
* src/util/buf.h (_virBuffer): Increase size. (virBufferAdjustIndent, virBufferGetIndent): New prototypes. * src/libvirt_private.syms (buf.h): Export new functions. * src/util/buf.c (virBufferAdjustIndent, virBufferGetIndent): New functions. (virBufferSetError, virBufferAdd, virBufferAddChar) (virBufferVasprintf, virBufferStrcat, virBufferURIEncodeString): Implement auto-indentation. * tests/virbuftest.c (testBufAutoIndent): Test it. (testBufInfiniteLoop): Don't rely on internals. Idea by Daniel P. Berrange. --- src/libvirt_private.syms | 2 + src/util/buf.c | 138 ++++++++++++++++++++++++++++----------------- src/util/buf.h | 12 +++- tests/virbuftest.c | 85 +++++++++++++++++++++++++--- 4 files changed, 172 insertions(+), 65 deletions(-)
+static int testBufAutoIndent(const void *data ATTRIBUTE_UNUSED) +{ + virBuffer bufinit = VIR_BUFFER_INITIALIZER; + virBufferPtr buf =&bufinit; + const char expected[] = + " 1\n 2\n 3\n 4\n 5\n 6\n 7\n&\n 8\n 9\n"; + char *result = NULL; + int ret = 0; + + if (virBufferGetIndent(buf, false) != 0 || + virBufferGetIndent(buf, true) != 0) { + TEST_ERROR("Wrong indentation"); + ret = -1; + } + virBufferAdjustIndent(buf, 3); + if (virBufferGetIndent(buf, false) != 3 || + virBufferGetIndent(buf, true) != 3 || + virBufferError(buf)) { + TEST_ERROR("Wrong indentation"); + ret = -1; + } + virBufferAdjustIndent(buf, -2); + if (virBufferGetIndent(buf, false) != 1 || + virBufferGetIndent(buf, true) != 1 || + virBufferError(buf)) { + TEST_ERROR("Wrong indentation"); + ret = -1; + } + virBufferAdjustIndent(buf, -2); + if (virBufferGetIndent(buf, false) != -1 || + virBufferGetIndent(buf, true) != -1 || + virBufferError(buf) != -1) { + TEST_ERROR("Usage error not flagged"); + ret = -1; + } + virBufferFreeAndReset(buf); + if (virBufferGetIndent(buf, false) != 0 || + virBufferGetIndent(buf, true) != 0 || + virBufferError(buf)) { + TEST_ERROR("Reset didn't clear indentation"); + ret = -1; + } + virBufferAdjustIndent(buf, 2); + virBufferAddLit(buf, "1"); + if (virBufferGetIndent(buf, false) != 2 || + virBufferGetIndent(buf, true) != 0) { + TEST_ERROR("Wrong indentation"); + ret = -1; + } + virBufferAddLit(buf, "\n"); + virBufferAdd(buf, "" "2\n", -1); /* Extra "" appeases syntax-check */ + virBufferAddChar(buf, '3'); + virBufferAddChar(buf, '\n'); + virBufferAsprintf(buf, "%d", 4); + virBufferAsprintf(buf, "%c", '\n'); + virBufferStrcat(buf, "5", "\n", "6\n", NULL); + virBufferEscapeString(buf, "%s\n", "7"); + virBufferEscapeString(buf, "%s\n", "&"); + virBufferEscapeSexpr(buf, "%s", "8\n"); + virBufferURIEncodeString(buf, "9"); + virBufferAddChar(buf, '\n'); + + result = virBufferContentAndReset(buf); + if (!result || STRNEQ(result, expected)) { + virtTestDifference(stderr, expected, result); + ret = -1; + } + VIR_FREE(result); + return ret; +} Let me express my appreciation towards this testBufAutoIndent() function, by the way. It's beautiful. + static int mymain(void) { @@ -78,6 +144,7 @@ mymain(void)
DO_TEST("EscapeString infinite loop", testBufInfiniteLoop, 1); DO_TEST("VSprintf infinite loop", testBufInfiniteLoop, 0); + DO_TEST("Auto-indentation", testBufAutoIndent, 0);
return(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE); }