summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2021-03-26 10:06:47 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2021-03-30 08:26:30 +1000
commit7f4df04d59b1182fb8497f16dc5588bd6e1d4225 (patch)
treeba4b14f4903f81714701e948fabe0a9521a03383
parent4da9349a918848585e2fea57a295382b67f71cfa (diff)
downloadlibinput-7f4df04d59b1182fb8497f16dc5588bd6e1d4225.tar.gz
tools/record: deduplicate the device opening logic
With a new helper function strv_from_argv we can re-use the device opening loop for all the use-cases we have. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--src/util-strings.c30
-rw-r--r--src/util-strings.h1
-rw-r--r--test/test-utils.c39
-rw-r--r--tools/libinput-record.c44
4 files changed, 86 insertions, 28 deletions
diff --git a/src/util-strings.c b/src/util-strings.c
index 7d4c4628..4331a4b0 100644
--- a/src/util-strings.c
+++ b/src/util-strings.c
@@ -59,6 +59,36 @@ next_word(const char **state, size_t *len, const char *separators)
}
/**
+ * Return a null-terminated string array with the contents of argv
+ * duplicated.
+ *
+ * Use strv_free() to free the array.
+ *
+ * @return A null-terminated string array or NULL on errors
+ */
+char**
+strv_from_argv(int argc, char **argv)
+{
+ char **strv = NULL;
+
+ assert(argc >= 0);
+
+ if (argc == 0)
+ return NULL;
+
+ strv = zalloc((argc + 1) * sizeof *strv);
+ for (int i = 0; i < argc; i++) {
+ char *copy = safe_strdup(argv[i]);
+ if (!copy) {
+ strv_free(strv);
+ return NULL;
+ }
+ strv[i] = copy;
+ }
+ return strv;
+}
+
+/**
* Return a null-terminated string array with the tokens in the input
* string, e.g. "one two\tthree" with a separator list of " \t" will return
* an array [ "one", "two", "three", NULL ].
diff --git a/src/util-strings.h b/src/util-strings.h
index 9d044067..2a15fab3 100644
--- a/src/util-strings.h
+++ b/src/util-strings.h
@@ -252,6 +252,7 @@ safe_atod(const char *str, double *val)
return true;
}
+char **strv_from_argv(int argc, char **argv);
char **strv_from_string(const char *in, const char *separator);
char *strv_join(char **strv, const char *joiner);
diff --git a/test/test-utils.c b/test/test-utils.c
index dbd58031..882ee6c7 100644
--- a/test/test-utils.c
+++ b/test/test-utils.c
@@ -1022,6 +1022,44 @@ START_TEST(strsplit_test)
}
END_TEST
+START_TEST(strargv_test)
+{
+ struct argv_test {
+ int argc;
+ char *argv[10];
+ int expected;
+ } tests[] = {
+ { 0, {NULL}, 0 },
+ { 1, {"hello", "World"}, 1 },
+ { 2, {"hello", "World"}, 2 },
+ { 2, {"", " "}, 2 },
+ { 2, {"", NULL}, 0 },
+ { 2, {NULL, NULL}, 0 },
+ { 1, {NULL, NULL}, 0 },
+ { 3, {"hello", NULL, "World"}, 0 },
+ };
+ struct argv_test *t;
+
+ ARRAY_FOR_EACH(tests, t) {
+ char **strv = strv_from_argv(t->argc, t->argv);
+
+ if (t->expected == 0) {
+ ck_assert(strv == NULL);
+ } else {
+ int count = 0;
+ char **s = strv;
+ while (*s) {
+ ck_assert_str_eq(*s, t->argv[count]);
+ count++;
+ s++;
+ }
+ ck_assert_int_eq(t->expected, count);
+ strv_free(strv);
+ }
+ }
+}
+END_TEST
+
START_TEST(kvsplit_double_test)
{
struct kvsplit_dbl_test {
@@ -1378,6 +1416,7 @@ litest_utils_suite(void)
tcase_add_test(tc, safe_atou_base_8_test);
tcase_add_test(tc, safe_atod_test);
tcase_add_test(tc, strsplit_test);
+ tcase_add_test(tc, strargv_test);
tcase_add_test(tc, kvsplit_double_test);
tcase_add_test(tc, strjoin_test);
tcase_add_test(tc, strstrip_test);
diff --git a/tools/libinput-record.c b/tools/libinput-record.c
index 0704db39..062a45ad 100644
--- a/tools/libinput-record.c
+++ b/tools/libinput-record.c
@@ -2448,13 +2448,13 @@ mainloop(struct record_context *ctx)
}
static bool
-init_device(struct record_context *ctx, char *path, bool grab)
+init_device(struct record_context *ctx, const char *path, bool grab)
{
struct record_device *d;
int fd, rc;
d = zalloc(sizeof(*d));
- d->devnode = path;
+ d->devnode = safe_strdup(path);
d->nevents = 0;
d->events_sz = 5000;
d->events = zalloc(d->events_sz * sizeof(*d->events));
@@ -2698,6 +2698,7 @@ main(int argc, char **argv)
bool all = false, with_libinput = false, grab = false;
int ndevices;
int rc = EXIT_FAILURE;
+ char **paths = NULL;
list_init(&ctx.devices);
list_init(&ctx.sources);
@@ -2791,39 +2792,25 @@ main(int argc, char **argv)
goto out;
}
+ /* Now collect all device paths and init our device struct */
if (all) {
- char **devices; /* NULL-terminated */
- char **d;
-
- devices = all_devices();
- d = devices;
-
- while (*d) {
- if (!init_device(&ctx, safe_strdup(*d), grab)) {
- strv_free(devices);
- goto out;
- }
- d++;
- }
-
- strv_free(devices);
- } else if (ndevices > 1) {
- for (int i = ndevices; i > 0; i -= 1) {
- char *devnode = safe_strdup(argv[optind + i - 1]);
-
- if (!init_device(&ctx, devnode, grab))
- goto out;
- }
+ paths = all_devices();
+ } else if (ndevices >= 1) {
+ paths = strv_from_argv(ndevices, &argv[optind]);
} else {
- char *path;
-
- path = ndevices <= 0 ? select_device() : safe_strdup(argv[optind++]);
+ char *path = select_device();
if (path == NULL) {
goto out;
}
- if (!init_device(&ctx, path, grab))
+ paths = strv_from_argv(1, &path);
+ free(path);
+ }
+
+ for (char **p = paths; *p; p++) {
+ if (!init_device(&ctx, *p, grab)) {
goto out;
+ }
}
if (with_libinput && !init_libinput(&ctx))
@@ -2831,6 +2818,7 @@ main(int argc, char **argv)
rc = mainloop(&ctx);
out:
+ strv_free(paths);
list_for_each_safe(d, &ctx.devices, link) {
if (d->device)
libinput_device_unref(d->device);