From: Michael Tremer Date: Fri, 6 Oct 2023 14:04:04 +0000 (+0000) Subject: path: Add merge function to join two paths together X-Git-Tag: 0.9.30~1533 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9d71af43cca6ac1521000fe7deacea8bccd273a;p=pakfire.git path: Add merge function to join two paths together Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/include/pakfire/path.h b/src/libpakfire/include/pakfire/path.h index f35a87274..979bfa129 100644 --- a/src/libpakfire/include/pakfire/path.h +++ b/src/libpakfire/include/pakfire/path.h @@ -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 */ diff --git a/src/libpakfire/path.c b/src/libpakfire/path.c index 1a2b23aff..8e13cac11 100644 --- a/src/libpakfire/path.c +++ b/src/libpakfire/path.c @@ -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; +} diff --git a/tests/libpakfire/path.c b/tests/libpakfire/path.c index 1fab35bc4..e5c04b62f 100644 --- a/tests/libpakfire/path.c +++ b/tests/libpakfire/path.c @@ -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); }