utils: Add strreplace function
This commit is contained in:
@@ -384,6 +384,89 @@ START_TEST(test_translate)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* strreplace
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
char *in;
|
||||||
|
char *out;
|
||||||
|
char *search;
|
||||||
|
char *replace;
|
||||||
|
bool allocated;
|
||||||
|
} strreplace_data[] = {
|
||||||
|
/* invalid arguments */
|
||||||
|
{NULL, NULL, NULL, NULL, FALSE},
|
||||||
|
{"", "", NULL, NULL, FALSE},
|
||||||
|
{"", "", "", NULL, FALSE},
|
||||||
|
{"", "", NULL, "", FALSE},
|
||||||
|
{"", "", "", "", FALSE},
|
||||||
|
{"", "", "", "asdf", FALSE},
|
||||||
|
{"", "", "asdf", "", FALSE},
|
||||||
|
{"asdf", "asdf", NULL, NULL, FALSE},
|
||||||
|
{"asdf", "asdf", "", NULL, FALSE},
|
||||||
|
{"asdf", "asdf", NULL, "", FALSE},
|
||||||
|
{"asdf", "asdf", "", "", FALSE},
|
||||||
|
{"asdf", "asdf", "", "asdf", FALSE},
|
||||||
|
{"asdf", "asdf", "asdf", NULL, FALSE},
|
||||||
|
{"qwer", "qwer", "", "asdf", FALSE},
|
||||||
|
/* replacement shorter */
|
||||||
|
{"asdf", "", "asdf", "", TRUE},
|
||||||
|
{"asdfasdf", "", "asdf", "", TRUE},
|
||||||
|
{"asasdfdf", "asdf", "asdf", "", TRUE},
|
||||||
|
{"asdf", "df", "as", "", TRUE},
|
||||||
|
{"asdf", "as", "df", "", TRUE},
|
||||||
|
{"qwer", "qwer", "asdf", "", FALSE},
|
||||||
|
/* replacement same length */
|
||||||
|
{"a", "b", "a", "b", TRUE},
|
||||||
|
{"aaa", "bbb", "a", "b", TRUE},
|
||||||
|
{"aaa", "bbb", "aaa", "bbb", TRUE},
|
||||||
|
{"asdf", "asdf", "asdf", "asdf", TRUE},
|
||||||
|
{"qwer", "qwer", "asdf", "asdf", FALSE},
|
||||||
|
/* replacement longer */
|
||||||
|
{"asdf", "asdf", "", "asdf", FALSE},
|
||||||
|
{"asdf", "asdfasdf", "asdf", "asdfasdf", TRUE},
|
||||||
|
{"asdf", "asdfsdf", "a", "asdf", TRUE},
|
||||||
|
{"asdf", "asdasdf", "f", "asdf", TRUE},
|
||||||
|
{"aaa", "asdfasdfasdf", "a", "asdf", TRUE},
|
||||||
|
{"qwer", "qwer", "asdf", "asdfasdf", FALSE},
|
||||||
|
/* real examples */
|
||||||
|
{"http://x.org/no/spaces", "http://x.org/no/spaces", " ", "%20", FALSE},
|
||||||
|
{"http://x.org/end ", "http://x.org/end%20", " ", "%20", TRUE},
|
||||||
|
{" http://x.org/start", "%20http://x.org/start", " ", "%20", TRUE},
|
||||||
|
{" http://x.org/both ", "%20http://x.org/both%20", " ", "%20", TRUE},
|
||||||
|
{"http://x.org/ /slash", "http://x.org/%20/slash", " ", "%20", TRUE},
|
||||||
|
{"http://x.org/ /three", "http://x.org/%20%20%20/three", " ", "%20", TRUE},
|
||||||
|
{"http://x.org/ ", "http://x.org/%20%20%20%20%20%20", " ", "%20", TRUE},
|
||||||
|
{"http://x.org/%20/encoded", "http://x.org/%20/encoded", " ", "%20", FALSE},
|
||||||
|
};
|
||||||
|
|
||||||
|
START_TEST(test_strreplace)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
ret = strreplace(strreplace_data[_i].in, strreplace_data[_i].search,
|
||||||
|
strreplace_data[_i].replace);
|
||||||
|
if (ret && strreplace_data[_i].out)
|
||||||
|
{
|
||||||
|
ck_assert_str_eq(ret, strreplace_data[_i].out);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ck_assert(ret == strreplace_data[_i].out);
|
||||||
|
}
|
||||||
|
if (strreplace_data[_i].allocated)
|
||||||
|
{
|
||||||
|
ck_assert(ret != strreplace_data[_i].in);
|
||||||
|
free(ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ck_assert(ret == strreplace_data[_i].in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* time_printf_hook
|
* time_printf_hook
|
||||||
*/
|
*/
|
||||||
@@ -543,6 +626,10 @@ Suite *utils_suite_create()
|
|||||||
tcase_add_loop_test(tc, test_translate, 0, countof(translate_data));
|
tcase_add_loop_test(tc, test_translate, 0, countof(translate_data));
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
tc = tcase_create("strreplace");
|
||||||
|
tcase_add_loop_test(tc, test_strreplace, 0, countof(strreplace_data));
|
||||||
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("printf_hooks");
|
tc = tcase_create("printf_hooks");
|
||||||
tcase_add_loop_test(tc, test_time_printf_hook, 0, countof(time_data));
|
tcase_add_loop_test(tc, test_time_printf_hook, 0, countof(time_data));
|
||||||
tcase_add_loop_test(tc, test_time_delta_printf_hook, 0, countof(time_delta_data));
|
tcase_add_loop_test(tc, test_time_delta_printf_hook, 0, countof(time_delta_data));
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008-2012 Tobias Brunner
|
* Copyright (C) 2008-2013 Tobias Brunner
|
||||||
* Copyright (C) 2005-2008 Martin Willi
|
* Copyright (C) 2005-2008 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
@@ -141,6 +141,58 @@ char* translate(char *str, const char *from, const char *to)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
char* strreplace(const char *str, const char *search, const char *replace)
|
||||||
|
{
|
||||||
|
size_t len, slen, rlen, count = 0;
|
||||||
|
char *res, *pos, *found, *dst;
|
||||||
|
|
||||||
|
if (!str || !*str || !search || !*search || !replace)
|
||||||
|
{
|
||||||
|
return (char*)str;
|
||||||
|
}
|
||||||
|
slen = strlen(search);
|
||||||
|
rlen = strlen(replace);
|
||||||
|
if (slen != rlen)
|
||||||
|
{
|
||||||
|
for (pos = (char*)str; (pos = strstr(pos, search)); pos += slen)
|
||||||
|
{
|
||||||
|
found = pos;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if (!count)
|
||||||
|
{
|
||||||
|
return (char*)str;
|
||||||
|
}
|
||||||
|
len = (found - str) + strlen(found) + count * (rlen - slen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = strlen(str);
|
||||||
|
}
|
||||||
|
found = strstr(str, search);
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
return (char*)str;
|
||||||
|
}
|
||||||
|
dst = res = malloc(len + 1);
|
||||||
|
pos = (char*)str;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
len = found - pos;
|
||||||
|
memcpy(dst, pos, len);
|
||||||
|
dst += len;
|
||||||
|
memcpy(dst, replace, rlen);
|
||||||
|
dst += rlen;
|
||||||
|
pos = found + slen;
|
||||||
|
}
|
||||||
|
while ((found = strstr(pos, search)));
|
||||||
|
strcpy(dst, pos);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008-2012 Tobias Brunner
|
* Copyright (C) 2008-2013 Tobias Brunner
|
||||||
* Copyright (C) 2008 Martin Willi
|
* Copyright (C) 2008 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
@@ -471,6 +471,20 @@ void *memstr(const void *haystack, const char *needle, size_t n);
|
|||||||
*/
|
*/
|
||||||
char *translate(char *str, const char *from, const char *to);
|
char *translate(char *str, const char *from, const char *to);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces all occurences of search in the given string with replace.
|
||||||
|
*
|
||||||
|
* Allocates memory only if anything is replaced in the string. The original
|
||||||
|
* string is also returned if any of the arguments are invalid (e.g. if search
|
||||||
|
* is empty or any of them are NULL).
|
||||||
|
*
|
||||||
|
* @param str original string
|
||||||
|
* @param search string to search for and replace
|
||||||
|
* @param replace string to replace found occurences with
|
||||||
|
* @return allocated string, if anything got replaced, str otherwise
|
||||||
|
*/
|
||||||
|
char *strreplace(const char *str, const char *search, const char *replace);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a directory and all required parent directories.
|
* Creates a directory and all required parent directories.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user