summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2022-11-12 17:54:13 -0500
committerDavid Robillard <d@drobilla.net>2022-11-16 10:22:55 -0500
commitdd5e8510cb40b853a5d252084660dc38aab7c665 (patch)
tree95245a5209501cb496b273dbca996458f8ed7152
parentff9f776a48cdca700468f9d5a93625979d77e745 (diff)
downloadlilv-dd5e8510cb40b853a5d252084660dc38aab7c665.tar.gz
lilv-dd5e8510cb40b853a5d252084660dc38aab7c665.tar.bz2
lilv-dd5e8510cb40b853a5d252084660dc38aab7c665.zip
Use zix_canonical_path()
-rw-r--r--src/filesystem.c48
-rw-r--r--src/filesystem.h18
-rw-r--r--src/state.c76
-rw-r--r--test/lilv_test_utils.c11
-rw-r--r--test/test_filesystem.c70
-rw-r--r--test/test_state.c2
-rw-r--r--test/test_util.c2
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");