[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH 01/14] snapshot: indent domain xml when nesting, round 1



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  &amp;";
> +    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 veillard com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]