mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
Add virStringReplace method for substring replacement
Add a virStringReplace method to virstring.{h,c} to perform substring matching and replacement Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
12aa71dfde
commit
66e3a3e914
@ -1798,6 +1798,7 @@ virStringArrayHasString;
|
||||
virStringFreeList;
|
||||
virStringJoin;
|
||||
virStringListLength;
|
||||
virStringReplace;
|
||||
virStringSearch;
|
||||
virStringSortCompare;
|
||||
virStringSortRevCompare;
|
||||
|
@ -749,3 +749,48 @@ cleanup:
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* virStringReplace:
|
||||
* @haystack: the source string to process
|
||||
* @oldneedle: the substring to locate
|
||||
* @newneedle: the substring to insert
|
||||
*
|
||||
* Search @haystack and replace all occurences of @oldneedle with @newneedle.
|
||||
*
|
||||
* Returns: a new string with all the replacements, or NULL on error
|
||||
*/
|
||||
char *
|
||||
virStringReplace(const char *haystack,
|
||||
const char *oldneedle,
|
||||
const char *newneedle)
|
||||
{
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
const char *tmp1, *tmp2;
|
||||
size_t oldneedlelen = strlen(oldneedle);
|
||||
size_t newneedlelen = strlen(newneedle);
|
||||
|
||||
tmp1 = haystack;
|
||||
tmp2 = NULL;
|
||||
|
||||
while (tmp1) {
|
||||
tmp2 = strstr(tmp1, oldneedle);
|
||||
|
||||
if (tmp2) {
|
||||
virBufferAdd(&buf, tmp1, (tmp2 - tmp1));
|
||||
virBufferAdd(&buf, newneedle, newneedlelen);
|
||||
tmp2 += oldneedlelen;
|
||||
} else {
|
||||
virBufferAdd(&buf, tmp1, -1);
|
||||
}
|
||||
|
||||
tmp1 = tmp2;
|
||||
}
|
||||
|
||||
if (virBufferError(&buf)) {
|
||||
virReportOOMError();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return virBufferContentAndReset(&buf);
|
||||
}
|
||||
|
@ -232,5 +232,10 @@ ssize_t virStringSearch(const char *str,
|
||||
char ***matches)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
|
||||
|
||||
char *virStringReplace(const char *haystack,
|
||||
const char *oldneedle,
|
||||
const char *newneedle)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
|
||||
|
||||
|
||||
#endif /* __VIR_STRING_H__ */
|
||||
|
@ -338,6 +338,39 @@ testStringSearch(const void *opaque ATTRIBUTE_UNUSED)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct stringReplaceData {
|
||||
const char *haystack;
|
||||
const char *oldneedle;
|
||||
const char *newneedle;
|
||||
const char *result;
|
||||
};
|
||||
|
||||
static int
|
||||
testStringReplace(const void *opaque ATTRIBUTE_UNUSED)
|
||||
{
|
||||
const struct stringReplaceData *data = opaque;
|
||||
char *result;
|
||||
int ret = -1;
|
||||
|
||||
result = virStringReplace(data->haystack,
|
||||
data->oldneedle,
|
||||
data->newneedle);
|
||||
|
||||
if (STRNEQ_NULLABLE(data->result, result)) {
|
||||
fprintf(stderr, "Expected '%s' but got '%s'\n",
|
||||
data->result, NULLSTR(result));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(result);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mymain(void)
|
||||
{
|
||||
@ -428,6 +461,37 @@ mymain(void)
|
||||
const char *matches3[] = { "foo", "bar" };
|
||||
TEST_SEARCH("1foo2bar3eek", "([a-z]+)", 2, 2, matches3, false);
|
||||
|
||||
#define TEST_REPLACE(h, o, n, r) \
|
||||
do { \
|
||||
struct stringReplaceData data = { \
|
||||
.haystack = h, \
|
||||
.oldneedle = o, \
|
||||
.newneedle = n, \
|
||||
.result = r \
|
||||
}; \
|
||||
if (virtTestRun("virStringReplace " h, testStringReplace, &data) < 0) \
|
||||
ret = -1; \
|
||||
} while (0)
|
||||
|
||||
/* no matches */
|
||||
TEST_REPLACE("foo", "bar", "eek", "foo");
|
||||
|
||||
/* complete match */
|
||||
TEST_REPLACE("foo", "foo", "bar", "bar");
|
||||
|
||||
/* middle match */
|
||||
TEST_REPLACE("foobarwizz", "bar", "eek", "fooeekwizz");
|
||||
|
||||
/* many matches */
|
||||
TEST_REPLACE("foofoofoofoo", "foo", "bar", "barbarbarbar");
|
||||
|
||||
/* many matches */
|
||||
TEST_REPLACE("fooooofoooo", "foo", "bar", "barooobaroo");
|
||||
|
||||
/* different length old/new needles */
|
||||
TEST_REPLACE("fooooofoooo", "foo", "barwizzeek", "barwizzeekooobarwizzeekoo");
|
||||
TEST_REPLACE("fooooofoooo", "foooo", "foo", "fooofoo");
|
||||
|
||||
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user