diff options
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | src/state.c | 39 | ||||
-rw-r--r-- | test/lilv_test.c | 12 | ||||
-rw-r--r-- | test/test.lv2/test.c | 56 | ||||
-rw-r--r-- | wscript | 4 |
5 files changed, 85 insertions, 32 deletions
@@ -1,3 +1,9 @@ +lilv (0.24.7) unstable; + + * Implement state:freePath feature + + -- David Robillard <d@drobilla.net> Sun, 08 Dec 2019 12:30:32 +0000 + lilv (0.24.6) stable; * Add more strict error detection when storing plugin state properties diff --git a/src/state.c b/src/state.c index ac1468c..23a659d 100644 --- a/src/state.c +++ b/src/state.c @@ -327,23 +327,34 @@ absolute_path(LV2_State_Map_Path_Handle handle, return path; } -/** Return a new features array which is `feature` added to `features`. */ +/** Return a new features array with built-in features added to `features`. */ static const LV2_Feature** -add_features(const LV2_Feature *const * features, - const LV2_Feature* map, const LV2_Feature* make) +add_features(const LV2_Feature* const* features, + const LV2_Feature* map, + const LV2_Feature* make, + const LV2_Feature* free) { size_t n_features = 0; for (; features && features[n_features]; ++n_features) {} const LV2_Feature** ret = (const LV2_Feature**)calloc( - n_features + 3, sizeof(LV2_Feature*)); + n_features + 4, sizeof(LV2_Feature*)); if (features) { memcpy(ret, features, n_features * sizeof(LV2_Feature*)); } - ret[n_features] = map; - ret[n_features + 1] = make; + size_t i = n_features; + if (map) { + ret[i++] = map; + } + if (make) { + ret[i++] = make; + } + if (free) { + ret[i++] = free; + } + return ret; } @@ -369,6 +380,12 @@ state_strerror(LV2_State_Status st) } } +static void +lilv_free_path(LV2_State_Free_Path_Handle handle, char* path) +{ + lilv_free(path); +} + LILV_API LilvState* lilv_state_new_from_instance(const LilvPlugin* plugin, LilvInstance* instance, @@ -398,8 +415,11 @@ lilv_state_new_from_instance(const LilvPlugin* plugin, LV2_Feature pmap_feature = { LV2_STATE__mapPath, &pmap }; LV2_State_Make_Path pmake = { state, make_path }; LV2_Feature pmake_feature = { LV2_STATE__makePath, &pmake }; + LV2_State_Free_Path pfree = { NULL, lilv_free_path }; + LV2_Feature pfree_feature = { LV2_STATE__freePath, &pfree }; features = sfeatures = add_features(features, &pmap_feature, - save_dir ? &pmake_feature : NULL); + save_dir ? &pmake_feature : NULL, + &pfree_feature); // Store port values if (get_value) { @@ -473,6 +493,9 @@ lilv_state_restore(const LilvState* state, (LilvState*)state, abstract_path, absolute_path }; LV2_Feature map_feature = { LV2_STATE__mapPath, &map_path }; + LV2_State_Free_Path free_path = { NULL, lilv_free_path }; + LV2_Feature free_feature = { LV2_STATE__freePath, &free_path }; + if (instance) { const LV2_Descriptor* desc = instance->lv2_descriptor; if (desc->extension_data) { @@ -481,7 +504,7 @@ lilv_state_restore(const LilvState* state, if (iface && iface->restore) { const LV2_Feature** sfeatures = add_features( - features, &map_feature, NULL); + features, &map_feature, NULL, &free_feature); iface->restore(instance->lv2_handle, retrieve_callback, (LV2_State_Handle)state, flags, sfeatures); diff --git a/test/lilv_test.c b/test/lilv_test.c index 7231c24..430187e 100644 --- a/test/lilv_test.c +++ b/test/lilv_test.c @@ -1572,6 +1572,12 @@ lilv_make_path(LV2_State_Make_Path_Handle handle, return lilv_path_join(temp_dir, path); } +static void +lilv_free_path(LV2_State_Free_Path_Handle handle, char* path) +{ + lilv_free(path); +} + static int test_state(void) { @@ -1768,7 +1774,11 @@ test_state(void) LV2_State_Make_Path make_path = { NULL, lilv_make_path }; LV2_Feature make_path_feature = { LV2_STATE__makePath, &make_path }; - const LV2_Feature* ffeatures[] = { &make_path_feature, &map_feature, NULL }; + LV2_State_Free_Path free_path = { NULL, lilv_free_path }; + LV2_Feature free_path_feature = { LV2_STATE__freePath, &free_path }; + const LV2_Feature* ffeatures[] = { + &make_path_feature, &map_feature, &free_path_feature, NULL + }; lilv_instance_deactivate(instance); lilv_instance_free(instance); diff --git a/test/test.lv2/test.c b/test/test.lv2/test.c index d6802a6..fa3fb6e 100644 --- a/test/test.lv2/test.c +++ b/test/test.lv2/test.c @@ -43,7 +43,8 @@ enum { }; typedef struct { - LV2_URID_Map* map; + LV2_URID_Map* map; + LV2_State_Free_Path* free_path; struct { LV2_URID atom_Float; @@ -59,23 +60,18 @@ typedef struct { } Test; static void -free_path(char* path) -{ - /* FIXME: Temporary hack to avoid mismatched malloc/free crashes on - Windows. The specifications needs a feature for this. */ -#ifndef _WIN32 - free(path); -#endif -} - -static void cleanup(LV2_Handle instance) { Test* test = (Test*)instance; if (test->rec_file) { fclose(test->rec_file); } - free_path(test->rec_file_path); + + if (test->free_path) { + test->free_path->free_path(test->free_path->handle, + test->rec_file_path); + } + free(instance); } @@ -123,6 +119,8 @@ instantiate(const LV2_Descriptor* descriptor, test->map->handle, LV2_ATOM__Float); } else if (!strcmp(features[i]->URI, LV2_STATE__makePath)) { make_path = (LV2_State_Make_Path*)features[i]->data; + } else if (!strcmp(features[i]->URI, LV2_STATE__freePath)) { + test->free_path = (LV2_State_Free_Path*)features[i]->data; } } @@ -133,6 +131,12 @@ instantiate(const LV2_Descriptor* descriptor, } if (make_path) { + if (!test->free_path) { + fprintf(stderr, "Host provided make_path without free_path\n"); + free(test); + return NULL; + } + test->rec_file_path = make_path->path(make_path->handle, "recfile"); if (!(test->rec_file = fopen(test->rec_file_path, "w"))) { fprintf(stderr, "ERROR: Failed to open rec file\n"); @@ -179,14 +183,21 @@ save(LV2_Handle instance, LV2_State_Map_Path* map_path = NULL; LV2_State_Make_Path* make_path = NULL; + LV2_State_Free_Path* free_path = NULL; for (int i = 0; features && features[i]; ++i) { if (!strcmp(features[i]->URI, LV2_STATE__mapPath)) { map_path = (LV2_State_Map_Path*)features[i]->data; } else if (!strcmp(features[i]->URI, LV2_STATE__makePath)) { make_path = (LV2_State_Make_Path*)features[i]->data; + } else if (!strcmp(features[i]->URI, LV2_STATE__freePath)) { + free_path = (LV2_State_Free_Path*)features[i]->data; } } + if (!map_path || !free_path) { + return LV2_STATE_ERR_NO_FEATURE; + } + store(callback_data, map_uri(plugin, "http://example.org/greeting"), "hello", @@ -281,8 +292,8 @@ save(LV2_Handle instance, map_uri(plugin, LV2_ATOM__Path), LV2_STATE_IS_POD); - free_path(apath); - free_path(apath2); + free_path->free_path(free_path->handle, apath); + free_path->free_path(free_path->handle, apath2); if (plugin->rec_file) { fflush(plugin->rec_file); @@ -296,7 +307,7 @@ save(LV2_Handle instance, map_uri(plugin, LV2_ATOM__Path), LV2_STATE_IS_POD); - free_path(apath); + free_path->free_path(free_path->handle, apath); } if (make_path) { @@ -312,8 +323,8 @@ save(LV2_Handle instance, strlen(apath) + 1, map_uri(plugin, LV2_ATOM__Path), LV2_STATE_IS_POD); - free_path(apath); - free_path(spath); + free_path->free_path(free_path->handle, apath); + free_path->free_path(free_path->handle, spath); } } @@ -329,10 +340,13 @@ restore(LV2_Handle instance, { Test* plugin = (Test*)instance; - LV2_State_Map_Path* map_path = NULL; + LV2_State_Map_Path* map_path = NULL; + LV2_State_Free_Path* free_path = NULL; for (int i = 0; features && features[i]; ++i) { if (!strcmp(features[i]->URI, LV2_STATE__mapPath)) { map_path = (LV2_State_Map_Path*)features[i]->data; + } else if (!strcmp(features[i]->URI, LV2_STATE__freePath)) { + free_path = (LV2_State_Free_Path*)features[i]->data; } } @@ -345,7 +359,7 @@ restore(LV2_Handle instance, map_uri(plugin, "http://example.org/num-runs"), &size, &type, &valflags); - if (!map_path) { + if (!map_path || !free_path) { return LV2_STATE_ERR_NO_FEATURE; } @@ -369,7 +383,7 @@ restore(LV2_Handle instance, fprintf(stderr, "error: Restored bad file contents `%s' != `Hello'\n", str); } - free_path(path); + free_path->free_path(free_path->handle, path); } apath = (char*)retrieve( @@ -384,7 +398,7 @@ restore(LV2_Handle instance, } else { fclose(sfile); } - free_path(spath); + free_path->free_path(free_path->handle, spath); } else { fprintf(stderr, "error: Failed to restore save file.\n"); } @@ -12,7 +12,7 @@ from waflib.extras import autowaf # major increment <=> incompatible changes # minor increment <=> compatible changes (additions) # micro increment <=> no interface changes -LILV_VERSION = '0.24.6' +LILV_VERSION = '0.24.7' LILV_MAJOR_VERSION = '0' # Mandatory waf variables @@ -88,7 +88,7 @@ def configure(conf): if not conf.env.BUILD_SHARED and not conf.env.BUILD_STATIC: conf.fatal('Neither a shared nor a static build requested') - conf.check_pkg('lv2 >= 1.16.0', uselib_store='LV2') + conf.check_pkg('lv2 >= 1.17.0', uselib_store='LV2') conf.check_pkg('serd-0 >= 0.30.0', uselib_store='SERD') conf.check_pkg('sord-0 >= 0.14.0', uselib_store='SORD') conf.check_pkg('sratom-0 >= 0.4.0', uselib_store='SRATOM') |