[PATCH libinput 21/23] util: add a helper function to split a key-value pair string

Peter Hutterer peter.hutterer at who-t.net
Thu Apr 12 06:34:47 UTC 2018


Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 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



More information about the wayland-devel mailing list