util: add virBufferTrimChars

A new helper for trimming combinations of specified characters from
the tail of the buffer.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
Ján Tomko 2020-01-14 08:04:14 +01:00
parent 46afdc2120
commit fdd48f5b73
4 changed files with 64 additions and 0 deletions

View File

@ -1642,6 +1642,7 @@ virBufferSetIndent;
virBufferStrcat;
virBufferStrcatVArgs;
virBufferTrim;
virBufferTrimChars;
virBufferURIEncodeString;
virBufferUse;
virBufferVasprintf;

View File

@ -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:

View File

@ -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);

View File

@ -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;
}