mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-04 00:00:28 +01:00
util: add some extra strv helpers
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1178>
This commit is contained in:
parent
5c751491fa
commit
63a8ad2ead
3 changed files with 138 additions and 0 deletions
|
|
@ -62,6 +62,63 @@ next_word(const char **state, size_t *len, const char *separators)
|
|||
return next;
|
||||
}
|
||||
|
||||
size_t
|
||||
strv_len(char **strv)
|
||||
{
|
||||
if (!strv)
|
||||
return 0;
|
||||
|
||||
size_t size = 1;
|
||||
while (*strv) {
|
||||
size++;
|
||||
strv++;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
char **
|
||||
strv_append_vprintf(char **strv, const char *fmt, va_list args)
|
||||
{
|
||||
char *dup = strdup_vprintf(fmt, args);
|
||||
char **s = strv_append_take(strv, &dup);
|
||||
return s;
|
||||
}
|
||||
|
||||
char **
|
||||
strv_append_printf(char **strv, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char **s = strv_append_vprintf(strv, fmt, args);
|
||||
va_end(args);
|
||||
return s;
|
||||
}
|
||||
|
||||
char **
|
||||
strv_append_strdup(char **strv, const char *str)
|
||||
{
|
||||
char *dup = safe_strdup(str);
|
||||
return strv_append_take(strv, &dup);
|
||||
}
|
||||
|
||||
char **
|
||||
strv_append_take(char **strv, char **str)
|
||||
{
|
||||
if (str && *str) {
|
||||
size_t len = max(strv_len(strv) + 1, 2);
|
||||
|
||||
char **s = realloc(strv, len * sizeof(*strv));
|
||||
if (!s)
|
||||
abort();
|
||||
s[len - 1] = NULL;
|
||||
s[len - 2] = *str;
|
||||
*str = NULL;
|
||||
return s;
|
||||
} else {
|
||||
return strv;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a null-terminated string array with the contents of argv
|
||||
* duplicated.
|
||||
|
|
|
|||
|
|
@ -301,9 +301,18 @@ safe_atod(const char *str, double *val)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Returns the length of the strv, including the terminating NULL */
|
||||
size_t strv_len(char **strv);
|
||||
char **strv_from_argv(int argc, char **argv);
|
||||
char **strv_from_string(const char *in, const char *separator, size_t *num_elements);
|
||||
char *strv_join(char **strv, const char *joiner);
|
||||
char **strv_append_strdup(char **strv, const char *s);
|
||||
/* Takes ownership of the string and appends it to strv, s is set to NULL */
|
||||
char **strv_append_take(char **strv, char **s);
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
char **strv_append_printf(char **strv, const char *fmt, ...);
|
||||
__attribute__ ((format (printf, 2, 0)))
|
||||
char **strv_append_vprintf(char **strv, const char *fmt, va_list args);
|
||||
|
||||
typedef int (*strv_foreach_callback_t)(const char *str, size_t index, void *data);
|
||||
int strv_for_each(const char **strv, strv_foreach_callback_t func, void *data);
|
||||
|
|
|
|||
|
|
@ -1207,6 +1207,77 @@ START_TEST(strv_for_each_test)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
__attribute__ ((format (printf, 1, 0)))
|
||||
static char **
|
||||
test_strv_appendv(char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
char **strv = NULL;
|
||||
strv = strv_append_vprintf(strv, "%s %d", args);
|
||||
va_end(args);
|
||||
return strv;
|
||||
}
|
||||
|
||||
START_TEST(strv_append_test)
|
||||
{
|
||||
{
|
||||
char *test_strv1[] = {"a", "b", "c", NULL};
|
||||
char **test_strv2 = NULL;
|
||||
|
||||
litest_assert_int_eq(strv_len(test_strv1), 4U);
|
||||
litest_assert_int_eq(strv_len(test_strv2), 0U);
|
||||
}
|
||||
{
|
||||
char **strv = NULL;
|
||||
char *dup = safe_strdup("test");
|
||||
strv = strv_append_take(strv, &dup);
|
||||
litest_assert_ptr_null(dup);
|
||||
litest_assert_ptr_notnull(strv);
|
||||
litest_assert_str_eq(strv[0], "test");
|
||||
litest_assert_ptr_eq(strv[1], NULL);
|
||||
litest_assert_int_eq(strv_len(strv), 2U);
|
||||
|
||||
char *dup2 = safe_strdup("test2");
|
||||
strv = strv_append_take(strv, &dup2);
|
||||
litest_assert_ptr_null(dup2);
|
||||
litest_assert_str_eq(strv[1], "test2");
|
||||
litest_assert_ptr_eq(strv[2], NULL);
|
||||
litest_assert_int_eq(strv_len(strv), 3U);
|
||||
|
||||
strv = strv_append_take(strv, NULL);
|
||||
litest_assert_int_eq(strv_len(strv), 3U);
|
||||
strv_free(strv);
|
||||
}
|
||||
{
|
||||
char **strv = NULL;
|
||||
strv = strv_append_strdup(strv, "banana");
|
||||
litest_assert(strv != NULL);
|
||||
litest_assert_str_eq(strv[0], "banana");
|
||||
litest_assert_ptr_null(strv[1]);
|
||||
litest_assert_int_eq(strv_len(strv), 2U);
|
||||
strv_free(strv);
|
||||
}
|
||||
{
|
||||
char **strv = test_strv_appendv("%s %d", "apple", 2);
|
||||
litest_assert_ptr_notnull(strv);
|
||||
litest_assert_str_eq(strv[0], "apple 2");
|
||||
litest_assert_ptr_null(strv[1]);
|
||||
litest_assert_int_eq(strv_len(strv), 2U);
|
||||
strv_free(strv);
|
||||
}
|
||||
{
|
||||
char **strv = NULL;
|
||||
strv = strv_append_printf(strv, "coco%s", "nut");
|
||||
litest_assert_ptr_notnull(strv);
|
||||
litest_assert_str_eq(strv[0], "coconut");
|
||||
litest_assert_ptr_null(strv[1]);
|
||||
litest_assert_int_eq(strv_len(strv), 2U);
|
||||
strv_free(strv);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(double_array_from_string_test)
|
||||
{
|
||||
struct double_array_from_string_test {
|
||||
|
|
@ -2092,6 +2163,7 @@ int main(void)
|
|||
ADD_TEST(safe_atod_test);
|
||||
ADD_TEST(strsplit_test);
|
||||
ADD_TEST(strv_for_each_test);
|
||||
ADD_TEST(strv_append_test);
|
||||
ADD_TEST(double_array_from_string_test);
|
||||
ADD_TEST(strargv_test);
|
||||
ADD_TEST(kvsplit_double_test);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue