mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-26 21:30:13 +01:00
util: add a strv_join() helper function
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
6fe55cd0ea
commit
1e4c5a93a8
3 changed files with 82 additions and 0 deletions
|
|
@ -535,3 +535,46 @@ strv_from_string(const char *in, const char *separators)
|
|||
|
||||
return strv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a newly allocated string with all elements joined by the
|
||||
* joiner, same as Python's string.join() basically.
|
||||
* A strv of ["one", "two", "three", NULL] with a joiner of ", " results
|
||||
* in "one, two, three".
|
||||
*
|
||||
* An empty strv ([NULL]) returns NULL, same for passing NULL as either
|
||||
* argument.
|
||||
*
|
||||
* @param strv Input string arrray
|
||||
* @param joiner Joiner between the elements in the final string
|
||||
*
|
||||
* @return A null-terminated string joining all elements
|
||||
*/
|
||||
char *
|
||||
strv_join(char **strv, const char *joiner)
|
||||
{
|
||||
char **s;
|
||||
char *str;
|
||||
size_t slen = 0;
|
||||
size_t count = 0;
|
||||
|
||||
if (!strv || !joiner)
|
||||
return NULL;
|
||||
|
||||
s = strv;
|
||||
for (s = strv, count = 0; *s; s++, count++) {
|
||||
slen += strlen(*s);
|
||||
}
|
||||
|
||||
slen += (count - 1) * strlen(joiner);
|
||||
|
||||
str = zalloc(slen + 1); /* trailing \0 */
|
||||
for (s = strv; *s; s++) {
|
||||
strcat(str, *s);
|
||||
--count;
|
||||
if (count > 0)
|
||||
strcat(str, joiner);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -543,6 +543,7 @@ safe_atod(const char *str, double *val)
|
|||
}
|
||||
|
||||
char **strv_from_string(const char *string, const char *separator);
|
||||
char *strv_join(char **strv, const char *separator);
|
||||
|
||||
static inline void
|
||||
strv_free(char **strv) {
|
||||
|
|
|
|||
|
|
@ -1343,6 +1343,43 @@ START_TEST(kvsplit_double_test)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
struct strjoin_test {
|
||||
char *strv[10];
|
||||
const char *joiner;
|
||||
const char *result;
|
||||
};
|
||||
|
||||
START_TEST(strjoin_test)
|
||||
{
|
||||
struct strjoin_test tests[] = {
|
||||
{ { "one", "two", "three", NULL }, " ", "one two three" },
|
||||
{ { "one", NULL }, "x", "one" },
|
||||
{ { "one", "two", NULL }, "x", "onextwo" },
|
||||
{ { "one", "two", NULL }, ",", "one,two" },
|
||||
{ { "one", "two", NULL }, ", ", "one, two" },
|
||||
{ { "one", "two", NULL }, "one", "oneonetwo" },
|
||||
{ { "one", "two", NULL }, NULL, NULL },
|
||||
{ { "", "", "", NULL }, " ", " " },
|
||||
{ { "a", "b", "c", NULL }, "", "abc" },
|
||||
{ { "", "b", "c", NULL }, "x", "xbxc" },
|
||||
{ { "", "", "", NULL }, "", "" },
|
||||
{ { NULL }, NULL, NULL }
|
||||
};
|
||||
struct strjoin_test *t = tests;
|
||||
|
||||
while (t->strv[0]) {
|
||||
char *str;
|
||||
str = strv_join(t->strv, t->joiner);
|
||||
if (t->result == NULL)
|
||||
ck_assert_ptr_null(str);
|
||||
else
|
||||
ck_assert_str_eq(str, t->result);
|
||||
free(str);
|
||||
t++;
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static int open_restricted_leak(const char *path, int flags, void *data)
|
||||
{
|
||||
return *(int*)data;
|
||||
|
|
@ -1580,6 +1617,7 @@ TEST_COLLECTION(misc)
|
|||
litest_add_no_device("misc:parser", safe_atod_test);
|
||||
litest_add_no_device("misc:parser", strsplit_test);
|
||||
litest_add_no_device("misc:parser", kvsplit_double_test);
|
||||
litest_add_no_device("misc:parser", strjoin_test);
|
||||
litest_add_no_device("misc:time", time_conversion);
|
||||
|
||||
litest_add_no_device("misc:fd", fd_no_event_leak);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue