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);
}