]> git.ipfire.org Git - pakfire.git/commitdiff
path: Add merge function to join two paths together
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 6 Oct 2023 14:04:04 +0000 (14:04 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 6 Oct 2023 14:04:04 +0000 (14:04 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/path.h
src/libpakfire/path.c
tests/libpakfire/path.c

index f35a87274fffb5b06ef91d73dfd84359807bafea..979bfa12968f298c3f7cf775695081e6fefb5895 100644 (file)
@@ -31,4 +31,8 @@ int __pakfire_path_normalize(char* p, const size_t length);
        __pakfire_path_append(path, sizeof(path), s1, s2)
 int __pakfire_path_append(char* buffer, const size_t length, const char* s1, const char* s2);
 
+#define pakfire_path_merge(path, s1, s2) \
+       __pakfire_path_merge(path, sizeof(path), s1, s2)
+int __pakfire_path_merge(char* buffer, const size_t length, const char* s1, const char* s2);
+
 #endif /* PAKFIRE_PATH_H */
index 1a2b23afff729ea050d3d1623269f2ba9bf6154e..8e13cac112636866942f2fa36244093223393aa6 100644 (file)
@@ -35,13 +35,20 @@ struct pakfire_path {
        char** segments;
 };
 
-static void pakfire_path_free(struct pakfire_path* path) {
-       if (path->segments) {
-               for (unsigned int i = 0; i < path->num_segments; i++)
-                       free(path->segments[i]);
+static void pakfire_path_free_segments(struct pakfire_path* path) {
+       for (unsigned int i = 0; i < path->num_segments; i++)
+               free(path->segments[i]);
 
-               free(path->segments);
-       }
+       free(path->segments);
+
+       // Reset the data structure
+       path->segments = NULL;
+       path->num_segments = 0;
+}
+
+static void pakfire_path_free(struct pakfire_path* path) {
+       if (path->segments)
+               pakfire_path_free_segments(path);
 
        free(path);
 }
@@ -92,9 +99,14 @@ static int pakfire_path_import_segments(struct pakfire_path* path, const char* s
        int r;
 
        // Is the path absolute?
-       if (*s == '/')
+       if (*s == '/') {
                path->is_absolute = 1;
 
+               // If we are joining strings and the new string is absolute,
+               // we throw away all segments.
+               pakfire_path_free_segments(path);
+       }
+
        // Copy path into buffer
        r = pakfire_string_set(buffer, s);
        if (r)
@@ -283,3 +295,48 @@ ERROR:
 
        return r;
 }
+
+int __pakfire_path_merge(char* buffer, const size_t length, const char* s1, const char* s2) {
+       struct pakfire_path* path = NULL;
+       int r;
+
+       // Check inputs
+       if (!buffer || !length || !s1 || !s2)
+               return -EINVAL;
+
+       // Parse the path
+       r = pakfire_path_parse(&path, s1);
+       if (r)
+               goto ERROR;
+
+       // Normalize the path
+       r = pakfire_path_do_normalize(path);
+       if (r)
+               goto ERROR;
+
+       // Drop the last segment
+       r = pakfire_path_remove_segment(path, path->num_segments - 1);
+       if (r)
+               goto ERROR;
+
+       // Add the second part
+       r = pakfire_path_import_segments(path, s2);
+       if (r)
+               goto ERROR;
+
+       // Normalize the path
+       r = pakfire_path_do_normalize(path);
+       if (r)
+               goto ERROR;
+
+       // Write back the path
+       r = pakfire_path_to_string(path, buffer, length);
+       if (r)
+               goto ERROR;
+
+ERROR:
+       if (path)
+               pakfire_path_free(path);
+
+       return r;
+}
index 1fab35bc4c0e0e68e6ee0c443f2515dbc352d509..e5c04b62fb19a8fcf18e440afa3e71d0f48d2170 100644 (file)
@@ -76,9 +76,28 @@ FAIL:
        return EXIT_FAILURE;
 }
 
+static int test_path_merge(const struct test* t) {
+       char path[PATH_MAX];
+
+       ASSERT_SUCCESS(pakfire_path_merge(path, "/usr/bin/sh", "bash"));
+       ASSERT_STRING_EQUALS(path, "/usr/bin/bash");
+
+       ASSERT_SUCCESS(pakfire_path_merge(path, "/usr/bin", "/bash"));
+       ASSERT_STRING_EQUALS(path, "/bash");
+
+       ASSERT_SUCCESS(pakfire_path_merge(path, "/usr/bin/sh", "../bin/bash"));
+       ASSERT_STRING_EQUALS(path, "/usr/bin/bash");
+
+       return EXIT_SUCCESS;
+
+FAIL:
+       return EXIT_FAILURE;
+}
+
 int main(int argc, const char* argv[]) {
        testsuite_add_test(test_path_normalize);
        testsuite_add_test(test_path_append);
+       testsuite_add_test(test_path_merge);
 
        return testsuite_run(argc, argv);
 }