Check if the buffer is in error state and report an error if it is.
This replaces the pattern:
if (virBufferError(buf)) {
virReportOOMError();
goto cleanup;
}
with:
if (virBufferCheckError(buf) < 0)
goto cleanup;
Document typical buffer usage to favor this.
Also remove the redundant FreeAndReset - if an error has
been set via virBufferSetError, the content is already freed.
---
HACKING | 7 ++-----
docs/hacking.html.in | 7 ++-----
po/POTFILES.in | 1 +
src/libvirt_private.syms | 1 +
src/util/virbuffer.c | 31 +++++++++++++++++++++++++++++++
src/util/virbuffer.h | 17 +++++++++++++++++
6 files changed, 54 insertions(+), 10 deletions(-)
diff --git a/HACKING b/HACKING
index ac3e9d7..0745d5f 100644
--- a/HACKING
+++ b/HACKING
@@ -776,7 +776,7 @@ Variable length string buffer
=============================
If there is a need for complex string concatenations, avoid using the usual
sequence of malloc/strcpy/strcat/snprintf functions and make use of the
-virBuffer API described in buf.h
+virBuffer API described in virbuffer.h
Typical usage is as follows:
@@ -794,11 +794,8 @@ Typical usage is as follows:
...
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- virReportOOMError();
+ if (virBufferCheckError(&buf) < 0)
return NULL;
- }
return virBufferContentAndReset(&buf);
}
diff --git a/docs/hacking.html.in b/docs/hacking.html.in
index 9c6dd26..9456520 100644
--- a/docs/hacking.html.in
+++ b/docs/hacking.html.in
@@ -948,7 +948,7 @@
<p>
If there is a need for complex string concatenations, avoid using
the usual sequence of malloc/strcpy/strcat/snprintf functions and
- make use of the virBuffer API described in buf.h
+ make use of the virBuffer API described in virbuffer.h
</p>
<p>Typical usage is as follows:</p>
@@ -968,11 +968,8 @@
...
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- virReportOOMError();
+ if (virBufferCheckError(&buf) < 0)
return NULL;
- }
return virBufferContentAndReset(&buf);
}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 31a8381..d338151 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -156,6 +156,7 @@ src/util/viraudit.c
src/util/virauth.c
src/util/virauthconfig.c
src/util/virbitmap.c
+src/util/virbuffer.c
src/util/vircgroup.c
src/util/virclosecallbacks.c
src/util/vircommand.c
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ed56103..cc5fd32 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1008,6 +1008,7 @@ virBufferAdd;
virBufferAddChar;
virBufferAdjustIndent;
virBufferAsprintf;
+virBufferCheckErrorInternal;
virBufferContentAndReset;
virBufferCurrentContent;
virBufferError;
diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
index eb29012..025f0ab 100644
--- a/src/util/virbuffer.c
+++ b/src/util/virbuffer.c
@@ -32,6 +32,7 @@
#include "virbuffer.h"
#include "viralloc.h"
+#include "virerror.h"
/* If adding more fields, ensure to edit buf.h to match
@@ -264,6 +265,36 @@ virBufferError(const virBuffer *buf)
}
/**
+ * virBufferCheckErrorInternal:
+ * @buf: the buffer
+ *
+ * Report an error if the buffer is in an error state.
+ *
+ * Return -1 if an error has been reported, 0 otherwise.
+ */
+int
+virBufferCheckErrorInternal(const virBuffer *buf,
+ int domcode,
+ const char *filename,
+ const char *funcname,
+ size_t linenr)
+{
+ if (buf->error == 0)
+ return 0;
+
+ if (buf->error == ENOMEM) {
+ virReportOOMErrorFull(domcode, filename, funcname, linenr);
+ errno = ENOMEM;
+ } else {
+ virReportErrorHelper(domcode, VIR_ERR_INTERNAL_ERROR, filename,
+ funcname, linenr, "%s",
+ _("Invalid buffer API usage"));
+ errno = EINVAL;
+ }
+ return -1;
+}
+
+/**
* virBufferUse:
* @buf: the usage of the string in the buffer
*
diff --git a/src/util/virbuffer.h b/src/util/virbuffer.h
index a0cc4e6..bdfff5e 100644
--- a/src/util/virbuffer.h
+++ b/src/util/virbuffer.h
@@ -53,6 +53,23 @@ const char *virBufferCurrentContent(virBufferPtr buf);
char *virBufferContentAndReset(virBufferPtr buf);
void virBufferFreeAndReset(virBufferPtr buf);
int virBufferError(const virBuffer *buf);
+int virBufferCheckErrorInternal(const virBuffer *buf,
+ int domcode,
+ const char *filename,
+ const char *funcname,
+ size_t linenr)
+ ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
+/**
+ * virBufferCheckError
+ *
+ * Checks if the buffer is in error state and reports an error.
+ *
+ * Returns 0 if no error has occured, otherwise an error is reported
+ * and -1 is returned.
+ */
+# define virBufferCheckError(buf) \
+ virBufferCheckErrorInternal(buf, VIR_FROM_THIS, __FILE__, __FUNCTION__, \
+ __LINE__)
unsigned int virBufferUse(const virBuffer *buf);
void virBufferAdd(virBufferPtr buf, const char *str, int len);
void virBufferAddChar(virBufferPtr buf, char c);
--
1.8.5.5