diff options
author | Stef Walter <stef@thewalter.net> | 2013-06-14 12:53:15 +0200 |
---|---|---|
committer | Stef Walter <stef@thewalter.net> | 2013-06-14 12:59:29 +0200 |
commit | 045df29606ea9853b4fc8bdba062a5e4a7a5be95 (patch) | |
tree | ef19ba4bb04471cf3c42d6bd3d1f4c11a1d4d754 | |
parent | 8c6dd48789bdaf2a3dc800df7ed3416ddc3b7e1f (diff) |
path: Add p11_path_parent() function
Gets the parent element of the path, removing the last component.
Handles trailing and duplicate path separators correctly.
-rw-r--r-- | common/path.c | 36 | ||||
-rw-r--r-- | common/path.h | 2 | ||||
-rw-r--r-- | common/tests/test-path.c | 17 |
3 files changed, 55 insertions, 0 deletions
diff --git a/common/path.c b/common/path.c index d3d881d..a2ba6ec 100644 --- a/common/path.c +++ b/common/path.c @@ -262,3 +262,39 @@ p11_path_build (const char *path, built[at] = '\0'; return built; } + +char * +p11_path_parent (const char *path) +{ + const char *e; + char *parent; + bool had = false; + + return_val_if_fail (path != NULL, NULL); + + /* Find the end of the last component */ + e = path + strlen (path); + while (e != path && is_path_component_or_null (*e)) + e--; + + /* Find the beginning of the last component */ + while (e != path && !is_path_component_or_null (*e)) { + had = true; + e--; + } + + /* Find the end of the last component */ + while (e != path && is_path_component_or_null (*e)) + e--; + + if (e == path) { + if (!had) + return NULL; + parent = strdup ("/"); + } else { + parent = strndup (path, (e - path) + 1); + } + + return_val_if_fail (parent != NULL, NULL); + return parent; +} diff --git a/common/path.h b/common/path.h index a518008..1fce607 100644 --- a/common/path.h +++ b/common/path.h @@ -59,4 +59,6 @@ char * p11_path_build (const char *path, bool p11_path_absolute (const char *path); +char * p11_path_parent (const char *path); + #endif /* P11_PATH_H__ */ diff --git a/common/tests/test-path.c b/common/tests/test-path.c index f1bccbd..ec2c200 100644 --- a/common/tests/test-path.c +++ b/common/tests/test-path.c @@ -173,6 +173,22 @@ test_absolute (void) #endif } +static void +test_parent (void) +{ + check_equals_and_free ("/", p11_path_parent ("/root")); + check_equals_and_free ("/", p11_path_parent ("/root/")); + check_equals_and_free ("/", p11_path_parent ("/root//")); + check_equals_and_free ("/root", p11_path_parent ("/root/second")); + check_equals_and_free ("/root", p11_path_parent ("/root//second")); + check_equals_and_free ("/root", p11_path_parent ("/root//second//")); + check_equals_and_free ("/root", p11_path_parent ("/root///second")); + check_equals_and_free ("/root/second", p11_path_parent ("/root/second/test.file")); + assert_ptr_eq (NULL, p11_path_parent ("/")); + assert_ptr_eq (NULL, p11_path_parent ("//")); + assert_ptr_eq (NULL, p11_path_parent ("")); +} + int main (int argc, char *argv[]) @@ -181,6 +197,7 @@ main (int argc, p11_test (test_build, "/path/build"); p11_test (test_expand, "/path/expand"); p11_test (test_absolute, "/path/absolute"); + p11_test (test_parent, "/path/parent"); return p11_test_run (argc, argv); } |