From 1bb1de7ecd19a99a1a29a9a4d734fcc38c2ba9cc Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 18 Jan 2020 15:28:45 +0100 Subject: Fix deleting state bundles loaded from the model --- NEWS | 3 ++- src/state.c | 25 ++++++++++++++++------- test/lilv_test.c | 62 +++++++++++++++++++++++++++++--------------------------- 3 files changed, 52 insertions(+), 38 deletions(-) diff --git a/NEWS b/NEWS index a7c43a8..46f9d61 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,9 @@ lilv (0.24.7) unstable; * Implement state:freePath feature + * Fix deleting state bundles loaded from the model - -- David Robillard Sun, 08 Dec 2019 12:30:32 +0000 + -- David Robillard Sat, 18 Jan 2020 14:28:23 +0000 lilv (0.24.6) stable; diff --git a/src/state.c b/src/state.c index 5c3b90c..7e0f50d 100644 --- a/src/state.c +++ b/src/state.c @@ -1276,13 +1276,24 @@ lilv_state_delete(LilvWorld* world, try_unlink(state->dir, manifest_path); // Remove all known files from state bundle - for (ZixTreeIter* i = zix_tree_begin(state->abs2rel); - i != zix_tree_end(state->abs2rel); - i = zix_tree_iter_next(i)) { - const PathMap* pm = (const PathMap*)zix_tree_get(i); - char* path = lilv_path_join(state->dir, pm->rel); - try_unlink(state->dir, path); - free(path); + if (state->abs2rel) { + // State created from instance, get paths from map + for (ZixTreeIter* i = zix_tree_begin(state->abs2rel); + i != zix_tree_end(state->abs2rel); + i = zix_tree_iter_next(i)) { + const PathMap* pm = (const PathMap*)zix_tree_get(i); + char* path = lilv_path_join(state->dir, pm->rel); + try_unlink(state->dir, path); + free(path); + } + } else { + // State loaded from model, get paths from loaded properties + for (uint32_t i = 0; i < state->props.n; ++i) { + const Property* const p = &state->props.props[i]; + if (p->type == state->atom_Path) { + try_unlink(state->dir, (const char*)p->value); + } + } } if (rmdir(state->dir)) { diff --git a/test/lilv_test.c b/test/lilv_test.c index 430187e..8836cda 100644 --- a/test/lilv_test.c +++ b/test/lilv_test.c @@ -1734,35 +1734,38 @@ test_state(void) "state/state6.lv2", "state6.ttl"); TEST_ASSERT(!ret); - // Load default bundle into world and load state from it - uint8_t* state6_path = (uint8_t*)lilv_path_absolute("state/state6.lv2/"); - SerdNode state6_uri = serd_node_new_file_uri(state6_path, 0, 0, true); - LilvNode* test_state_bundle = lilv_new_uri(world, (const char*)state6_uri.buf); - LilvNode* test_state_node = lilv_new_uri(world, state_uri); - lilv_world_load_bundle(world, test_state_bundle); - lilv_world_load_resource(world, test_state_node); - serd_node_free(&state6_uri); - lilv_free(state6_path); - - LilvState* state6 = lilv_state_new_from_world(world, &map, test_state_node); - TEST_ASSERT(lilv_state_equals(state, state6)); // Round trip accuracy - - // Check that loaded state has correct URI - TEST_ASSERT(lilv_state_get_uri(state6)); - TEST_ASSERT(!strcmp(lilv_node_as_string(lilv_state_get_uri(state6)), - state_uri)); - - lilv_world_unload_resource(world, test_state_node); - lilv_world_unload_bundle(world, test_state_bundle); - - LilvState* state6_2 = lilv_state_new_from_world(world, &map, test_state_node); - TEST_ASSERT(!state6_2); // No longer present - lilv_state_free(state6_2); - - lilv_node_free(test_state_bundle); - lilv_node_free(test_state_node); - - unsetenv("LV2_STATE_BUNDLE"); + // Load state bundle into world and verify it matches + { + uint8_t* state6_path = (uint8_t*)lilv_path_absolute("state/state6.lv2/"); + SerdNode state6_uri = serd_node_new_file_uri(state6_path, 0, 0, true); + LilvNode* state6_bundle = lilv_new_uri(world, (const char*)state6_uri.buf); + LilvNode* state6_node = lilv_new_uri(world, state_uri); + lilv_world_load_bundle(world, state6_bundle); + lilv_world_load_resource(world, state6_node); + serd_node_free(&state6_uri); + lilv_free(state6_path); + + LilvState* state6 = lilv_state_new_from_world(world, &map, state6_node); + TEST_ASSERT(lilv_state_equals(state, state6)); // Round trip accuracy + + // Check that loaded state has correct URI + TEST_ASSERT(lilv_state_get_uri(state6)); + TEST_ASSERT(!strcmp(lilv_node_as_string(lilv_state_get_uri(state6)), + state_uri)); + + // Unload state from world + lilv_world_unload_resource(world, state6_node); + lilv_world_unload_bundle(world, state6_bundle); + + // Ensure that it is no longer present + TEST_ASSERT(!lilv_state_new_from_world(world, &map, state6_node)); + lilv_node_free(state6_bundle); + lilv_node_free(state6_node); + + // Delete state + lilv_state_delete(world, state6); + lilv_state_free(state6); + } // Make directories and test files support mkdir("temp", 0700); @@ -1889,7 +1892,6 @@ test_state(void) lilv_state_free(state3); lilv_state_free(state4); lilv_state_free(state5); - lilv_state_free(state6); lilv_state_free(fstate); lilv_state_free(fstate2); lilv_state_free(fstate3); -- cgit v1.2.1