diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2021-02-05 14:36:16 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2021-02-12 14:31:50 +1000 |
commit | e6ed506df335e8eb0d79d22d22d0734a2b93fe43 (patch) | |
tree | 7ad530110cfb98dc731a9aeb4961b26a48c2b14f | |
parent | 8ab2581d202e95f51dabc84eebd7e0311b59bfe1 (diff) |
utils: add a trunkname() function to extract the trunk of a filename
/path/to/foo.bar returns "foo"
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r-- | src/util-strings.c | 31 | ||||
-rw-r--r-- | src/util-strings.h | 3 | ||||
-rw-r--r-- | test/test-utils.c | 27 |
3 files changed, 61 insertions, 0 deletions
diff --git a/src/util-strings.c b/src/util-strings.c index 8d2aeb01..3e174806 100644 --- a/src/util-strings.c +++ b/src/util-strings.c @@ -155,3 +155,34 @@ strv_join(char **strv, const char *joiner) return str; } + +/** + * Similar to basename() but returns the trunk only without the (last) + * trailing suffix, so that: + * + * - foo.c returns foo + * - foo.a.b returns foo.a + * - foo returns foo + * - foo/ returns "" + * + * @return an allocated string representing the trunk name of the file + */ +char * +trunkname(const char *filename) +{ + /* See basename(3), there are two versions and they depend on + * whether libgen.h is included. We can't be sure which basename() + * applies here, so let's play it safe and assume it's the POSIX + * one. */ + char *tmp = strdup(filename); + char *base = basename(tmp); + char *suffix; + char *trunk; + + if ((suffix = rindex(base, '.'))) + *suffix = '\0'; + + trunk = strdup(base); + free(tmp); + return trunk; +} diff --git a/src/util-strings.h b/src/util-strings.h index 7e9e8bca..ad007f69 100644 --- a/src/util-strings.h +++ b/src/util-strings.h @@ -391,3 +391,6 @@ strstartswith(const char *str, const char *prefix) return prefixlen > 0 ? strneq(str, prefix, strlen(prefix)) : false; } + +char * +trunkname(const char *filename); diff --git a/test/test-utils.c b/test/test-utils.c index 8cc3f22a..f31b2e07 100644 --- a/test/test-utils.c +++ b/test/test-utils.c @@ -1292,6 +1292,32 @@ START_TEST(strneq_test) } END_TEST +START_TEST(trunkname_test) +{ + struct test { + const char *path; + const char *expected; + } tests[] = { + { "foo.c", "foo" }, + { "/path/to/foo.h", "foo" }, + { "../bar.foo", "bar" }, + { "./bar.foo.baz", "bar.foo" }, + { "./", "" }, + { "/", "" }, + { "/bar/", "" }, + { "/bar", "bar" }, + { "", "" }, + }; + struct test *t; + + ARRAY_FOR_EACH(tests, t) { + char *result = trunkname(t->path); + ck_assert_str_eq(result, t->expected); + free(result); + } +} +END_TEST + static Suite * litest_utils_suite(void) { @@ -1335,6 +1361,7 @@ litest_utils_suite(void) tcase_add_test(tc, strverscmp_test); tcase_add_test(tc, streq_test); tcase_add_test(tc, strneq_test); + tcase_add_test(tc, trunkname_test); suite_add_tcase(s, tc); |