[libvirt] [PATCH 01/14] snapshot: indent domain xml when nesting, round 1
Daniel Veillard
veillard at redhat.com
Tue Sep 27 07:14:17 UTC 2011
On Thu, Sep 22, 2011 at 02:34:55PM -0600, Eric Blake wrote:
> Future patches can take advantage of this to generate nicer
> XML output with parameterizable indentation.
>
> On the side, I had some temporary test failures as I was using
> these functions in later patches, with output that looked like:
>
> Expected [<]
> Actual [ <]
>
> which is pretty hard to figure out. Adding an Offset designation
> made it much easier to find which particular '<' was at the
> wrong indentation, to fix the right part of the code.
>
> * src/util/buf.h (virBufferIndentAdd, virBufferIndentAddLit)
> (virBufferIndentEscapeString): New prototypes and macro.
> * src/libvirt_private.syms (buf.h): Export new functions.
> * src/util/buf.c (virBufferAdd): Move body...
> (virBufferIndentAdd): ...to new function.
> (virBufferIndentEscapeString): New function.
> * tests/virbuftest.c (testBufIndentation): Test it.
> * tests/testutils.c (virtTestDifference): Make it easier to
> diagnose test failures.
> ---
> src/libvirt_private.syms | 2 +
> src/util/buf.c | 70 ++++++++++++++++++++++++++++++++++++---------
> src/util/buf.h | 19 ++++++++++--
> tests/testutils.c | 2 +-
> tests/virbuftest.c | 32 ++++++++++++++++++++-
> 5 files changed, 105 insertions(+), 20 deletions(-)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 8235ea1..1523289 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -28,6 +28,8 @@ virBufferError;
> virBufferEscapeSexpr;
> virBufferEscapeString;
> virBufferFreeAndReset;
> +virBufferIndentAdd;
> +virBufferIndentEscapeString;
> virBufferStrcat;
> virBufferURIEncodeString;
> virBufferUse;
> diff --git a/src/util/buf.c b/src/util/buf.c
> index 5002486..061d83b 100644
> --- a/src/util/buf.c
> +++ b/src/util/buf.c
> @@ -78,21 +78,23 @@ virBufferGrow(virBufferPtr buf, unsigned int len)
> }
>
> /**
> - * virBufferAdd:
> - * @buf: the buffer to add to
> - * @str: the string
> - * @len: the number of bytes to add
> + * virBufferIndentAdd:
> + * @buf: the buffer to add to
> + * @indent: amount of indentation
> + * @str: the string, or NULL to skip indentation
> + * @len: the number of bytes to add
> *
> - * Add a string range to an XML buffer. if len == -1, the length of
> - * str is recomputed to the full string.
> + * Add indentation, then a string range to an XML buffer. if len == -1, the
> + * length of str is recomputed to the full string.
> *
> */
> void
> -virBufferAdd(const virBufferPtr buf, const char *str, int len)
> +virBufferIndentAdd(const virBufferPtr buf, int indent,
> + const char *str, int len)
> {
> unsigned int needSize;
>
> - if ((str == NULL) || (buf == NULL) || (len == 0))
> + if (!str || !buf || (len == 0 && indent == 0))
> return;
>
> if (buf->error)
> @@ -101,17 +103,34 @@ virBufferAdd(const virBufferPtr buf, const char *str, int len)
> if (len < 0)
> len = strlen(str);
>
> - needSize = buf->use + len + 2;
> + needSize = buf->use + indent + len + 2;
> if (needSize > buf->size &&
> virBufferGrow(buf, needSize - buf->use) < 0)
> return;
>
> - memcpy (&buf->content[buf->use], str, len);
> - buf->use += len;
> + memset (&buf->content[buf->use], ' ', indent);
> + memcpy (&buf->content[buf->use + indent], str, len);
> + buf->use += indent + len;
> buf->content[buf->use] = '\0';
> }
>
> /**
> + * virBufferAdd:
> + * @buf: the buffer to add to
> + * @str: the string
> + * @len: the number of bytes to add
> + *
> + * Add a string range to an XML buffer. if len == -1, the length of
> + * str is recomputed to the full string.
> + *
> + */
> +void
> +virBufferAdd(const virBufferPtr buf, const char *str, int len)
> +{
> + virBufferIndentAdd(buf, 0, str, len);
> +}
> +
> +/**
> * virBufferAddChar:
> * @buf: the buffer to add to
> * @c: the character to add
> @@ -120,7 +139,7 @@ virBufferAdd(const virBufferPtr buf, const char *str, int len)
> *
> */
> void
> -virBufferAddChar (virBufferPtr buf, char c)
> +virBufferAddChar(virBufferPtr buf, char c)
> {
> unsigned int needSize;
>
> @@ -290,10 +309,12 @@ virBufferVasprintf(const virBufferPtr buf, const char *format, va_list argptr)
> * @str: the string argument which need to be escaped
> *
> * Do a formatted print with a single string to an XML buffer. The string
> - * is escaped to avoid generating a not well-formed XML instance.
> + * is escaped to avoid generating a not well-formed XML instance. If
> + * @str is NULL, nothing is added (not even the rest of @format).
> */
> void
> -virBufferEscapeString(const virBufferPtr buf, const char *format, const char *str)
> +virBufferEscapeString(const virBufferPtr buf, const char *format,
> + const char *str)
> {
> int len;
> char *escaped, *out;
> @@ -369,6 +390,27 @@ virBufferEscapeString(const virBufferPtr buf, const char *format, const char *st
> }
>
> /**
> + * virBufferIndentEscapeString:
> + * @buf: the buffer to dump
> + * @indent: amount of indentation
> + * @format: a printf like format string but with only one %s parameter
> + * @str: the string argument which need to be escaped, or NULL for no action
> + *
> + * Do a formatted print with a single string to an XML buffer, with leading
> + * indentation. The single %s string is escaped to avoid generating a not
> + * well-formed XML instance.
> + */
> +void
> +virBufferIndentEscapeString(const virBufferPtr buf, int indent,
> + const char *format, const char *str)
> +{
> + if (str) {
> + virBufferIndentAdd(buf, indent, "", 0);
> + virBufferEscapeString(buf, format, str);
> + }
> +}
> +
> +/**
> * virBufferEscapeSexpr:
> * @buf: the buffer to dump
> * @format: a printf like format string but with only one %s parameter
> diff --git a/src/util/buf.h b/src/util/buf.h
> index 06d01ba..c5e2874 100644
> --- a/src/util/buf.h
> +++ b/src/util/buf.h
> @@ -48,11 +48,22 @@ void virBufferVasprintf(const virBufferPtr buf, const char *format, va_list ap)
> ATTRIBUTE_FMT_PRINTF(2, 0);
> void virBufferStrcat(const virBufferPtr buf, ...)
> ATTRIBUTE_SENTINEL;
> -void virBufferEscapeString(const virBufferPtr buf, const char *format, const char *str);
> -void virBufferEscapeSexpr(const virBufferPtr buf, const char *format, const char *str);
> -void virBufferURIEncodeString (const virBufferPtr buf, const char *str);
> +void virBufferEscapeString(const virBufferPtr buf, const char *format,
> + const char *str);
> +void virBufferEscapeSexpr(const virBufferPtr buf, const char *format,
> + const char *str);
> +void virBufferURIEncodeString(const virBufferPtr buf, const char *str);
>
> # define virBufferAddLit(buf_, literal_string_) \
> - virBufferAdd (buf_, "" literal_string_ "", sizeof literal_string_ - 1)
> + virBufferAdd(buf_, "" literal_string_ "", sizeof literal_string_ - 1)
> +
> +void virBufferIndentAdd(const virBufferPtr buf, int indent,
> + const char *str, int len);
> +void virBufferIndentEscapeString(const virBufferPtr buf, int indent,
> + const char *format, const char *str);
> +
> +# define virBufferIndentAddLit(buf_, indent_, literal_string_) \
> + virBufferIndentAdd(buf_, indent_, "" literal_string_ "", \
> + sizeof literal_string_ - 1)
>
> #endif /* __VIR_BUFFER_H__ */
> diff --git a/tests/testutils.c b/tests/testutils.c
> index d9582af..b107d3c 100644
> --- a/tests/testutils.c
> +++ b/tests/testutils.c
> @@ -359,7 +359,7 @@ int virtTestDifference(FILE *stream,
> }
>
> /* Show the trimmed differences */
> - fprintf(stream, "\nExpect [");
> + fprintf(stream, "\nOffset %d\nExpect [", (int) (expectStart - expect));
> if ((expectEnd - expectStart + 1) &&
> fwrite(expectStart, (expectEnd-expectStart+1), 1, stream) != 1)
> return -1;
> diff --git a/tests/virbuftest.c b/tests/virbuftest.c
> index 01db313..0a99e78 100644
> --- a/tests/virbuftest.c
> +++ b/tests/virbuftest.c
> @@ -20,7 +20,7 @@ struct testInfo {
> int doEscape;
> };
>
> -static int testBufInfiniteLoop(const void *data ATTRIBUTE_UNUSED)
> +static int testBufInfiniteLoop(const void *data)
> {
> virBuffer bufinit = VIR_BUFFER_INITIALIZER;
> virBufferPtr buf = &bufinit;
> @@ -63,6 +63,35 @@ out:
> return ret;
> }
>
> +static int testBufIndentation(const void *data ATTRIBUTE_UNUSED)
> +{
> + virBuffer bufinit = VIR_BUFFER_INITIALIZER;
> + virBufferPtr buf = &bufinit;
> + const char expected[] = "ab c d &";
> + char *result = NULL;
> + int ret = 0;
> +
> + virBufferIndentAdd(buf, 0, "a", -1);
> + virBufferIndentAdd(buf, 0, "", -1);
> + virBufferIndentAdd(buf, 0, "", 0);
> + virBufferIndentAddLit(buf, 0, "");
> + virBufferIndentAddLit(buf, 0, "b");
> + virBufferIndentAdd(buf, 3, NULL, -1);
> + virBufferIndentAdd(buf, 2, "c", -1);
> + virBufferIndentAddLit(buf, 1, "");
> + virBufferIndentEscapeString(buf, 1, "%s", "d");
> + virBufferIndentEscapeString(buf, 3, "%s", NULL);
> + virBufferIndentEscapeString(buf, 2, "%s", "&");
> +
> + result = virBufferContentAndReset(buf);
> + if (!result || STRNEQ(result, expected)) {
> + TEST_ERROR("Built buffer was wrong: %s", NULLSTR(result));
> + ret = -1;
> + }
> + VIR_FREE(result);
> + return ret;
> +}
> +
> static int
> mymain(void)
> {
> @@ -78,6 +107,7 @@ mymain(void)
>
> DO_TEST("EscapeString infinite loop", testBufInfiniteLoop, 1);
> DO_TEST("VSprintf infinite loop", testBufInfiniteLoop, 0);
> + DO_TEST("Indentation", testBufIndentation, 0);
>
> return(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
> }
Looks fine to me, ACK
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list