mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-20 08:00:08 +01:00
utils: add a safe version of basename
So we don't need to worry about the libgen.h include game. And we can switch trunkname over to that, making it a bit simpler. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
fd9d165a77
commit
671eb8cbbb
3 changed files with 66 additions and 12 deletions
|
|
@ -156,6 +156,30 @@ strv_join(char **strv, const char *joiner)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a pointer to the basename within filename.
|
||||||
|
* If the filename the empty string or a directory (i.e. the last char of
|
||||||
|
* filename is '/') NULL is returned.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
safe_basename(const char *filename)
|
||||||
|
{
|
||||||
|
const char *basename;
|
||||||
|
|
||||||
|
if (*filename == '\0')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
basename = strrchr(filename, '/');
|
||||||
|
if (basename == NULL)
|
||||||
|
return filename;
|
||||||
|
|
||||||
|
if (*(basename + 1) == '\0')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return basename + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to basename() but returns the trunk only without the (last)
|
* Similar to basename() but returns the trunk only without the (last)
|
||||||
* trailing suffix, so that:
|
* trailing suffix, so that:
|
||||||
|
|
@ -170,19 +194,15 @@ strv_join(char **strv, const char *joiner)
|
||||||
char *
|
char *
|
||||||
trunkname(const char *filename)
|
trunkname(const char *filename)
|
||||||
{
|
{
|
||||||
/* See basename(3), there are two versions and they depend on
|
const char *base = safe_basename(filename);
|
||||||
* 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 *suffix;
|
||||||
char *trunk;
|
|
||||||
|
|
||||||
if ((suffix = rindex(base, '.')))
|
if (base == NULL)
|
||||||
*suffix = '\0';
|
return strdup("");
|
||||||
|
|
||||||
trunk = strdup(base);
|
suffix = rindex(base, '.');
|
||||||
free(tmp);
|
if (suffix == NULL)
|
||||||
return trunk;
|
return strdup(base);
|
||||||
|
else
|
||||||
|
return strndup(base, suffix-base);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -392,5 +392,8 @@ strstartswith(const char *str, const char *prefix)
|
||||||
return prefixlen > 0 ? strneq(str, prefix, strlen(prefix)) : false;
|
return prefixlen > 0 ? strneq(str, prefix, strlen(prefix)) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
safe_basename(const char *filename);
|
||||||
|
|
||||||
char *
|
char *
|
||||||
trunkname(const char *filename);
|
trunkname(const char *filename);
|
||||||
|
|
|
||||||
|
|
@ -1292,6 +1292,35 @@ START_TEST(strneq_test)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(basename_test)
|
||||||
|
{
|
||||||
|
struct test {
|
||||||
|
const char *path;
|
||||||
|
const char *expected;
|
||||||
|
} tests[] = {
|
||||||
|
{ "a", "a" },
|
||||||
|
{ "foo.c", "foo.c" },
|
||||||
|
{ "foo", "foo" },
|
||||||
|
{ "/path/to/foo.h", "foo.h" },
|
||||||
|
{ "../bar.foo", "bar.foo" },
|
||||||
|
{ "./bar.foo.baz", "bar.foo.baz" },
|
||||||
|
{ "./", NULL },
|
||||||
|
{ "/", NULL },
|
||||||
|
{ "/bar/", NULL },
|
||||||
|
{ "/bar", "bar" },
|
||||||
|
{ "", NULL },
|
||||||
|
};
|
||||||
|
struct test *t;
|
||||||
|
|
||||||
|
ARRAY_FOR_EACH(tests, t) {
|
||||||
|
const char *result = safe_basename(t->path);
|
||||||
|
if (t->expected == NULL)
|
||||||
|
ck_assert(result == NULL);
|
||||||
|
else
|
||||||
|
ck_assert_str_eq(result, t->expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
START_TEST(trunkname_test)
|
START_TEST(trunkname_test)
|
||||||
{
|
{
|
||||||
struct test {
|
struct test {
|
||||||
|
|
@ -1300,6 +1329,7 @@ START_TEST(trunkname_test)
|
||||||
} tests[] = {
|
} tests[] = {
|
||||||
{ "foo.c", "foo" },
|
{ "foo.c", "foo" },
|
||||||
{ "/path/to/foo.h", "foo" },
|
{ "/path/to/foo.h", "foo" },
|
||||||
|
{ "/path/to/foo", "foo" },
|
||||||
{ "../bar.foo", "bar" },
|
{ "../bar.foo", "bar" },
|
||||||
{ "./bar.foo.baz", "bar.foo" },
|
{ "./bar.foo.baz", "bar.foo" },
|
||||||
{ "./", "" },
|
{ "./", "" },
|
||||||
|
|
@ -1362,6 +1392,7 @@ litest_utils_suite(void)
|
||||||
tcase_add_test(tc, streq_test);
|
tcase_add_test(tc, streq_test);
|
||||||
tcase_add_test(tc, strneq_test);
|
tcase_add_test(tc, strneq_test);
|
||||||
tcase_add_test(tc, trunkname_test);
|
tcase_add_test(tc, trunkname_test);
|
||||||
|
tcase_add_test(tc, basename_test);
|
||||||
|
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue