提交 66e3a3e9 编写于 作者: D Daniel P. Berrange

Add virStringReplace method for substring replacement

Add a virStringReplace method to virstring.{h,c} to perform
substring matching and replacement
Signed-off-by: NDaniel P. Berrange <berrange@redhat.com>
上级 12aa71df
......@@ -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;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册