diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2021-03-26 10:06:47 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2021-03-30 08:26:30 +1000 |
commit | 7f4df04d59b1182fb8497f16dc5588bd6e1d4225 (patch) | |
tree | ba4b14f4903f81714701e948fabe0a9521a03383 | |
parent | 4da9349a918848585e2fea57a295382b67f71cfa (diff) | |
download | libinput-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.c | 30 | ||||
-rw-r--r-- | src/util-strings.h | 1 | ||||
-rw-r--r-- | test/test-utils.c | 39 | ||||
-rw-r--r-- | tools/libinput-record.c | 44 |
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); |