path-util: introduce path_find_first_component()

The function may be useful to iterate on each path component.
This commit is contained in:
Yu Watanabe
2021-05-28 13:41:23 +09:00
parent 340cd6b6f9
commit 0ee54dd4e2
3 changed files with 170 additions and 0 deletions
+85
View File
@@ -577,6 +577,90 @@ static void test_file_in_same_dir(void) {
free(t);
}
static void test_path_find_first_component_one(
const char *path,
bool accept_dot_dot,
char **expected,
int ret) {
log_debug("/* %s(\"%s\", accept_dot_dot=%s) */", __func__, strnull(path), yes_no(accept_dot_dot));
for (const char *p = path;;) {
const char *e;
int r;
r = path_find_first_component(&p, accept_dot_dot, &e);
if (r <= 0) {
if (r == 0) {
if (path)
assert_se(p == path + strlen_ptr(path));
else
assert_se(!p);
assert_se(!e);
}
assert_se(r == ret);
assert_se(strv_isempty(expected));
return;
}
assert_se(e);
assert_se(strcspn(e, "/") == (size_t) r);
assert_se(strlen_ptr(*expected) == (size_t) r);
assert_se(strneq(e, *expected++, r));
}
}
static void test_path_find_first_component(void) {
_cleanup_free_ char *hoge = NULL;
char foo[NAME_MAX * 2];
log_info("/* %s */", __func__);
test_path_find_first_component_one(NULL, false, NULL, 0);
test_path_find_first_component_one("", false, NULL, 0);
test_path_find_first_component_one("/", false, NULL, 0);
test_path_find_first_component_one(".", false, NULL, 0);
test_path_find_first_component_one("./", false, NULL, 0);
test_path_find_first_component_one("./.", false, NULL, 0);
test_path_find_first_component_one("..", false, NULL, -EINVAL);
test_path_find_first_component_one("/..", false, NULL, -EINVAL);
test_path_find_first_component_one("./..", false, NULL, -EINVAL);
test_path_find_first_component_one("////./././//.", false, NULL, 0);
test_path_find_first_component_one("a/b/c", false, STRV_MAKE("a", "b", "c"), 0);
test_path_find_first_component_one("././//.///aa/bbb//./ccc", false, STRV_MAKE("aa", "bbb", "ccc"), 0);
test_path_find_first_component_one("././//.///aa/.../../bbb//./ccc/.", false, STRV_MAKE("aa", "..."), -EINVAL);
test_path_find_first_component_one("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.", false, STRV_MAKE("aaa", ".bbb"), -EINVAL);
test_path_find_first_component_one("a/foo./b", false, STRV_MAKE("a", "foo.", "b"), 0);
test_path_find_first_component_one(NULL, true, NULL, 0);
test_path_find_first_component_one("", true, NULL, 0);
test_path_find_first_component_one("/", true, NULL, 0);
test_path_find_first_component_one(".", true, NULL, 0);
test_path_find_first_component_one("./", true, NULL, 0);
test_path_find_first_component_one("./.", true, NULL, 0);
test_path_find_first_component_one("..", true, STRV_MAKE(".."), 0);
test_path_find_first_component_one("/..", true, STRV_MAKE(".."), 0);
test_path_find_first_component_one("./..", true, STRV_MAKE(".."), 0);
test_path_find_first_component_one("////./././//.", true, NULL, 0);
test_path_find_first_component_one("a/b/c", true, STRV_MAKE("a", "b", "c"), 0);
test_path_find_first_component_one("././//.///aa/bbb//./ccc", true, STRV_MAKE("aa", "bbb", "ccc"), 0);
test_path_find_first_component_one("././//.///aa/.../../bbb//./ccc/.", true, STRV_MAKE("aa", "...", "..", "bbb", "ccc"), 0);
test_path_find_first_component_one("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.", true, STRV_MAKE("aaa", ".bbb", "..", "c.", "d.dd", "..eeee"), 0);
test_path_find_first_component_one("a/foo./b", true, STRV_MAKE("a", "foo.", "b"), 0);
memset(foo, 'a', sizeof(foo) -1);
char_array_0(foo);
test_path_find_first_component_one(foo, false, NULL, -EINVAL);
test_path_find_first_component_one(foo, true, NULL, -EINVAL);
hoge = strjoin("a/b/c/", foo, "//d/e/.//f/");
assert_se(hoge);
test_path_find_first_component_one(hoge, false, STRV_MAKE("a", "b", "c"), -EINVAL);
test_path_find_first_component_one(hoge, true, STRV_MAKE("a", "b", "c"), -EINVAL);
}
static void test_last_path_component(void) {
assert_se(last_path_component(NULL) == NULL);
assert_se(streq(last_path_component("a/b/c"), "c"));
@@ -894,6 +978,7 @@ int main(int argc, char **argv) {
test_path_startswith();
test_prefix_root();
test_file_in_same_dir();
test_path_find_first_component();
test_last_path_component();
test_path_extract_filename();
test_path_extract_directory();