virBufferAdd(buf, str, -1);
va_end(ap);
}
+
+/**
+ * virBufferTrim:
+ * @buf: the buffer to trim
+ * @str: the optional string, to force an exact trim
+ * @len: the number of bytes to trim, or -1 to use @str
+ *
+ * Trim the tail of a buffer. If @str is provided, the trim only occurs
+ * if the current tail of the buffer matches @str; a non-negative @len
+ * further limits how much of the tail is trimmed. If @str is NULL, then
+ * @len must be non-negative.
+ *
+ * Returns -1 if @buf has previously encountered an error or if @len is
+ * invalid, 0 if there was nothing to trim (@buf was too short or @str
+ * didn't match), and 1 if the trim was successful.
+ */
+int
+virBufferTrim(virBufferPtr buf, const char *str, int len)
+{
+ size_t len2 = 0;
+
+ if (!buf || buf->error || (!str && len < 0))
+ return -1;
+
+ if (len > 0 && len > buf->use)
+ return 0;
+ if (str) {
+ len2 = strlen(str);
+ if (len2 > buf->use ||
+ memcmp(&buf->content[buf->use - len2], str, len2) != 0)
+ return 0;
+ }
+ buf->use -= len < 0 ? len2 : len;
+ buf->content[buf->use] = '\0';
+ return 1;
+}
void virBufferAdjustIndent(virBufferPtr buf, int indent);
int virBufferGetIndent(const virBufferPtr buf, bool dynamic);
+int virBufferTrim(virBufferPtr buf, const char *trim, int len);
+
#endif /* __VIR_BUFFER_H__ */
return ret;
}
+static int testBufTrim(const void *data ATTRIBUTE_UNUSED)
+{
+ virBuffer bufinit = VIR_BUFFER_INITIALIZER;
+ virBufferPtr buf = NULL;
+ char *result = NULL;
+ const char *expected = "a,b";
+ int ret = -1;
+ int i = 1;
+
+#define ACT(str, len, result) \
+ do { \
+ if (virBufferTrim(buf, str, len) != result) { \
+ TEST_ERROR("trim %d failed", i); \
+ goto cleanup; \
+ } \
+ i++; \
+ } while (0);
+
+ if (virBufferTrim(buf, "", 0) != -1) {
+ TEST_ERROR("Wrong failure detection 1");
+ goto cleanup;
+ }
+ buf = &bufinit;
+ if (virBufferTrim(buf, NULL, -1) != -1) {
+ TEST_ERROR("Wrong failure detection 2");
+ goto cleanup;
+ }
+
+ virBufferAddLit(buf, "a;");
+ ACT("", 0, 1);
+ ACT("", -1, 1);
+ ACT(NULL, 1, 1);
+ ACT(NULL, 5, 0);
+ ACT("a", 2, 0);
+
+ virBufferAddLit(buf, ",b,,");
+ ACT("b", -1, 0);
+ ACT("b,,", 1, 1);
+ ACT(",", -1, 1);
+
+ result = virBufferContentAndReset(buf);
+ if (!result || STRNEQ(result, expected)) {
+ virtTestDifference(stderr, expected, result);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ virBufferFreeAndReset(buf);
+ VIR_FREE(result);
+ return ret;
+}
+
+
static int
mymain(void)
{
DO_TEST("EscapeString infinite loop", testBufInfiniteLoop, 1);
DO_TEST("VSprintf infinite loop", testBufInfiniteLoop, 0);
DO_TEST("Auto-indentation", testBufAutoIndent, 0);
+ DO_TEST("Trim", testBufTrim, 0);
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}