mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-05-07 07:18:08 +02: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;
|
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
|
* Return a null-terminated string array with the contents of argv
|
||||||
* duplicated.
|
* duplicated.
|
||||||
|
|
|
||||||
|
|
@ -301,9 +301,18 @@ safe_atod(const char *str, double *val)
|
||||||
return true;
|
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_argv(int argc, char **argv);
|
||||||
char **strv_from_string(const char *in, const char *separator, size_t *num_elements);
|
char **strv_from_string(const char *in, const char *separator, size_t *num_elements);
|
||||||
char *strv_join(char **strv, const char *joiner);
|
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);
|
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);
|
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
|
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)
|
START_TEST(double_array_from_string_test)
|
||||||
{
|
{
|
||||||
struct 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(safe_atod_test);
|
||||||
ADD_TEST(strsplit_test);
|
ADD_TEST(strsplit_test);
|
||||||
ADD_TEST(strv_for_each_test);
|
ADD_TEST(strv_for_each_test);
|
||||||
|
ADD_TEST(strv_append_test);
|
||||||
ADD_TEST(double_array_from_string_test);
|
ADD_TEST(double_array_from_string_test);
|
||||||
ADD_TEST(strargv_test);
|
ADD_TEST(strargv_test);
|
||||||
ADD_TEST(kvsplit_double_test);
|
ADD_TEST(kvsplit_double_test);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue