__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 */
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);
}
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)
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;
+}
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);
}