diff options
-rw-r--r-- | src/filesystem.c | 48 | ||||
-rw-r--r-- | src/filesystem.h | 18 | ||||
-rw-r--r-- | src/state.c | 76 | ||||
-rw-r--r-- | test/lilv_test_utils.c | 11 | ||||
-rw-r--r-- | test/test_filesystem.c | 70 | ||||
-rw-r--r-- | test/test_state.c | 2 | ||||
-rw-r--r-- | test/test_util.c | 2 |
7 files changed, 60 insertions, 167 deletions
diff --git a/src/filesystem.c b/src/filesystem.c index d8f42f3..cce197d 100644 --- a/src/filesystem.c +++ b/src/filesystem.c @@ -5,6 +5,8 @@ #include "lilv_config.h" #include "lilv_internal.h" +#include "zix/allocator.h" +#include "zix/filesystem.h" #include "zix/path.h" #ifdef _WIN32 @@ -102,19 +104,6 @@ lilv_path_current(void) } char* -lilv_path_absolute(const char* path) -{ - if (lilv_path_is_absolute(path)) { - return lilv_strdup(path); - } - - char* cwd = getcwd(NULL, 0); - char* abs_path = zix_path_join(NULL, cwd, path); - free(cwd); - return abs_path; -} - -char* lilv_path_relative_to(const char* path, const char* base) { const size_t path_len = strlen(path); @@ -214,23 +203,6 @@ lilv_path_filename(const char* path) return ret; } -char* -lilv_path_canonical(const char* path) -{ - if (!path) { - return NULL; - } - -#if defined(_WIN32) - char* out = (char*)malloc(MAX_PATH); - GetFullPathName(path, MAX_PATH, out, NULL); - return out; -#else - char* real_path = realpath(path, NULL); - return real_path ? real_path : lilv_strdup(path); -#endif -} - bool lilv_is_directory(const char* path) { @@ -240,7 +212,7 @@ lilv_is_directory(const char* path) return (attrs != INVALID_FILE_ATTRIBUTES) && (attrs & FILE_ATTRIBUTE_DIRECTORY); #else - struct stat st; + struct stat st; return !stat(path, &st) && S_ISDIR(st.st_mode); #endif } @@ -468,11 +440,13 @@ lilv_file_equals(const char* a_path, const char* b_path) bool match = false; FILE* a_file = NULL; FILE* b_file = NULL; - char* const a_real = lilv_path_canonical(a_path); - char* const b_real = lilv_path_canonical(b_path); - if (!strcmp(a_real, b_real)) { + char* const a_real = zix_canonical_path(NULL, a_path); + char* const b_real = zix_canonical_path(NULL, b_path); + if (!a_real || !b_real) { + match = false; // At least one file doesn't exist + } else if (!strcmp(a_real, b_real)) { match = true; // Real paths match - } else if (lilv_file_size(a_path) != lilv_file_size(b_path)) { + } else if (lilv_file_size(a_real) != lilv_file_size(b_real)) { match = false; // Sizes differ } else if (!(a_file = fopen(a_real, "rb")) || !(b_file = fopen(b_real, "rb"))) { @@ -494,7 +468,7 @@ lilv_file_equals(const char* a_path, const char* b_path) if (b_file) { fclose(b_file); } - free(a_real); - free(b_real); + zix_free(NULL, a_real); + zix_free(NULL, b_real); return match; } diff --git a/src/filesystem.h b/src/filesystem.h index db398f3..ffbcbe5 100644 --- a/src/filesystem.h +++ b/src/filesystem.h @@ -21,15 +21,6 @@ char* lilv_path_current(void); /** - Return `path` as an absolute path. - - If `path` is absolute, an identical copy of it is returned. Otherwise, the - returned path is relative to the current working directory. -*/ -char* -lilv_path_absolute(const char* path); - -/** Return `path` relative to `base` if possible. If `path` is not within `base`, a copy is returned. Otherwise, an @@ -55,15 +46,6 @@ lilv_path_parent(const char* path); char* lilv_path_filename(const char* path); -/** - Return `path` as a canonicalized absolute path. - - This expands all symbolic links, relative references, and removes extra - directory separators. -*/ -char* -lilv_path_canonical(const char* path); - /// Return true iff `path` points to an existing directory bool lilv_is_directory(const char* path); diff --git a/src/state.c b/src/state.c index 2adb7bc..61558e9 100644 --- a/src/state.c +++ b/src/state.c @@ -259,11 +259,15 @@ make_path(LV2_State_Make_Path_Handle handle, const char* path) static char* abstract_path(LV2_State_Map_Path_Handle handle, const char* abs_path) { - LilvState* state = (LilvState*)handle; - char* path = NULL; - char* real_path = lilv_path_canonical(abs_path); - const PathMap key = {real_path, NULL}; - ZixTreeIter* iter = NULL; + LilvState* state = (LilvState*)handle; + char* path = NULL; + char* real_path = zix_canonical_path(NULL, abs_path); + if (!real_path) { + real_path = zix_path_lexically_normal(NULL, abs_path); + } + + const PathMap key = {real_path, NULL}; + ZixTreeIter* iter = NULL; if (abs_path[0] == '\0') { return lilv_strdup(abs_path); @@ -272,7 +276,7 @@ abstract_path(LV2_State_Map_Path_Handle handle, const char* abs_path) if (!zix_tree_find(state->abs2rel, &key, &iter)) { // Already mapped path in a previous call PathMap* pm = (PathMap*)zix_tree_get(iter); - free(real_path); + zix_free(NULL, real_path); return lilv_strdup(pm->rel); } @@ -299,7 +303,7 @@ abstract_path(LV2_State_Map_Path_Handle handle, const char* abs_path) LILV_ERRORF("Error copying state file %s (%s)\n", copy, strerror(st)); } } - free(real_path); + zix_free(NULL, real_path); zix_free(NULL, cpath); // Refer to the latest copy in plugin state @@ -379,14 +383,15 @@ add_features(const LV2_Feature* const* features, return ret; } -/// Return the canonical path for a directory with a trailing separator +/// Return a normal path for a directory with a trailing separator static char* -real_dir(const char* path) +normal_dir(const char* path) { - char* abs_path = lilv_path_canonical(path); - char* base = zix_path_join(NULL, abs_path, NULL); - free(abs_path); - return base; + char* const normal_path = zix_path_lexically_normal(NULL, path); + char* const base_path = zix_path_join(NULL, normal_path, NULL); + + zix_free(NULL, normal_path); + return base_path; } static const char* @@ -435,10 +440,10 @@ lilv_state_new_from_instance(const LilvPlugin* plugin, state->plugin_uri = lilv_node_duplicate(lilv_plugin_get_uri(plugin)); state->abs2rel = zix_tree_new(NULL, false, abs_cmp, NULL, map_free, NULL); state->rel2abs = zix_tree_new(NULL, false, rel_cmp, NULL, NULL, NULL); - state->scratch_dir = scratch_dir ? real_dir(scratch_dir) : NULL; - state->copy_dir = copy_dir ? real_dir(copy_dir) : NULL; - state->link_dir = link_dir ? real_dir(link_dir) : NULL; - state->dir = save_dir ? real_dir(save_dir) : NULL; + state->scratch_dir = scratch_dir ? normal_dir(scratch_dir) : NULL; + state->copy_dir = copy_dir ? normal_dir(copy_dir) : NULL; + state->link_dir = link_dir ? normal_dir(link_dir) : NULL; + state->dir = save_dir ? normal_dir(save_dir) : NULL; state->atom_Path = map->map(map->handle, LV2_ATOM__Path); LV2_State_Map_Path pmap = {state, abstract_path, absolute_path}; @@ -733,7 +738,7 @@ lilv_state_new_from_file(LilvWorld* world, return NULL; } - uint8_t* abs_path = (uint8_t*)lilv_path_absolute(path); + uint8_t* abs_path = (uint8_t*)zix_canonical_path(NULL, path); SerdNode node = serd_node_new_file_uri(abs_path, NULL, NULL, true); SerdEnv* env = serd_env_new(&node); SordModel* model = sord_new(world->world, SORD_SPO, false); @@ -746,16 +751,16 @@ lilv_state_new_from_file(LilvWorld* world, : sord_node_from_serd_node(world->world, env, &node, NULL, NULL); char* dirname = lilv_path_parent(path); - char* real_path = lilv_path_canonical(dirname); + char* real_path = zix_canonical_path(NULL, dirname); char* dir_path = zix_path_join(NULL, real_path, NULL); LilvState* state = new_state_from_model(world, map, model, subject_node, dir_path); zix_free(NULL, dir_path); - free(real_path); + zix_free(NULL, real_path); free(dirname); serd_node_free(&node); - free(abs_path); + zix_free(NULL, abs_path); serd_reader_free(reader); sord_free(model); serd_env_free(env); @@ -1003,9 +1008,10 @@ link_exists(const char* path, const void* data) if (zix_file_type(path) == ZIX_FILE_TYPE_NONE) { return false; } - char* real_path = lilv_path_canonical(path); + + char* real_path = zix_canonical_path(NULL, path); bool matches = !strcmp(real_path, target); - free(real_path); + zix_free(NULL, real_path); return !matches; } @@ -1221,12 +1227,12 @@ lilv_state_save(LilvWorld* world, return 1; } - char* abs_dir = real_dir(dir); + char* abs_dir = zix_canonical_path(NULL, dir); char* const path = zix_path_join(NULL, abs_dir, filename); FILE* fd = fopen(path, "w"); if (!fd) { LILV_ERRORF("Failed to open %s (%s)\n", path, strerror(errno)); - free(abs_dir); + zix_free(NULL, abs_dir); zix_free(NULL, path); return 4; } @@ -1245,7 +1251,7 @@ lilv_state_save(LilvWorld* world, // Set saved dir and uri (FIXME: const violation) zix_free(NULL, state->dir); lilv_node_free(state->uri); - ((LilvState*)state)->dir = lilv_strdup(abs_dir); + ((LilvState*)state)->dir = zix_path_join(NULL, abs_dir, ""); ((LilvState*)state)->uri = lilv_new_uri(world, (const char*)node.buf); serd_node_free(&file); @@ -1262,7 +1268,7 @@ lilv_state_save(LilvWorld* world, zix_free(NULL, manifest); } - free(abs_dir); + zix_free(NULL, abs_dir); zix_free(NULL, path); return ret; } @@ -1309,7 +1315,7 @@ static char* get_canonical_path(const LilvNode* const node) { char* const path = lilv_node_get_path(node, NULL); - char* const real_path = lilv_path_canonical(path); + char* const real_path = zix_canonical_path(NULL, path); free(path); return real_path; @@ -1326,8 +1332,10 @@ lilv_state_delete(LilvWorld* world, const LilvState* state) LilvNode* bundle = lilv_new_file_uri(world, NULL, state->dir); LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle); char* manifest_path = get_canonical_path(manifest); - const bool has_manifest = zix_file_type(manifest_path) != ZIX_FILE_TYPE_NONE; - SordModel* model = sord_new(world->world, SORD_SPO, false); + const bool has_manifest = + manifest_path && zix_file_type(manifest_path) == ZIX_FILE_TYPE_REGULAR; + + SordModel* model = sord_new(world->world, SORD_SPO, false); if (has_manifest) { // Read manifest into temporary local model @@ -1345,11 +1353,11 @@ lilv_state_delete(LilvWorld* world, const LilvState* state) // Remove state file const uint8_t* uri = sord_node_get_string(file); char* path = (char*)serd_file_uri_parse(uri, NULL); - char* real_path = lilv_path_canonical(path); - if (path) { + char* real_path = zix_canonical_path(NULL, path); + if (real_path) { try_unlink(state->dir, real_path); } - serd_free(real_path); + zix_free(NULL, real_path); serd_free(path); } @@ -1404,7 +1412,7 @@ lilv_state_delete(LilvWorld* world, const LilvState* state) } sord_free(model); - lilv_free(manifest_path); + zix_free(NULL, manifest_path); lilv_node_free(manifest); lilv_node_free(bundle); diff --git a/test/lilv_test_utils.c b/test/lilv_test_utils.c index 520b91a..e924873 100644 --- a/test/lilv_test_utils.c +++ b/test/lilv_test_utils.c @@ -8,6 +8,7 @@ #include "lilv/lilv.h" #include "serd/serd.h" #include "zix/allocator.h" +#include "zix/filesystem.h" #include "zix/path.h" #include <errno.h> @@ -32,13 +33,13 @@ lilv_test_env_new(void) env->plugin2_uri = lilv_new_uri(world, "http://example.org/foobar"); // Set custom LV2_PATH in build directory to only use test data - char* test_path = lilv_path_canonical(LILV_TEST_DIR); + char* test_path = zix_canonical_path(NULL, LILV_TEST_DIR); char* lv2_path = zix_path_join(NULL, test_path, "lv2"); LilvNode* path = lilv_new_string(world, lv2_path); lilv_world_set_option(world, LILV_OPTION_LV2_PATH, path); - zix_free(NULL, lv2_path); - free(test_path); lilv_node_free(path); + zix_free(NULL, lv2_path); + zix_free(NULL, test_path); return env; } @@ -63,13 +64,13 @@ create_bundle(LilvTestEnv* env, const char* plugin) { { - char* const test_dir = lilv_path_canonical(LILV_TEST_DIR); + char* const test_dir = zix_canonical_path(NULL, LILV_TEST_DIR); char* const bundle_dir = zix_path_join(NULL, test_dir, name); env->test_bundle_path = zix_path_join(NULL, bundle_dir, ""); zix_free(NULL, bundle_dir); - lilv_free(test_dir); + zix_free(NULL, test_dir); } if (lilv_create_directories(env->test_bundle_path)) { diff --git a/test/test_filesystem.c b/test/test_filesystem.c index dc4fd27..0e199c7 100644 --- a/test/test_filesystem.c +++ b/test/test_filesystem.c @@ -84,24 +84,6 @@ test_path_current(void) } static void -test_path_absolute(void) -{ - const char* const short_path = "a"; - const char* const long_path = "a/b/c"; - - char* const cwd = lilv_path_current(); - char* const expected_short = zix_path_join(NULL, cwd, short_path); - char* const expected_long = zix_path_join(NULL, cwd, long_path); - - assert(equals(lilv_path_absolute(short_path), expected_short)); - assert(equals(lilv_path_absolute(long_path), expected_long)); - - free(expected_long); - free(expected_short); - free(cwd); -} - -static void test_path_relative_to(void) { assert(equals(lilv_path_relative_to("/a/b", "/a/"), "b")); @@ -163,56 +145,6 @@ test_path_filename(void) } static void -test_path_canonical(void) -{ - char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); - char* const file_path = zix_path_join(NULL, temp_dir, "lilv_test_file"); - - FILE* f = fopen(file_path, "w"); - fprintf(f, "test\n"); - fclose(f); - -#ifndef _WIN32 - // Test symlink resolution - - char* const link_path = zix_path_join(NULL, temp_dir, "lilv_test_link"); - - assert(!lilv_symlink(file_path, link_path)); - - char* const real_file_path = lilv_path_canonical(file_path); - char* const real_link_path = lilv_path_canonical(link_path); - - assert(!strcmp(real_file_path, real_link_path)); - - assert(!lilv_remove(link_path)); - free(real_link_path); - free(real_file_path); - free(link_path); -#endif - - // Test dot segment resolution - - char* const parent_dir_1 = zix_path_join(NULL, temp_dir, ".."); - char* const parent_dir_2 = lilv_path_parent(temp_dir); - char* const real_parent_dir_1 = lilv_path_canonical(parent_dir_1); - char* const real_parent_dir_2 = lilv_path_canonical(parent_dir_2); - - assert(!strcmp(real_parent_dir_1, real_parent_dir_2)); - - // Clean everything up - - assert(!lilv_remove(file_path)); - assert(!lilv_remove(temp_dir)); - - free(real_parent_dir_2); - free(real_parent_dir_1); - free(parent_dir_2); - free(parent_dir_1); - free(file_path); - free(temp_dir); -} - -static void test_is_directory(void) { char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); @@ -431,11 +363,9 @@ main(void) test_path_is_absolute(); test_path_is_child(); test_path_current(); - test_path_absolute(); test_path_relative_to(); test_path_parent(); test_path_filename(); - test_path_canonical(); test_is_directory(); test_copy_file(); test_flock(); diff --git a/test/test_state.c b/test/test_state.c index 97567a2..78a4e5d 100644 --- a/test/test_state.c +++ b/test/test_state.c @@ -118,7 +118,7 @@ create_test_directories(void) /* On MacOS, temporary directories from mkdtemp involve symlinks, so resolve it here so that path comparisons in tests work. */ - dirs.top = lilv_path_canonical(top); + dirs.top = zix_canonical_path(NULL, top); dirs.shared = zix_path_join(NULL, dirs.top, "shared"); dirs.scratch = zix_path_join(NULL, dirs.shared, "scratch"); dirs.copy = zix_path_join(NULL, dirs.shared, "copy"); diff --git a/test/test_util.c b/test/test_util.c index f8fcd7f..94e5567 100644 --- a/test/test_util.c +++ b/test/test_util.c @@ -14,8 +14,6 @@ int main(void) { - assert(!lilv_path_canonical(NULL)); - char* const dir = lilv_create_temporary_directory("lilv_test_util_XXXXXX"); char* const a_path = zix_path_join(NULL, dir, "copy_a_XXXXXX"); char* const b_path = zix_path_join(NULL, dir, "copy_b_XXXXXX"); |