Signed-off-by: Peter Hutterer <[email protected]>
---
 src/libinput-util.h | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 test/test-misc.c    | 53 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 116 insertions(+)

diff --git a/src/libinput-util.h b/src/libinput-util.h
index c6d40efc..1f6994be 100644
--- a/src/libinput-util.h
+++ b/src/libinput-util.h
@@ -560,4 +560,67 @@ strv_free(char **strv) {
        free (strv);
 }
 
+struct key_value_double {
+       double key;
+       double value;
+};
+
+static inline ssize_t
+kv_double_from_string(const char *string,
+                     const char *pair_separator,
+                     const char *kv_separator,
+                     struct key_value_double **result_out)
+
+{
+       char **pairs;
+       char **pair;
+       struct key_value_double *result = NULL;
+       ssize_t npairs = 0;
+       unsigned int idx = 0;
+
+       if (!pair_separator || pair_separator[0] == '\0' ||
+           !kv_separator || kv_separator[0] == '\0')
+               return -1;
+
+       pairs = strv_from_string(string, pair_separator);
+       if (!pairs)
+               return -1;
+
+       for (pair = pairs; *pair; pair++)
+               npairs++;
+
+       if (npairs == 0)
+               return -1;
+
+       result = zalloc(npairs * sizeof *result);
+
+       for (pair = pairs; *pair; pair++) {
+               char **kv = strv_from_string(*pair, kv_separator);
+               double k, v;
+
+               if (!kv || !kv[0] || !kv[1] || kv[2] ||
+                   !safe_atod(kv[0], &k) ||
+                   !safe_atod(kv[1], &v)) {
+                       strv_free(kv);
+                       goto error;
+               }
+
+               result[idx].key = k;
+               result[idx].value = v;
+               idx++;
+
+               strv_free(kv);
+       }
+
+       strv_free(pairs);
+
+       *result_out = result;
+
+       return npairs;
+
+error:
+       strv_free(pairs);
+       free(result);
+       return -1;
+}
 #endif /* LIBINPUT_UTIL_H */
diff --git a/test/test-misc.c b/test/test-misc.c
index c62cd03e..7222a84c 100644
--- a/test/test-misc.c
+++ b/test/test-misc.c
@@ -1292,6 +1292,58 @@ START_TEST(strsplit_test)
 }
 END_TEST
 
+struct kvsplit_dbl_test {
+       const char *string;
+       const char *psep;
+       const char *kvsep;
+       ssize_t nresults;
+       struct {
+               double a;
+               double b;
+       } results[32];
+};
+
+START_TEST(kvsplit_double_test)
+{
+       struct kvsplit_dbl_test tests[] = {
+               { "1:2;3:4;5:6", ";", ":", 3, { {1, 2}, {3, 4}, {5, 6}}},
+               { "1.0x2.3 -3.2x4.5 8.090909x-6.00", " ", "x", 3, { {1.0, 2.3}, 
{-3.2, 4.5}, {8.090909, -6}}},
+
+               { "1:2", "x", ":", 1, {{1, 2}}},
+               { "1:2", ":", "x", -1, {}},
+               { "1:2", NULL, "x", -1, {}},
+               { "1:2", "", "x", -1, {}},
+               { "1:2", "x", NULL, -1, {}},
+               { "1:2", "x", "", -1, {}},
+               { "a:b", "x", ":", -1, {}},
+               { "", " ", "x", -1, {}},
+               { "1.2.3.4.5", ".", "", -1, {}},
+               { NULL }
+       };
+       struct kvsplit_dbl_test *t = tests;
+
+       while (t->string) {
+               struct key_value_double *result = NULL;
+               ssize_t npairs;
+
+               npairs = kv_double_from_string(t->string,
+                                              t->psep,
+                                              t->kvsep,
+                                              &result);
+               ck_assert_int_eq(npairs, t->nresults);
+
+               for (ssize_t i = 0; i < npairs; i++) {
+                       ck_assert_double_eq(t->results[i].a, result[i].key);
+                       ck_assert_double_eq(t->results[i].b, result[i].value);
+               }
+
+
+               free(result);
+               t++;
+       }
+}
+END_TEST
+
 static int open_restricted_leak(const char *path, int flags, void *data)
 {
        return *(int*)data;
@@ -1528,6 +1580,7 @@ TEST_COLLECTION(misc)
        litest_add_no_device("misc:parser", safe_atoi_base_8_test);
        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:time", time_conversion);
 
        litest_add_no_device("misc:fd", fd_no_event_leak);
-- 
2.14.3

_______________________________________________
wayland-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to