]> granicus.if.org Git - p11-kit/commitdiff
path: Add p11_path_parent() function
authorStef Walter <stef@thewalter.net>
Fri, 14 Jun 2013 10:53:15 +0000 (12:53 +0200)
committerStef Walter <stef@thewalter.net>
Fri, 14 Jun 2013 10:59:29 +0000 (12:59 +0200)
Gets the parent element of the path, removing the last component.
Handles trailing and duplicate path separators correctly.

common/path.c
common/path.h
common/tests/test-path.c

index d3d881d63689e06ea19769215063b5bc40ab308b..a2ba6ec3231d08c941b84f264cc76ac32088476e 100644 (file)
@@ -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;
+}
index a5180087ff70514a4b91b686ce90cd497119994e..1fce607284b2e981e329801cc7943ced7d3326eb 100644 (file)
@@ -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__ */
index f1bccbd517a657b61b5ebb870adf511bd5573eed..ec2c2007ca39a4f37f518bdc01fb9dcb9bc08ba0 100644 (file)
@@ -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);
 }