A new helper for trimming combinations of specified characters from
the tail of the buffer.
Signed-off-by: Ján Tomko <jtomko(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virbuffer.c | 26 ++++++++++++++++++++++++++
src/util/virbuffer.h | 1 +
tests/virbuftest.c | 36 ++++++++++++++++++++++++++++++++++++
4 files changed, 64 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b97906b852..f46ed29eac 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1642,6 +1642,7 @@ virBufferSetIndent;
virBufferStrcat;
virBufferStrcatVArgs;
virBufferTrim;
+virBufferTrimChars;
virBufferURIEncodeString;
virBufferUse;
virBufferVasprintf;
diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
index 1b93110919..914c386b18 100644
--- a/src/util/virbuffer.c
+++ b/src/util/virbuffer.c
@@ -673,6 +673,32 @@ virBufferTrim(virBufferPtr buf, const char *str, int len)
g_string_truncate(buf->str, buf->str->len - len);
}
+/**
+ * virBufferTrimChars:
+ * @buf: the buffer to trim
+ * @trim: the characters to be trimmed
+ *
+ * Trim the tail of the buffer. The longest string that can be formed with
+ * the characters from @trim is trimmed.
+ */
+void
+virBufferTrimChars(virBufferPtr buf, const char *trim)
+{
+ ssize_t i;
+
+ if (!buf || !buf->str)
+ return;
+
+ if (!trim)
+ return;
+
+ for (i = buf->str->len - 1; i > 0; i--) {
+ if (!strchr(trim, buf->str->str[i]))
+ break;
+ }
+
+ g_string_truncate(buf->str, i + 1);
+}
/**
* virBufferAddStr:
diff --git a/src/util/virbuffer.h b/src/util/virbuffer.h
index 38758a9125..183f78f279 100644
--- a/src/util/virbuffer.h
+++ b/src/util/virbuffer.h
@@ -92,4 +92,5 @@ size_t virBufferGetIndent(const virBuffer *buf);
size_t virBufferGetEffectiveIndent(const virBuffer *buf);
void virBufferTrim(virBufferPtr buf, const char *trim, int len);
+void virBufferTrimChars(virBufferPtr buf, const char *trim);
void virBufferAddStr(virBufferPtr buf, const char *str);
diff --git a/tests/virbuftest.c b/tests/virbuftest.c
index 1780b62bf4..7919075000 100644
--- a/tests/virbuftest.c
+++ b/tests/virbuftest.c
@@ -12,6 +12,7 @@
struct testBufAddStrData {
const char *data;
const char *expect;
+ const char *arg;
};
static int testBufAutoIndent(const void *data G_GNUC_UNUSED)
@@ -130,6 +131,30 @@ static int testBufTrim(const void *data G_GNUC_UNUSED)
return ret;
}
+static int
+testBufTrimChars(const void *opaque)
+{
+ const struct testBufAddStrData *data = opaque;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ g_autofree char *actual = NULL;
+
+ virBufferAddStr(&buf, data->data);
+ virBufferTrimChars(&buf, data->arg);
+
+ if (!(actual = virBufferContentAndReset(&buf))) {
+ VIR_TEST_DEBUG("buf is empty");
+ return -1;
+ }
+
+ if (STRNEQ_NULLABLE(actual, data->expect)) {
+ VIR_TEST_DEBUG("testBufEscapeStr(): Strings don't match:");
+ virTestDifference(stderr, data->expect, actual);
+ return -1;
+ }
+
+ return 0;
+}
+
static int testBufAddBuffer(const void *data G_GNUC_UNUSED)
{
virBuffer buf1 = VIR_BUFFER_INITIALIZER;
@@ -411,6 +436,17 @@ mymain(void)
DO_TEST_ESCAPE_REGEX("^$.|?*+()[]{}\\",
"\\^\\$\\.\\|\\?\\*\\+\\(\\)\\[\\]\\{\\}\\\\");
+#define DO_TEST_TRIM_CHARS(_data, _arg, _expect) \
+ do { \
+ struct testBufAddStrData info = { .data = _data, .expect = _expect, .arg = _arg
}; \
+ if (virTestRun("Buf: Trim: " #_data, testBufTrimChars, &info) <
0) \
+ ret = -1; \
+ } while (0)
+
+ DO_TEST_TRIM_CHARS("Trimmm", "m", "Tri");
+ DO_TEST_TRIM_CHARS("-abcd-efgh--", "-", "-abcd-efgh");
+ DO_TEST_TRIM_CHARS("-hABC-efgh--", "-h", "-hABC-efg");
+
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
2.21.0