diff options
75 files changed, 9989 insertions, 9923 deletions
diff --git a/bindings/test/bindings_test_plugin.c b/bindings/test/bindings_test_plugin.c index 1945c0d..0c3af4f 100644 --- a/bindings/test/bindings_test_plugin.c +++ b/bindings/test/bindings_test_plugin.c @@ -42,10 +42,10 @@ should be defined for readability. */ typedef enum { - TEST_CONTROL_IN = 0, - TEST_CONTROL_OUT = 1, - TEST_AUDIO_IN = 2, - TEST_AUDIO_OUT = 3 + TEST_CONTROL_IN = 0, + TEST_CONTROL_OUT = 1, + TEST_AUDIO_IN = 2, + TEST_AUDIO_OUT = 3 } PortIndex; /** @@ -54,7 +54,7 @@ typedef enum { every instance method. In this simple plugin, only port buffers need to be stored, since there is no additional instance data. */ typedef struct { - float* buf; + float* buf; } Test; /** @@ -73,9 +73,9 @@ instantiate(const LV2_Descriptor* descriptor, const char* bundle_path, const LV2_Feature* const* features) { - Test* test = (Test*)malloc(sizeof(Test)); + Test* test = (Test*)malloc(sizeof(Test)); - return (LV2_Handle)test; + return (LV2_Handle)test; } /** @@ -87,11 +87,8 @@ instantiate(const LV2_Descriptor* descriptor, context as run(). */ static void -connect_port(LV2_Handle instance, - uint32_t port, - void* data) -{ -} +connect_port(LV2_Handle instance, uint32_t port, void* data) +{} /** The activate() method is called by the host to initialise and prepare the @@ -104,14 +101,12 @@ connect_port(LV2_Handle instance, */ static void activate(LV2_Handle instance) -{ -} +{} /** Process a block of audio (audio thread, must be RT safe). */ static void run(LV2_Handle instance, uint32_t n_samples) -{ -} +{} /** The deactivate() method is the counterpart to activate() called by the host @@ -126,8 +121,7 @@ run(LV2_Handle instance, uint32_t n_samples) */ static void deactivate(LV2_Handle instance) -{ -} +{} /** Destroy a plugin instance (counterpart to instantiate()). @@ -138,7 +132,7 @@ deactivate(LV2_Handle instance) static void cleanup(LV2_Handle instance) { - free(instance); + free(instance); } /** @@ -154,7 +148,7 @@ cleanup(LV2_Handle instance) static const void* extension_data(const char* uri) { - return NULL; + return NULL; } /** @@ -162,16 +156,14 @@ extension_data(const char* uri) statically to avoid leaking memory and non-portable shared library constructors and destructors to clean up properly. */ -static const LV2_Descriptor descriptor = { - TEST_URI, - instantiate, - connect_port, - activate, - run, - deactivate, - cleanup, - extension_data -}; +static const LV2_Descriptor descriptor = {TEST_URI, + instantiate, + connect_port, + activate, + run, + deactivate, + cleanup, + extension_data}; /** The lv2_descriptor() function is the entry point to the plugin library. The @@ -187,10 +179,10 @@ LV2_SYMBOL_EXPORT const LV2_Descriptor* lv2_descriptor(uint32_t index) { - switch (index) { - case 0: - return &descriptor; - default: - return NULL; - } + switch (index) { + case 0: + return &descriptor; + default: + return NULL; + } } diff --git a/include/lilv/lilv.h b/include/lilv/lilv.h index af75913..b803cb1 100644 --- a/include/lilv/lilv.h +++ b/include/lilv/lilv.h @@ -30,73 +30,73 @@ #include <stdio.h> #ifdef LILV_SHARED -# ifdef _WIN32 -# define LILV_LIB_IMPORT __declspec(dllimport) -# define LILV_LIB_EXPORT __declspec(dllexport) -# else -# define LILV_LIB_IMPORT __attribute__((visibility("default"))) -# define LILV_LIB_EXPORT __attribute__((visibility("default"))) -# endif -# ifdef LILV_INTERNAL -# define LILV_API LILV_LIB_EXPORT -# else -# define LILV_API LILV_LIB_IMPORT -# endif +# ifdef _WIN32 +# define LILV_LIB_IMPORT __declspec(dllimport) +# define LILV_LIB_EXPORT __declspec(dllexport) +# else +# define LILV_LIB_IMPORT __attribute__((visibility("default"))) +# define LILV_LIB_EXPORT __attribute__((visibility("default"))) +# endif +# ifdef LILV_INTERNAL +# define LILV_API LILV_LIB_EXPORT +# else +# define LILV_API LILV_LIB_IMPORT +# endif #else -# define LILV_API +# define LILV_API #endif -#if defined(__GNUC__) && (__GNUC__ > 3 || \ - (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) -# define LILV_DEPRECATED __attribute__((__deprecated__)) +#if defined(__GNUC__) && \ + (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +# define LILV_DEPRECATED __attribute__((__deprecated__)) #else -# define LILV_DEPRECATED +# define LILV_DEPRECATED #endif #ifdef __cplusplus extern "C" { -# if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" -# endif +# if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +# endif #endif #define LILV_NS_DOAP "http://usefulinc.com/ns/doap#" #define LILV_NS_FOAF "http://xmlns.com/foaf/0.1/" #define LILV_NS_LILV "http://drobilla.net/ns/lilv#" -#define LILV_NS_LV2 "http://lv2plug.in/ns/lv2core#" -#define LILV_NS_OWL "http://www.w3.org/2002/07/owl#" -#define LILV_NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#" +#define LILV_NS_LV2 "http://lv2plug.in/ns/lv2core#" +#define LILV_NS_OWL "http://www.w3.org/2002/07/owl#" +#define LILV_NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#" #define LILV_NS_RDFS "http://www.w3.org/2000/01/rdf-schema#" -#define LILV_NS_XSD "http://www.w3.org/2001/XMLSchema#" +#define LILV_NS_XSD "http://www.w3.org/2001/XMLSchema#" -#define LILV_URI_ATOM_PORT "http://lv2plug.in/ns/ext/atom#AtomPort" -#define LILV_URI_AUDIO_PORT "http://lv2plug.in/ns/lv2core#AudioPort" +#define LILV_URI_ATOM_PORT "http://lv2plug.in/ns/ext/atom#AtomPort" +#define LILV_URI_AUDIO_PORT "http://lv2plug.in/ns/lv2core#AudioPort" #define LILV_URI_CONTROL_PORT "http://lv2plug.in/ns/lv2core#ControlPort" -#define LILV_URI_CV_PORT "http://lv2plug.in/ns/lv2core#CVPort" -#define LILV_URI_EVENT_PORT "http://lv2plug.in/ns/ext/event#EventPort" -#define LILV_URI_INPUT_PORT "http://lv2plug.in/ns/lv2core#InputPort" -#define LILV_URI_MIDI_EVENT "http://lv2plug.in/ns/ext/midi#MidiEvent" -#define LILV_URI_OUTPUT_PORT "http://lv2plug.in/ns/lv2core#OutputPort" -#define LILV_URI_PORT "http://lv2plug.in/ns/lv2core#Port" +#define LILV_URI_CV_PORT "http://lv2plug.in/ns/lv2core#CVPort" +#define LILV_URI_EVENT_PORT "http://lv2plug.in/ns/ext/event#EventPort" +#define LILV_URI_INPUT_PORT "http://lv2plug.in/ns/lv2core#InputPort" +#define LILV_URI_MIDI_EVENT "http://lv2plug.in/ns/ext/midi#MidiEvent" +#define LILV_URI_OUTPUT_PORT "http://lv2plug.in/ns/lv2core#OutputPort" +#define LILV_URI_PORT "http://lv2plug.in/ns/lv2core#Port" struct LilvInstanceImpl; -typedef struct LilvPluginImpl LilvPlugin; /**< LV2 Plugin. */ -typedef struct LilvPluginClassImpl LilvPluginClass; /**< Plugin Class. */ -typedef struct LilvPortImpl LilvPort; /**< Port. */ -typedef struct LilvScalePointImpl LilvScalePoint; /**< Scale Point. */ -typedef struct LilvUIImpl LilvUI; /**< Plugin UI. */ -typedef struct LilvNodeImpl LilvNode; /**< Typed Value. */ -typedef struct LilvWorldImpl LilvWorld; /**< Lilv World. */ -typedef struct LilvInstanceImpl LilvInstance; /**< Plugin instance. */ -typedef struct LilvStateImpl LilvState; /**< Plugin state. */ +typedef struct LilvPluginImpl LilvPlugin; /**< LV2 Plugin. */ +typedef struct LilvPluginClassImpl LilvPluginClass; /**< Plugin Class. */ +typedef struct LilvPortImpl LilvPort; /**< Port. */ +typedef struct LilvScalePointImpl LilvScalePoint; /**< Scale Point. */ +typedef struct LilvUIImpl LilvUI; /**< Plugin UI. */ +typedef struct LilvNodeImpl LilvNode; /**< Typed Value. */ +typedef struct LilvWorldImpl LilvWorld; /**< Lilv World. */ +typedef struct LilvInstanceImpl LilvInstance; /**< Plugin instance. */ +typedef struct LilvStateImpl LilvState; /**< Plugin state. */ -typedef void LilvIter; /**< Collection iterator */ -typedef void LilvPluginClasses; /**< set<PluginClass>. */ -typedef void LilvPlugins; /**< set<Plugin>. */ -typedef void LilvScalePoints; /**< set<ScalePoint>. */ -typedef void LilvUIs; /**< set<UI>. */ -typedef void LilvNodes; /**< set<Node>. */ +typedef void LilvIter; /**< Collection iterator */ +typedef void LilvPluginClasses; /**< set<PluginClass>. */ +typedef void LilvPlugins; /**< set<Plugin>. */ +typedef void LilvScalePoints; /**< set<ScalePoint>. */ +typedef void LilvUIs; /**< set<UI>. */ +typedef void LilvNodes; /**< set<Node>. */ /** @defgroup lilv Lilv @@ -115,7 +115,8 @@ typedef void LilvNodes; /**< set<Node>. */ library to be freed by code in the same library. It is otherwise equivalent to the standard C free() function. */ -LILV_API void +LILV_API +void lilv_free(void* ptr); /** @@ -131,7 +132,9 @@ lilv_free(void* ptr); general file URIs. Use lilv_file_uri_parse() instead. @return `uri` converted to a path, or NULL on failure (URI is not local). */ -LILV_API LILV_DEPRECATED const char* +LILV_API +LILV_DEPRECATED +const char* lilv_uri_to_path(const char* uri); /** @@ -142,14 +145,16 @@ lilv_uri_to_path(const char* uri); @param hostname If non-NULL, set to the hostname in the URI, if any. @return `uri` converted to a path, or NULL on failure (URI is not local). */ -LILV_API char* +LILV_API +char* lilv_file_uri_parse(const char* uri, char** hostname); /** Create a new URI value. Returned value must be freed by caller with lilv_node_free(). */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_new_uri(LilvWorld* world, const char* uri); /** @@ -162,54 +167,62 @@ lilv_new_uri(LilvWorld* world, const char* uri); Relative paths are resolved against the current working directory. Note that this may yield unexpected results if `host` is another machine. */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_new_file_uri(LilvWorld* world, const char* host, const char* path); /** Create a new string value (with no language). Returned value must be freed by caller with lilv_node_free(). */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_new_string(LilvWorld* world, const char* str); /** Create a new integer value. Returned value must be freed by caller with lilv_node_free(). */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_new_int(LilvWorld* world, int val); /** Create a new floating point value. Returned value must be freed by caller with lilv_node_free(). */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_new_float(LilvWorld* world, float val); /** Create a new boolean value. Returned value must be freed by caller with lilv_node_free(). */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_new_bool(LilvWorld* world, bool val); /** Free a LilvNode. It is safe to call this function on NULL. */ -LILV_API void +LILV_API +void lilv_node_free(LilvNode* val); /** Duplicate a LilvNode. */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_node_duplicate(const LilvNode* val); /** Return whether two values are equivalent. */ -LILV_API bool +LILV_API +bool lilv_node_equals(const LilvNode* value, const LilvNode* other); /** @@ -225,13 +238,15 @@ lilv_node_equals(const LilvNode* value, const LilvNode* other); <tr><th>Boolean</th><td>true</td></tr> </table> */ -LILV_API char* +LILV_API +char* lilv_node_get_turtle_token(const LilvNode* value); /** Return whether the value is a URI (resource). */ -LILV_API bool +LILV_API +bool lilv_node_is_uri(const LilvNode* value); /** @@ -239,13 +254,15 @@ lilv_node_is_uri(const LilvNode* value); Valid to call only if `lilv_node_is_uri(value)` returns true. Returned value is owned by `value` and must not be freed by caller. */ -LILV_API const char* +LILV_API +const char* lilv_node_as_uri(const LilvNode* value); /** Return whether the value is a blank node (resource with no URI). */ -LILV_API bool +LILV_API +bool lilv_node_is_blank(const LilvNode* value); /** @@ -253,27 +270,31 @@ lilv_node_is_blank(const LilvNode* value); Valid to call only if `lilv_node_is_blank(value)` returns true. Returned value is owned by `value` and must not be freed by caller. */ -LILV_API const char* +LILV_API +const char* lilv_node_as_blank(const LilvNode* value); /** Return whether this value is a literal (i.e. not a URI). Returns true if `value` is a string or numeric value. */ -LILV_API bool +LILV_API +bool lilv_node_is_literal(const LilvNode* value); /** Return whether this value is a string literal. Returns true if `value` is a string value (and not numeric). */ -LILV_API bool +LILV_API +bool lilv_node_is_string(const LilvNode* value); /** Return `value` as a string. */ -LILV_API const char* +LILV_API +const char* lilv_node_as_string(const LilvNode* value); /** @@ -281,13 +302,15 @@ lilv_node_as_string(const LilvNode* value); Returns NULL if `value` is not a file URI. Returned value must be freed by caller with lilv_free(). */ -LILV_API char* +LILV_API +char* lilv_node_get_path(const LilvNode* value, char** hostname); /** Return whether this value is a decimal literal. */ -LILV_API bool +LILV_API +bool lilv_node_is_float(const LilvNode* value); /** @@ -295,33 +318,38 @@ lilv_node_is_float(const LilvNode* value); Valid to call only if `lilv_node_is_float(value)` or `lilv_node_is_int(value)` returns true. */ -LILV_API float +LILV_API +float lilv_node_as_float(const LilvNode* value); /** Return whether this value is an integer literal. */ -LILV_API bool +LILV_API +bool lilv_node_is_int(const LilvNode* value); /** Return `value` as an integer. Valid to call only if `lilv_node_is_int(value)` returns true. */ -LILV_API int +LILV_API +int lilv_node_as_int(const LilvNode* value); /** Return whether this value is a boolean. */ -LILV_API bool +LILV_API +bool lilv_node_is_bool(const LilvNode* value); /** Return `value` as a bool. Valid to call only if `lilv_node_is_bool(value)` returns true. */ -LILV_API bool +LILV_API +bool lilv_node_as_bool(const LilvNode* value); /** @@ -357,29 +385,35 @@ lilv_node_as_bool(const LilvNode* value); } @endcode */ -#define LILV_FOREACH(colltype, iter, collection) \ - for (LilvIter* iter = lilv_ ## colltype ## _begin(collection); \ - !lilv_ ## colltype ## _is_end(collection, iter); \ - (iter) = lilv_ ## colltype ## _next(collection, iter)) +#define LILV_FOREACH(colltype, iter, collection) \ + for (LilvIter* iter = lilv_##colltype##_begin(collection); \ + !lilv_##colltype##_is_end(collection, iter); \ + (iter) = lilv_##colltype##_next(collection, iter)) /* LilvPluginClasses */ -LILV_API void +LILV_API +void lilv_plugin_classes_free(LilvPluginClasses* collection); -LILV_API unsigned +LILV_API +unsigned lilv_plugin_classes_size(const LilvPluginClasses* collection); -LILV_API LilvIter* +LILV_API +LilvIter* lilv_plugin_classes_begin(const LilvPluginClasses* collection); -LILV_API const LilvPluginClass* +LILV_API +const LilvPluginClass* lilv_plugin_classes_get(const LilvPluginClasses* collection, LilvIter* i); -LILV_API LilvIter* +LILV_API +LilvIter* lilv_plugin_classes_next(const LilvPluginClasses* collection, LilvIter* i); -LILV_API bool +LILV_API +bool lilv_plugin_classes_is_end(const LilvPluginClasses* collection, LilvIter* i); /** @@ -388,48 +422,61 @@ lilv_plugin_classes_is_end(const LilvPluginClasses* collection, LilvIter* i); modified by the caller in any way. @return NULL if no plugin class with `uri` is found in `classes`. */ -LILV_API const LilvPluginClass* +LILV_API +const LilvPluginClass* lilv_plugin_classes_get_by_uri(const LilvPluginClasses* classes, const LilvNode* uri); /* ScalePoints */ -LILV_API void +LILV_API +void lilv_scale_points_free(LilvScalePoints* collection); -LILV_API unsigned +LILV_API +unsigned lilv_scale_points_size(const LilvScalePoints* collection); -LILV_API LilvIter* +LILV_API +LilvIter* lilv_scale_points_begin(const LilvScalePoints* collection); -LILV_API const LilvScalePoint* +LILV_API +const LilvScalePoint* lilv_scale_points_get(const LilvScalePoints* collection, LilvIter* i); -LILV_API LilvIter* +LILV_API +LilvIter* lilv_scale_points_next(const LilvScalePoints* collection, LilvIter* i); -LILV_API bool +LILV_API +bool lilv_scale_points_is_end(const LilvScalePoints* collection, LilvIter* i); /* UIs */ -LILV_API void +LILV_API +void lilv_uis_free(LilvUIs* collection); -LILV_API unsigned +LILV_API +unsigned lilv_uis_size(const LilvUIs* collection); -LILV_API LilvIter* +LILV_API +LilvIter* lilv_uis_begin(const LilvUIs* collection); -LILV_API const LilvUI* +LILV_API +const LilvUI* lilv_uis_get(const LilvUIs* collection, LilvIter* i); -LILV_API LilvIter* +LILV_API +LilvIter* lilv_uis_next(const LilvUIs* collection, LilvIter* i); -LILV_API bool +LILV_API +bool lilv_uis_is_end(const LilvUIs* collection, LilvIter* i); /** @@ -438,60 +485,74 @@ lilv_uis_is_end(const LilvUIs* collection, LilvIter* i); modified by the caller in any way. @return NULL if no UI with `uri` is found in `list`. */ -LILV_API const LilvUI* -lilv_uis_get_by_uri(const LilvUIs* uis, - const LilvNode* uri); +LILV_API +const LilvUI* +lilv_uis_get_by_uri(const LilvUIs* uis, const LilvNode* uri); /* Nodes */ -LILV_API void +LILV_API +void lilv_nodes_free(LilvNodes* collection); -LILV_API unsigned +LILV_API +unsigned lilv_nodes_size(const LilvNodes* collection); -LILV_API LilvIter* +LILV_API +LilvIter* lilv_nodes_begin(const LilvNodes* collection); -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_nodes_get(const LilvNodes* collection, LilvIter* i); -LILV_API LilvIter* +LILV_API +LilvIter* lilv_nodes_next(const LilvNodes* collection, LilvIter* i); -LILV_API bool +LILV_API +bool lilv_nodes_is_end(const LilvNodes* collection, LilvIter* i); -LILV_API LilvNode* +LILV_API +LilvNode* lilv_nodes_get_first(const LilvNodes* collection); /** Return whether `values` contains `value`. */ -LILV_API bool +LILV_API +bool lilv_nodes_contains(const LilvNodes* nodes, const LilvNode* value); /** Return a new LilvNodes that contains all nodes from both `a` and `b`. */ -LILV_API LilvNodes* +LILV_API +LilvNodes* lilv_nodes_merge(const LilvNodes* a, const LilvNodes* b); /* Plugins */ -LILV_API unsigned +LILV_API +unsigned lilv_plugins_size(const LilvPlugins* collection); -LILV_API LilvIter* +LILV_API +LilvIter* lilv_plugins_begin(const LilvPlugins* collection); -LILV_API const LilvPlugin* +LILV_API +const LilvPlugin* lilv_plugins_get(const LilvPlugins* collection, LilvIter* i); -LILV_API LilvIter* +LILV_API +LilvIter* lilv_plugins_next(const LilvPlugins* collection, LilvIter* i); -LILV_API bool +LILV_API +bool lilv_plugins_is_end(const LilvPlugins* collection, LilvIter* i); /** @@ -500,9 +561,9 @@ lilv_plugins_is_end(const LilvPlugins* collection, LilvIter* i); modified by the caller in any way. @return NULL if no plugin with `uri` is found in `plugins`. */ -LILV_API const LilvPlugin* -lilv_plugins_get_by_uri(const LilvPlugins* plugins, - const LilvNode* uri); +LILV_API +const LilvPlugin* +lilv_plugins_get_by_uri(const LilvPlugins* plugins, const LilvNode* uri); /** @} @@ -518,7 +579,8 @@ lilv_plugins_get_by_uri(const LilvPlugins* plugins, Initialize a new, empty world. If initialization fails, NULL is returned. */ -LILV_API LilvWorld* +LILV_API +LilvWorld* lilv_world_new(void); /** @@ -551,10 +613,9 @@ lilv_world_new(void); @ref LILV_OPTION_DYN_MANIFEST @ref LILV_OPTION_LV2_PATH */ -LILV_API void -lilv_world_set_option(LilvWorld* world, - const char* uri, - const LilvNode* value); +LILV_API +void +lilv_world_set_option(LilvWorld* world, const char* uri, const LilvNode* value); /** Destroy the world, mwahaha. @@ -563,7 +624,8 @@ lilv_world_set_option(LilvWorld* world, (e.g. instances of LilvPlugin). Do not destroy the world until you are finished with all objects that came from it. */ -LILV_API void +LILV_API +void lilv_world_free(LilvWorld* world); /** @@ -577,7 +639,8 @@ lilv_world_free(LilvWorld* world); in special circumstances (e.g. development utilities, or hosts that ship with special plugin bundles which are installed to a known location). */ -LILV_API void +LILV_API +void lilv_world_load_all(LilvWorld* world); /** @@ -592,9 +655,9 @@ lilv_world_load_all(LilvWorld* world); unchanged between (or even during) program invocations. Plugins (among other things) MUST be identified by URIs (not paths) in save files. */ -LILV_API void -lilv_world_load_bundle(LilvWorld* world, - const LilvNode* bundle_uri); +LILV_API +void +lilv_world_load_bundle(LilvWorld* world, const LilvNode* bundle_uri); /** Load all specifications from currently loaded bundles. @@ -603,7 +666,8 @@ lilv_world_load_bundle(LilvWorld* world, necessary when using lilv_world_load_all(). This function parses the specifications and adds them to the model. */ -LILV_API void +LILV_API +void lilv_world_load_specifications(LilvWorld* world); /** @@ -613,7 +677,8 @@ lilv_world_load_specifications(LilvWorld* world); that explicitly load specific bundles, its use is not necessary when using lilv_world_load_all(). */ -LILV_API void +LILV_API +void lilv_world_load_plugin_classes(LilvWorld* world); /** @@ -624,7 +689,8 @@ lilv_world_load_plugin_classes(LilvWorld* world); have been separately loaded with lilv_world_load_resource(), they must be separately unloaded with lilv_world_unload_resource(). */ -LILV_API int +LILV_API +int lilv_world_unload_bundle(LilvWorld* world, const LilvNode* bundle_uri); /** @@ -636,9 +702,9 @@ lilv_world_unload_bundle(LilvWorld* world, const LilvNode* bundle_uri); All accessible data files linked to `resource` with rdfs:seeAlso will be loaded into the world model. */ -LILV_API int -lilv_world_load_resource(LilvWorld* world, - const LilvNode* resource); +LILV_API +int +lilv_world_load_resource(LilvWorld* world, const LilvNode* resource); /** Unload all the data associated with the given `resource`. @@ -648,21 +714,23 @@ lilv_world_load_resource(LilvWorld* world, This unloads all data loaded by a previous call to lilv_world_load_resource() with the given `resource`. */ -LILV_API int -lilv_world_unload_resource(LilvWorld* world, - const LilvNode* resource); +LILV_API +int +lilv_world_unload_resource(LilvWorld* world, const LilvNode* resource); /** Get the parent of all other plugin classes, lv2:Plugin. */ -LILV_API const LilvPluginClass* +LILV_API +const LilvPluginClass* lilv_world_get_plugin_class(const LilvWorld* world); /** Return a list of all found plugin classes. Returned list is owned by world and must not be freed by the caller. */ -LILV_API const LilvPluginClasses* +LILV_API +const LilvPluginClasses* lilv_world_get_plugin_classes(const LilvWorld* world); /** @@ -676,7 +744,8 @@ lilv_world_get_plugin_classes(const LilvWorld* world); The returned list and the plugins it contains are owned by `world` and must not be freed by caller. */ -LILV_API const LilvPlugins* +LILV_API +const LilvPlugins* lilv_world_get_all_plugins(const LilvWorld* world); /** @@ -684,7 +753,8 @@ lilv_world_get_all_plugins(const LilvWorld* world); Either `subject` or `object` may be NULL (i.e. a wildcard), but not both. @return All matches for the wildcard field, or NULL. */ -LILV_API LilvNodes* +LILV_API +LilvNodes* lilv_world_find_nodes(LilvWorld* world, const LilvNode* subject, const LilvNode* predicate, @@ -698,7 +768,8 @@ lilv_world_find_nodes(LilvWorld* world, case of only wanting a single value. @return the first matching node, or NULL if no matches are found. */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_world_get(LilvWorld* world, const LilvNode* subject, const LilvNode* predicate, @@ -715,7 +786,8 @@ lilv_world_get(LilvWorld* world, @param predicate Predicate (key) of statement, or NULL for anything. @param object Object (value) of statement, or NULL for anything. */ -LILV_API bool +LILV_API +bool lilv_world_ask(LilvWorld* world, const LilvNode* subject, const LilvNode* predicate, @@ -728,7 +800,8 @@ lilv_world_ask(LilvWorld* world, explicitly, and otherwise will attempt to derive a symbol from the URI. @return A string node that is a valid LV2 symbol, or NULL on error. */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_world_get_symbol(LilvWorld* world, const LilvNode* subject); /** @@ -747,7 +820,8 @@ lilv_world_get_symbol(LilvWorld* world, const LilvNode* subject); testing utilities, etc. @return true iff `plugin` is valid. */ -LILV_API bool +LILV_API +bool lilv_plugin_verify(const LilvPlugin* plugin); /** @@ -764,7 +838,8 @@ lilv_plugin_verify(const LilvPlugin* plugin); @return A shared URI value which must not be modified or freed. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_plugin_get_uri(const LilvPlugin* plugin); /** @@ -779,7 +854,8 @@ lilv_plugin_get_uri(const LilvPlugin* plugin); filesystem path, use lilv_file_uri_parse(). @return a shared string which must not be modified or freed. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_plugin_get_bundle_uri(const LilvPlugin* plugin); /** @@ -790,7 +866,8 @@ lilv_plugin_get_bundle_uri(const LilvPlugin* plugin); @return a list of complete URLs eg. "file:///foo/ABundle.lv2/aplug.ttl", which is shared and must not be modified or freed. */ -LILV_API const LilvNodes* +LILV_API +const LilvNodes* lilv_plugin_get_data_uris(const LilvPlugin* plugin); /** @@ -799,7 +876,8 @@ lilv_plugin_get_data_uris(const LilvPlugin* plugin); filesystem path, use lilv_file_uri_parse(). @return a shared string which must not be modified or freed. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_plugin_get_library_uri(const LilvPlugin* plugin); /** @@ -809,13 +887,15 @@ lilv_plugin_get_library_uri(const LilvPlugin* plugin); as a plugin identifier (use the URI for that). Returned value must be freed by the caller. */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_plugin_get_name(const LilvPlugin* plugin); /** Get the class this plugin belongs to (e.g. Filters). */ -LILV_API const LilvPluginClass* +LILV_API +const LilvPluginClass* lilv_plugin_get_class(const LilvPlugin* plugin); /** @@ -830,36 +910,38 @@ lilv_plugin_get_class(const LilvPlugin* plugin); sensibly represented as a LilvNodes (e.g. blank nodes). Return value must be freed by caller with lilv_nodes_free(). */ -LILV_API LilvNodes* -lilv_plugin_get_value(const LilvPlugin* plugin, - const LilvNode* predicate); +LILV_API +LilvNodes* +lilv_plugin_get_value(const LilvPlugin* plugin, const LilvNode* predicate); /** Return whether a feature is supported by a plugin. This will return true if the feature is an optional or required feature of the plugin. */ -LILV_API bool -lilv_plugin_has_feature(const LilvPlugin* plugin, - const LilvNode* feature); +LILV_API +bool +lilv_plugin_has_feature(const LilvPlugin* plugin, const LilvNode* feature); /** Get the LV2 Features supported (required or optionally) by a plugin. A feature is "supported" by a plugin if it is required OR optional. Since required features have special rules the host must obey, this function - probably shouldn't be used by normal hosts. Using lilv_plugin_get_optional_features() - and lilv_plugin_get_required_features() separately is best in most cases. + probably shouldn't be used by normal hosts. Using + lilv_plugin_get_optional_features() and lilv_plugin_get_required_features() + separately is best in most cases. Returned value must be freed by caller with lilv_nodes_free(). */ -LILV_API LilvNodes* +LILV_API +LilvNodes* lilv_plugin_get_supported_features(const LilvPlugin* plugin); /** Get the LV2 Features required by a plugin. - If a feature is required by a plugin, hosts MUST NOT use the plugin if they do not - understand (or are unable to support) that feature. + If a feature is required by a plugin, hosts MUST NOT use the plugin if they + do not understand (or are unable to support) that feature. All values returned here MUST be passed to the plugin's instantiate method (along with data, if necessary, as defined by the feature specification) @@ -867,7 +949,8 @@ lilv_plugin_get_supported_features(const LilvPlugin* plugin); Return value must be freed by caller with lilv_nodes_free(). */ -LILV_API LilvNodes* +LILV_API +LilvNodes* lilv_plugin_get_required_features(const LilvPlugin* plugin); /** @@ -878,28 +961,31 @@ lilv_plugin_get_required_features(const LilvPlugin* plugin); Return value must be freed by caller with lilv_nodes_free(). */ -LILV_API LilvNodes* +LILV_API +LilvNodes* lilv_plugin_get_optional_features(const LilvPlugin* plugin); /** Return whether or not a plugin provides a specific extension data. */ -LILV_API bool -lilv_plugin_has_extension_data(const LilvPlugin* plugin, - const LilvNode* uri); +LILV_API +bool +lilv_plugin_has_extension_data(const LilvPlugin* plugin, const LilvNode* uri); /** Get a sequence of all extension data provided by a plugin. This can be used to find which URIs lilv_instance_get_extension_data() will return a value for without instantiating the plugin. */ -LILV_API LilvNodes* +LILV_API +LilvNodes* lilv_plugin_get_extension_data(const LilvPlugin* plugin); /** Get the number of ports on this plugin. */ -LILV_API uint32_t +LILV_API +uint32_t lilv_plugin_get_num_ports(const LilvPlugin* plugin); /** @@ -916,7 +1002,8 @@ lilv_plugin_get_num_ports(const LilvPlugin* plugin); all float ports on a plugin, and may be significantly faster than repeated calls to lilv_port_get_range(). */ -LILV_API void +LILV_API +void lilv_plugin_get_port_ranges_float(const LilvPlugin* plugin, float* min_values, float* max_values, @@ -928,16 +1015,19 @@ lilv_plugin_get_port_ranges_float(const LilvPlugin* plugin, desired can be found quickly. REMEMBER TO TERMINATE THE PARAMETER LIST OF THIS FUNCTION WITH NULL OR VERY NASTY THINGS WILL HAPPEN. */ -LILV_API uint32_t +LILV_API +uint32_t lilv_plugin_get_num_ports_of_class(const LilvPlugin* plugin, - const LilvNode* class_1, ...); + const LilvNode* class_1, + ...); /** Variant of lilv_plugin_get_num_ports_of_class() that takes a va_list. This function calls va_arg() on `args` but does not call va_end(). */ -LILV_API uint32_t +LILV_API +uint32_t lilv_plugin_get_num_ports_of_class_va(const LilvPlugin* plugin, const LilvNode* class_1, va_list args); @@ -947,7 +1037,8 @@ lilv_plugin_get_num_ports_of_class_va(const LilvPlugin* plugin, The index of the latency port can be found with lilv_plugin_get_latency_port() ONLY if this function returns true. */ -LILV_API bool +LILV_API +bool lilv_plugin_has_latency(const LilvPlugin* plugin); /** @@ -959,22 +1050,24 @@ lilv_plugin_has_latency(const LilvPlugin* plugin); (by hosts with the ability/need) MUST provide this port, which is a control rate output port that reports the latency for each cycle in frames. */ -LILV_API uint32_t +LILV_API +uint32_t lilv_plugin_get_latency_port_index(const LilvPlugin* plugin); /** Get a port on `plugin` by `index`. */ -LILV_API const LilvPort* -lilv_plugin_get_port_by_index(const LilvPlugin* plugin, - uint32_t index); +LILV_API +const LilvPort* +lilv_plugin_get_port_by_index(const LilvPlugin* plugin, uint32_t index); /** Get a port on `plugin` by `symbol`. Note this function is slower than lilv_plugin_get_port_by_index(), especially on plugins with a very large number of ports. */ -LILV_API const LilvPort* +LILV_API +const LilvPort* lilv_plugin_get_port_by_symbol(const LilvPlugin* plugin, const LilvNode* symbol); @@ -988,7 +1081,8 @@ lilv_plugin_get_port_by_symbol(const LilvPlugin* plugin, ports for a particular designation. If `port_class` is NULL, any port with the given designation will be returned. */ -LILV_API const LilvPort* +LILV_API +const LilvPort* lilv_plugin_get_port_by_designation(const LilvPlugin* plugin, const LilvNode* port_class, const LilvNode* designation); @@ -999,7 +1093,8 @@ lilv_plugin_get_port_by_designation(const LilvPlugin* plugin, More information about the project can be read via lilv_world_find_nodes(), typically using properties from DOAP (e.g. doap:name). */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_plugin_get_project(const LilvPlugin* plugin); /** @@ -1007,7 +1102,8 @@ lilv_plugin_get_project(const LilvPlugin* plugin); Returns NULL if author name is not present. Returned value must be freed by caller. */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_plugin_get_author_name(const LilvPlugin* plugin); /** @@ -1015,7 +1111,8 @@ lilv_plugin_get_author_name(const LilvPlugin* plugin); Returns NULL if author email address is not present. Returned value must be freed by caller. */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_plugin_get_author_email(const LilvPlugin* plugin); /** @@ -1023,7 +1120,8 @@ lilv_plugin_get_author_email(const LilvPlugin* plugin); Returns NULL if author homepage is not present. Returned value must be freed by caller. */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_plugin_get_author_homepage(const LilvPlugin* plugin); /** @@ -1032,7 +1130,8 @@ lilv_plugin_get_author_homepage(const LilvPlugin* plugin); The plugin will still be usable, but hosts should hide them from their user interfaces to prevent users from using deprecated plugins. */ -LILV_API bool +LILV_API +bool lilv_plugin_is_replaced(const LilvPlugin* plugin); /** @@ -1041,7 +1140,8 @@ lilv_plugin_is_replaced(const LilvPlugin* plugin); This function is particularly useful for porting plugins in conjunction with an LV2 bridge such as NASPRO. */ -LILV_API void +LILV_API +void lilv_plugin_write_description(LilvWorld* world, const LilvPlugin* plugin, const LilvNode* base_uri, @@ -1053,7 +1153,8 @@ lilv_plugin_write_description(LilvWorld* world, This function is intended for use with lilv_plugin_write_description() to write a complete description of a plugin to a bundle. */ -LILV_API void +LILV_API +void lilv_plugin_write_manifest_entry(LilvWorld* world, const LilvPlugin* plugin, const LilvNode* base_uri, @@ -1073,7 +1174,8 @@ lilv_plugin_write_manifest_entry(LilvWorld* world, To actually load the data for each returned resource, use lilv_world_load_resource(). */ -LILV_API LilvNodes* +LILV_API +LilvNodes* lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type); /** @@ -1089,14 +1191,15 @@ lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type); @return A shared node which must not be modified or freed. */ -LILV_API const LilvNode* -lilv_port_get_node(const LilvPlugin* plugin, - const LilvPort* port); +LILV_API +const LilvNode* +lilv_port_get_node(const LilvPlugin* plugin, const LilvPort* port); /** Port analog of lilv_plugin_get_value(). */ -LILV_API LilvNodes* +LILV_API +LilvNodes* lilv_port_get_value(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* predicate); @@ -1108,7 +1211,8 @@ lilv_port_get_value(const LilvPlugin* plugin, simpler to use in the common case of only caring about one value. The caller is responsible for freeing the returned node. */ -LILV_API LilvNode* +LILV_API +LilvNode* lilv_port_get(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* predicate); @@ -1116,14 +1220,15 @@ lilv_port_get(const LilvPlugin* plugin, /** Return the LV2 port properties of a port. */ -LILV_API LilvNodes* -lilv_port_get_properties(const LilvPlugin* plugin, - const LilvPort* port); +LILV_API +LilvNodes* +lilv_port_get_properties(const LilvPlugin* plugin, const LilvPort* port); /** Return whether a port has a certain property. */ -LILV_API bool +LILV_API +bool lilv_port_has_property(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* property); @@ -1134,7 +1239,8 @@ lilv_port_has_property(const LilvPlugin* plugin, More precisely, this returns true iff the port has an atom:supports or an ev:supportsEvent property with `event_type` as the value. */ -LILV_API bool +LILV_API +bool lilv_port_supports_event(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* event_type); @@ -1144,18 +1250,18 @@ lilv_port_supports_event(const LilvPlugin* plugin, The index is only valid for the life of the plugin and may change between versions. For a stable identifier, use the symbol. */ -LILV_API uint32_t -lilv_port_get_index(const LilvPlugin* plugin, - const LilvPort* port); +LILV_API +uint32_t +lilv_port_get_index(const LilvPlugin* plugin, const LilvPort* port); /** Get the symbol of a port. The 'symbol' is a short string, a valid C identifier. Returned value is owned by `port` and must not be freed. */ -LILV_API const LilvNode* -lilv_port_get_symbol(const LilvPlugin* plugin, - const LilvPort* port); +LILV_API +const LilvNode* +lilv_port_get_symbol(const LilvPlugin* plugin, const LilvPort* port); /** Get the name of a port. @@ -1163,9 +1269,9 @@ lilv_port_get_symbol(const LilvPlugin* plugin, data file without a language tag). Returned value must be freed by the caller. */ -LILV_API LilvNode* -lilv_port_get_name(const LilvPlugin* plugin, - const LilvPort* port); +LILV_API +LilvNode* +lilv_port_get_name(const LilvPlugin* plugin, const LilvPort* port); /** Get all the classes of a port. @@ -1174,9 +1280,9 @@ lilv_port_get_name(const LilvPlugin* plugin, The returned list does not include lv2:Port, which is implied. Returned value is shared and must not be destroyed by caller. */ -LILV_API const LilvNodes* -lilv_port_get_classes(const LilvPlugin* plugin, - const LilvPort* port); +LILV_API +const LilvNodes* +lilv_port_get_classes(const LilvPlugin* plugin, const LilvPort* port); /** Determine if a port is of a given class (input, output, audio, etc). @@ -1186,7 +1292,8 @@ lilv_port_get_classes(const LilvPlugin* plugin, this function is designed so that Lilv is usable with any port types without requiring explicit support in Lilv. */ -LILV_API bool +LILV_API +bool lilv_port_is_a(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* port_class); @@ -1199,7 +1306,8 @@ lilv_port_is_a(const LilvPlugin* plugin, be freed by the caller using lilv_node_free()), or NULL if the value does not exist. */ -LILV_API void +LILV_API +void lilv_port_get_range(const LilvPlugin* plugin, const LilvPort* port, LilvNode** def, @@ -1213,9 +1321,9 @@ lilv_port_get_range(const LilvPlugin* plugin, Returned value may be NULL if `port` has no scale points, otherwise it must be freed by caller with lilv_scale_points_free(). */ -LILV_API LilvScalePoints* -lilv_port_get_scale_points(const LilvPlugin* plugin, - const LilvPort* port); +LILV_API +LilvScalePoints* +lilv_port_get_scale_points(const LilvPlugin* plugin, const LilvPort* port); /** @} @@ -1232,7 +1340,8 @@ lilv_port_get_scale_points(const LilvPlugin* plugin, @param node The subject of the state description (e.g. a preset URI). @return A new LilvState which must be freed with lilv_state_free(), or NULL. */ -LILV_API LilvState* +LILV_API +LilvState* lilv_state_new_from_world(LilvWorld* world, LV2_URID_Map* map, const LilvNode* node); @@ -1252,7 +1361,8 @@ lilv_state_new_from_world(LilvWorld* world, parse the file into the world model, i.e. the returned state is the only new memory consumed once this function returns. */ -LILV_API LilvState* +LILV_API +LilvState* lilv_state_new_from_file(LilvWorld* world, LV2_URID_Map* map, const LilvNode* subject, @@ -1261,7 +1371,8 @@ lilv_state_new_from_file(LilvWorld* world, /** Load a state snapshot from a string made by lilv_state_to_string(). */ -LILV_API LilvState* +LILV_API +LilvState* lilv_state_new_from_string(LilvWorld* world, LV2_URID_Map* map, const char* str); @@ -1356,41 +1467,46 @@ typedef const void* (*LilvGetPortValueFunc)(const char* port_symbol, See <a href="http://lv2plug.in/ns/ext/state/state.h">state.h</a> from the LV2 State extension for details on the `flags` and `features` parameters. */ -LILV_API LilvState* -lilv_state_new_from_instance(const LilvPlugin* plugin, - LilvInstance* instance, - LV2_URID_Map* map, - const char* scratch_dir, - const char* copy_dir, - const char* link_dir, - const char* save_dir, - LilvGetPortValueFunc get_value, - void* user_data, - uint32_t flags, - const LV2_Feature *const * features); +LILV_API +LilvState* +lilv_state_new_from_instance(const LilvPlugin* plugin, + LilvInstance* instance, + LV2_URID_Map* map, + const char* scratch_dir, + const char* copy_dir, + const char* link_dir, + const char* save_dir, + LilvGetPortValueFunc get_value, + void* user_data, + uint32_t flags, + const LV2_Feature* const* features); /** Free `state`. */ -LILV_API void +LILV_API +void lilv_state_free(LilvState* state); /** Return true iff `a` is equivalent to `b`. */ -LILV_API bool +LILV_API +bool lilv_state_equals(const LilvState* a, const LilvState* b); /** Return the number of properties in `state`. */ -LILV_API unsigned +LILV_API +unsigned lilv_state_get_num_properties(const LilvState* state); /** Get the URI of the plugin `state` applies to. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_state_get_plugin_uri(const LilvState* state); /** @@ -1398,21 +1514,23 @@ lilv_state_get_plugin_uri(const LilvState* state); This may return NULL if the state has not been saved and has no URI. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_state_get_uri(const LilvState* state); /** Get the label of `state`. */ -LILV_API const char* +LILV_API +const char* lilv_state_get_label(const LilvState* state); /** Set the label of `state`. */ -LILV_API void -lilv_state_set_label(LilvState* state, - const char* label); +LILV_API +void +lilv_state_set_label(LilvState* state, const char* label); /** Set a metadata property on `state`. @@ -1428,7 +1546,8 @@ lilv_state_set_label(LilvState* state, properties visible to hosts, but not plugins. This allows storing useful information such as comments or preset banks. */ -LILV_API int +LILV_API +int lilv_state_set_metadata(LilvState* state, uint32_t key, const void* value, @@ -1461,7 +1580,8 @@ typedef void (*LilvSetPortValueFunc)(const char* port_symbol, is useful in hosts that need to retrieve the port values in a state snapshot for special handling. */ -LILV_API void +LILV_API +void lilv_state_emit_port_values(const LilvState* state, LilvSetPortValueFunc set_value, void* user_data); @@ -1489,13 +1609,14 @@ lilv_state_emit_port_values(const LilvState* state, See <a href="http://lv2plug.in/ns/ext/state/state.h">state.h</a> from the LV2 State extension for details on the `flags` and `features` parameters. */ -LILV_API void -lilv_state_restore(const LilvState* state, - LilvInstance* instance, - LilvSetPortValueFunc set_value, - void* user_data, - uint32_t flags, - const LV2_Feature *const * features); +LILV_API +void +lilv_state_restore(const LilvState* state, + LilvInstance* instance, + LilvSetPortValueFunc set_value, + void* user_data, + uint32_t flags, + const LV2_Feature* const* features); /** Save state to a file. @@ -1514,14 +1635,15 @@ lilv_state_restore(const LilvState* state, If `uri` is NULL, the preset URI will be a file URI, but the bundle can safely be moved (i.e. the state file will use "<>" as the subject). */ -LILV_API int -lilv_state_save(LilvWorld* world, - LV2_URID_Map* map, - LV2_URID_Unmap* unmap, - const LilvState* state, - const char* uri, - const char* dir, - const char* filename); +LILV_API +int +lilv_state_save(LilvWorld* world, + LV2_URID_Map* map, + LV2_URID_Unmap* unmap, + const LilvState* state, + const char* uri, + const char* dir, + const char* filename); /** Save state to a string. This function does not use the filesystem. @@ -1535,7 +1657,8 @@ lilv_state_save(LilvWorld* world, doing, pass NULL for this, otherwise the state may not be restorable via lilv_state_new_from_string(). */ -LILV_API char* +LILV_API +char* lilv_state_to_string(LilvWorld* world, LV2_URID_Map* map, LV2_URID_Unmap* unmap, @@ -1557,9 +1680,9 @@ lilv_state_to_string(LilvWorld* world, then the manifest file is removed. If this results in an empty bundle, then the bundle directory is removed as well. */ -LILV_API int -lilv_state_delete(LilvWorld* world, - const LilvState* state); +LILV_API +int +lilv_state_delete(LilvWorld* world, const LilvState* state); /** @} @@ -1571,14 +1694,16 @@ lilv_state_delete(LilvWorld* world, Get the label of this scale point (enumeration value) Returned value is owned by `point` and must not be freed. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_scale_point_get_label(const LilvScalePoint* point); /** Get the value of this scale point (enumeration value) Returned value is owned by `point` and must not be freed. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_scale_point_get_value(const LilvScalePoint* point); /** @@ -1592,28 +1717,32 @@ lilv_scale_point_get_value(const LilvScalePoint* point); Returned value is owned by `plugin_class` and must not be freed by caller. Returned value may be NULL, if class has no parent. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_plugin_class_get_parent_uri(const LilvPluginClass* plugin_class); /** Get the URI of this plugin class. Returned value is owned by `plugin_class` and must not be freed by caller. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_plugin_class_get_uri(const LilvPluginClass* plugin_class); /** Get the label of this plugin class, ie "Oscillators". Returned value is owned by `plugin_class` and must not be freed by caller. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_plugin_class_get_label(const LilvPluginClass* plugin_class); /** Get the subclasses of this plugin class. Returned value must be freed by caller with lilv_plugin_classes_free(). */ -LILV_API LilvPluginClasses* +LILV_API +LilvPluginClasses* lilv_plugin_class_get_children(const LilvPluginClass* plugin_class); /** @@ -1634,9 +1763,9 @@ lilv_plugin_class_get_children(const LilvPluginClass* plugin_class); Truly private implementation details are hidden via `pimpl`. */ struct LilvInstanceImpl { - const LV2_Descriptor* lv2_descriptor; - LV2_Handle lv2_handle; - void* pimpl; + const LV2_Descriptor* lv2_descriptor; + LV2_Handle lv2_handle; + void* pimpl; }; /** @@ -1652,17 +1781,19 @@ struct LilvInstanceImpl { NULL may be passed if the host supports no additional features. @return NULL if instantiation failed. */ -LILV_API LilvInstance* -lilv_plugin_instantiate(const LilvPlugin* plugin, - double sample_rate, - const LV2_Feature*const* features); +LILV_API +LilvInstance* +lilv_plugin_instantiate(const LilvPlugin* plugin, + double sample_rate, + const LV2_Feature* const* features); /** Free a plugin instance. It is safe to call this function on NULL. `instance` is invalid after this call. */ -LILV_API void +LILV_API +void lilv_instance_free(LilvInstance* instance); #ifndef LILV_INTERNAL @@ -1674,7 +1805,7 @@ lilv_instance_free(LilvInstance* instance); static inline const char* lilv_instance_get_uri(const LilvInstance* instance) { - return instance->lv2_descriptor->URI; + return instance->lv2_descriptor->URI; } /** @@ -1687,8 +1818,8 @@ lilv_instance_connect_port(LilvInstance* instance, uint32_t port_index, void* data_location) { - instance->lv2_descriptor->connect_port - (instance->lv2_handle, port_index, data_location); + instance->lv2_descriptor->connect_port( + instance->lv2_handle, port_index, data_location); } /** @@ -1700,9 +1831,9 @@ lilv_instance_connect_port(LilvInstance* instance, static inline void lilv_instance_activate(LilvInstance* instance) { - if (instance->lv2_descriptor->activate) { - instance->lv2_descriptor->activate(instance->lv2_handle); - } + if (instance->lv2_descriptor->activate) { + instance->lv2_descriptor->activate(instance->lv2_handle); + } } /** @@ -1711,10 +1842,9 @@ lilv_instance_activate(LilvInstance* instance) guaranteed not to block. */ static inline void -lilv_instance_run(LilvInstance* instance, - uint32_t sample_count) +lilv_instance_run(LilvInstance* instance, uint32_t sample_count) { - instance->lv2_descriptor->run(instance->lv2_handle, sample_count); + instance->lv2_descriptor->run(instance->lv2_handle, sample_count); } /** @@ -1725,9 +1855,9 @@ lilv_instance_run(LilvInstance* instance, static inline void lilv_instance_deactivate(LilvInstance* instance) { - if (instance->lv2_descriptor->deactivate) { - instance->lv2_descriptor->deactivate(instance->lv2_handle); - } + if (instance->lv2_descriptor->deactivate) { + instance->lv2_descriptor->deactivate(instance->lv2_handle); + } } /** @@ -1736,14 +1866,13 @@ lilv_instance_deactivate(LilvInstance* instance) extension, though in all cases it is shared and must not be deleted. */ static inline const void* -lilv_instance_get_extension_data(const LilvInstance* instance, - const char* uri) +lilv_instance_get_extension_data(const LilvInstance* instance, const char* uri) { - if (instance->lv2_descriptor->extension_data) { - return instance->lv2_descriptor->extension_data(uri); - } + if (instance->lv2_descriptor->extension_data) { + return instance->lv2_descriptor->extension_data(uri); + } - return NULL; + return NULL; } /** @@ -1756,7 +1885,7 @@ lilv_instance_get_extension_data(const LilvInstance* instance, static inline const LV2_Descriptor* lilv_instance_get_descriptor(const LilvInstance* instance) { - return instance->lv2_descriptor; + return instance->lv2_descriptor; } /** @@ -1769,7 +1898,7 @@ lilv_instance_get_descriptor(const LilvInstance* instance) static inline LV2_Handle lilv_instance_get_handle(const LilvInstance* instance) { - return instance->lv2_handle; + return instance->lv2_handle; } #endif /* LILV_INTERNAL */ @@ -1784,7 +1913,8 @@ lilv_instance_get_handle(const LilvInstance* instance) Get all UIs for `plugin`. Returned value must be freed by caller using lilv_uis_free(). */ -LILV_API LilvUIs* +LILV_API +LilvUIs* lilv_plugin_get_uis(const LilvPlugin* plugin); /** @@ -1792,7 +1922,8 @@ lilv_plugin_get_uis(const LilvPlugin* plugin); @param ui The Plugin UI @return a shared value which must not be modified or freed. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_ui_get_uri(const LilvUI* ui); /** @@ -1803,7 +1934,8 @@ lilv_ui_get_uri(const LilvUI* ui); Note that in most cases lilv_ui_is_supported() should be used, which avoids the need to use this function (and type specific logic). */ -LILV_API const LilvNodes* +LILV_API +const LilvNodes* lilv_ui_get_classes(const LilvUI* ui); /** @@ -1811,7 +1943,8 @@ lilv_ui_get_classes(const LilvUI* ui); @param ui The Plugin UI @param class_uri The URI of the LV2 UI type to check this UI against */ -LILV_API bool +LILV_API +bool lilv_ui_is_a(const LilvUI* ui, const LilvNode* class_uri); /** @@ -1832,7 +1965,8 @@ typedef unsigned (*LilvUISupportedFunc)(const char* container_type_uri, which is owned by `ui` and must not be freed by the caller. @return The embedding quality level returned by `supported_func`. */ -LILV_API unsigned +LILV_API +unsigned lilv_ui_is_supported(const LilvUI* ui, LilvUISupportedFunc supported_func, const LilvNode* container_type, @@ -1843,7 +1977,8 @@ lilv_ui_is_supported(const LilvUI* ui, @param ui The Plugin UI @return a shared value which must not be modified or freed. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_ui_get_bundle_uri(const LilvUI* ui); /** @@ -1851,7 +1986,8 @@ lilv_ui_get_bundle_uri(const LilvUI* ui); @param ui The Plugin UI @return a shared value which must not be modified or freed. */ -LILV_API const LilvNode* +LILV_API +const LilvNode* lilv_ui_get_binary_uri(const LilvUI* ui); /** @@ -1860,9 +1996,9 @@ lilv_ui_get_binary_uri(const LilvUI* ui); */ #ifdef __cplusplus -# if defined(__clang__) -# pragma clang diagnostic pop -# endif +# if defined(__clang__) +# pragma clang diagnostic pop +# endif } /* extern "C" */ #endif diff --git a/include/lilv/lilvmm.hpp b/include/lilv/lilvmm.hpp index 011c9c8..33a0dcd 100644 --- a/include/lilv/lilvmm.hpp +++ b/include/lilv/lilvmm.hpp @@ -26,11 +26,11 @@ namespace Lilv { #if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated-declarations" #elif defined(__GNUC__) && __GNUC__ > 4 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif struct Instance; @@ -49,348 +49,390 @@ struct World; LILV_DEPRECATED static inline const char* -uri_to_path(const char* uri) { - return lilv_uri_to_path(uri); +uri_to_path(const char* uri) +{ + return lilv_uri_to_path(uri); } #if defined(__clang__) -# pragma clang diagnostic pop +# pragma clang diagnostic pop #elif defined(__GNUC__) && __GNUC__ > 4 -# pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif #define LILV_WRAP0(RT, prefix, name) \ - inline RT name() { return lilv_ ## prefix ## _ ## name (me); } + inline RT name() { return lilv_##prefix##_##name(me); } #define LILV_WRAP0_VOID(prefix, name) \ - inline void name() { lilv_ ## prefix ## _ ## name(me); } + inline void name() { lilv_##prefix##_##name(me); } #define LILV_WRAP1(RT, prefix, name, T1, a1) \ - inline RT name(T1 a1) { return lilv_ ## prefix ## _ ## name (me, a1); } + inline RT name(T1 a1) { return lilv_##prefix##_##name(me, a1); } #define LILV_WRAP1_VOID(prefix, name, T1, a1) \ - inline void name(T1 a1) { lilv_ ## prefix ## _ ## name(me, a1); } + inline void name(T1 a1) { lilv_##prefix##_##name(me, a1); } #define LILV_WRAP2(RT, prefix, name, T1, a1, T2, a2) \ - inline RT name(T1 a1, T2 a2) { \ - return lilv_ ## prefix ## _ ## name(me, a1, a2); \ - } + inline RT name(T1 a1, T2 a2) { return lilv_##prefix##_##name(me, a1, a2); } #define LILV_WRAP3(RT, prefix, name, T1, a1, T2, a2, T3, a3) \ - inline RT name(T1 a1, T2 a2, T3 a3) { \ - return lilv_ ## prefix ## _ ## name(me, a1, a2, a3); \ - } + inline RT name(T1 a1, T2 a2, T3 a3) \ + { \ + return lilv_##prefix##_##name(me, a1, a2, a3); \ + } #define LILV_WRAP2_VOID(prefix, name, T1, a1, T2, a2) \ - inline void name(T1 a1, T2 a2) { lilv_ ## prefix ## _ ## name(me, a1, a2); } + inline void name(T1 a1, T2 a2) { lilv_##prefix##_##name(me, a1, a2); } #ifndef SWIG -#define LILV_WRAP_CONVERSION(CT) \ - inline operator CT*() const { return me; } +# define LILV_WRAP_CONVERSION(CT) \ + inline operator CT*() const { return me; } #else -#define LILV_WRAP_CONVERSION(CT) +# define LILV_WRAP_CONVERSION(CT) #endif struct Node { - inline Node(const LilvNode* node) : me(lilv_node_duplicate(node)) {} - - inline Node(const Node& copy) : me(lilv_node_duplicate(copy.me)) {} - - inline Node& operator=(const Node& rhs) - { - if (&rhs != this) { - lilv_node_free(me); - me = lilv_node_duplicate(rhs.me); - } - return *this; - } - - inline Node(Node&& other) noexcept : me(other.me) { other.me = nullptr; } - - inline Node& operator=(Node&& rhs) noexcept - { - if (&rhs != this) { - me = rhs.me; - rhs.me = nullptr; - } - return *this; - } - - inline ~Node() { lilv_node_free(me); } - - inline bool equals(const Node& other) const { - return lilv_node_equals(me, other.me); - } - - inline bool operator==(const Node& other) const { return equals(other); } - - LILV_WRAP_CONVERSION(LilvNode); - - LILV_WRAP0(char*, node, get_turtle_token); - LILV_WRAP0(bool, node, is_uri); - LILV_WRAP0(const char*, node, as_uri); - LILV_WRAP0(bool, node, is_blank); - LILV_WRAP0(const char*, node, as_blank); - LILV_WRAP0(bool, node, is_literal); - LILV_WRAP0(bool, node, is_string); - LILV_WRAP0(const char*, node, as_string); - LILV_WRAP0(bool, node, is_float); - LILV_WRAP0(float, node, as_float); - LILV_WRAP0(bool, node, is_int); - LILV_WRAP0(int, node, as_int); - LILV_WRAP0(bool, node, is_bool); - LILV_WRAP0(bool, node, as_bool); - - LilvNode* me; + inline Node(const LilvNode* node) + : me(lilv_node_duplicate(node)) + {} + + inline Node(const Node& copy) + : me(lilv_node_duplicate(copy.me)) + {} + + inline Node& operator=(const Node& rhs) + { + if (&rhs != this) { + lilv_node_free(me); + me = lilv_node_duplicate(rhs.me); + } + return *this; + } + + inline Node(Node&& other) noexcept + : me(other.me) + { + other.me = nullptr; + } + + inline Node& operator=(Node&& rhs) noexcept + { + if (&rhs != this) { + me = rhs.me; + rhs.me = nullptr; + } + return *this; + } + + inline ~Node() { lilv_node_free(me); } + + inline bool equals(const Node& other) const + { + return lilv_node_equals(me, other.me); + } + + inline bool operator==(const Node& other) const { return equals(other); } + + LILV_WRAP_CONVERSION(LilvNode); + + LILV_WRAP0(char*, node, get_turtle_token); + LILV_WRAP0(bool, node, is_uri); + LILV_WRAP0(const char*, node, as_uri); + LILV_WRAP0(bool, node, is_blank); + LILV_WRAP0(const char*, node, as_blank); + LILV_WRAP0(bool, node, is_literal); + LILV_WRAP0(bool, node, is_string); + LILV_WRAP0(const char*, node, as_string); + LILV_WRAP0(bool, node, is_float); + LILV_WRAP0(float, node, as_float); + LILV_WRAP0(bool, node, is_int); + LILV_WRAP0(int, node, as_int); + LILV_WRAP0(bool, node, is_bool); + LILV_WRAP0(bool, node, as_bool); + + LilvNode* me; }; struct ScalePoint { - inline ScalePoint(const LilvScalePoint* c_obj) : me(c_obj) {} - LILV_WRAP_CONVERSION(const LilvScalePoint); + inline ScalePoint(const LilvScalePoint* c_obj) + : me(c_obj) + {} - LILV_WRAP0(const LilvNode*, scale_point, get_label); - LILV_WRAP0(const LilvNode*, scale_point, get_value); + LILV_WRAP_CONVERSION(const LilvScalePoint); - const LilvScalePoint* me; + LILV_WRAP0(const LilvNode*, scale_point, get_label); + LILV_WRAP0(const LilvNode*, scale_point, get_value); + + const LilvScalePoint* me; }; struct PluginClass { - inline PluginClass(const LilvPluginClass* c_obj) : me(c_obj) {} - LILV_WRAP_CONVERSION(const LilvPluginClass); + inline PluginClass(const LilvPluginClass* c_obj) + : me(c_obj) + {} + + LILV_WRAP_CONVERSION(const LilvPluginClass); - LILV_WRAP0(Node, plugin_class, get_parent_uri); - LILV_WRAP0(Node, plugin_class, get_uri); - LILV_WRAP0(Node, plugin_class, get_label); - LILV_WRAP0(LilvPluginClasses*, plugin_class, get_children); + LILV_WRAP0(Node, plugin_class, get_parent_uri); + LILV_WRAP0(Node, plugin_class, get_uri); + LILV_WRAP0(Node, plugin_class, get_label); + LILV_WRAP0(LilvPluginClasses*, plugin_class, get_children); - const LilvPluginClass* me; + const LilvPluginClass* me; }; -#define LILV_WRAP_COLL(CT, ET, prefix) \ - inline CT(const Lilv ## CT* c_obj) : me(c_obj) {} \ - LILV_WRAP_CONVERSION(const Lilv ## CT); \ - LILV_WRAP0(unsigned, prefix, size); \ - LILV_WRAP1(ET, prefix, get, LilvIter*, i); \ - LILV_WRAP0(LilvIter*, prefix, begin); \ - LILV_WRAP1(LilvIter*, prefix, next, LilvIter*, i); \ - LILV_WRAP1(bool, prefix, is_end, LilvIter*, i); \ - const Lilv ## CT* me; \ +#define LILV_WRAP_COLL(CT, ET, prefix) \ + inline CT(const Lilv##CT* c_obj) \ + : me(c_obj) \ + {} \ + LILV_WRAP_CONVERSION(const Lilv##CT); \ + LILV_WRAP0(unsigned, prefix, size); \ + LILV_WRAP1(ET, prefix, get, LilvIter*, i); \ + LILV_WRAP0(LilvIter*, prefix, begin); \ + LILV_WRAP1(LilvIter*, prefix, next, LilvIter*, i); \ + LILV_WRAP1(bool, prefix, is_end, LilvIter*, i); \ + const Lilv##CT* me; struct PluginClasses { - LILV_WRAP_COLL(PluginClasses, PluginClass, plugin_classes); - LILV_WRAP1(PluginClass, plugin_classes, - get_by_uri, const LilvNode*, uri); + LILV_WRAP_COLL(PluginClasses, PluginClass, plugin_classes); + LILV_WRAP1(PluginClass, plugin_classes, get_by_uri, const LilvNode*, uri); }; struct ScalePoints { - LILV_WRAP_COLL(ScalePoints, ScalePoint, scale_points); + LILV_WRAP_COLL(ScalePoints, ScalePoint, scale_points); }; struct Nodes { - LILV_WRAP_COLL(Nodes, Node, nodes); - LILV_WRAP1(bool, nodes, contains, const Node&, node); - LILV_WRAP0(Node, nodes, get_first); + LILV_WRAP_COLL(Nodes, Node, nodes); + LILV_WRAP1(bool, nodes, contains, const Node&, node); + LILV_WRAP0(Node, nodes, get_first); }; struct UI { - inline UI(const LilvUI* c_obj) : me(c_obj) {} - LILV_WRAP_CONVERSION(const LilvUI); - - LILV_WRAP0(const LilvNode*, ui, get_uri); - LILV_WRAP0(const LilvNode*, ui, get_bundle_uri); - LILV_WRAP0(const LilvNode*, ui, get_binary_uri); - LILV_WRAP0(const LilvNodes*, ui, get_classes); - /*LILV_WRAP3(bool, ui, is_supported, - LilvUISupportedFunc, supported_func, - const LilvNode*, container_type, - const LilvNode**, ui_type);*/ - LILV_WRAP1(bool, ui, is_a, const LilvNode*, class_uri); - - const LilvUI* me; + inline UI(const LilvUI* c_obj) + : me(c_obj) + {} + + LILV_WRAP_CONVERSION(const LilvUI); + + LILV_WRAP0(const LilvNode*, ui, get_uri); + LILV_WRAP0(const LilvNode*, ui, get_bundle_uri); + LILV_WRAP0(const LilvNode*, ui, get_binary_uri); + LILV_WRAP0(const LilvNodes*, ui, get_classes); + /*LILV_WRAP3(bool, ui, is_supported, + LilvUISupportedFunc, supported_func, + const LilvNode*, container_type, + const LilvNode**, ui_type);*/ + LILV_WRAP1(bool, ui, is_a, const LilvNode*, class_uri); + + const LilvUI* me; }; struct UIs { - LILV_WRAP_COLL(UIs, UI, uis); + LILV_WRAP_COLL(UIs, UI, uis); }; struct Port { - inline Port(const LilvPlugin* p, const LilvPort* c_obj) - : parent(p), me(c_obj) - {} + inline Port(const LilvPlugin* p, const LilvPort* c_obj) + : parent(p) + , me(c_obj) + {} - LILV_WRAP_CONVERSION(const LilvPort); + LILV_WRAP_CONVERSION(const LilvPort); #define LILV_PORT_WRAP0(RT, name) \ - inline RT name () { return lilv_port_ ## name (parent, me); } + inline RT name() { return lilv_port_##name(parent, me); } #define LILV_PORT_WRAP1(RT, name, T1, a1) \ - inline RT name (T1 a1) { return lilv_port_ ## name (parent, me, a1); } - - LILV_PORT_WRAP1(LilvNodes*, get_value, LilvNode*, predicate); - LILV_PORT_WRAP0(LilvNodes*, get_properties) - LILV_PORT_WRAP1(bool, has_property, LilvNode*, property_uri); - LILV_PORT_WRAP1(bool, supports_event, LilvNode*, event_uri); - LILV_PORT_WRAP0(const LilvNode*, get_symbol); - LILV_PORT_WRAP0(LilvNode*, get_name); - LILV_PORT_WRAP0(const LilvNodes*, get_classes); - LILV_PORT_WRAP1(bool, is_a, LilvNode*, port_class); - LILV_PORT_WRAP0(LilvScalePoints*, get_scale_points); - - // TODO: get_range (output parameters) - - const LilvPlugin* parent; - const LilvPort* me; + inline RT name(T1 a1) { return lilv_port_##name(parent, me, a1); } + + LILV_PORT_WRAP1(LilvNodes*, get_value, LilvNode*, predicate); + LILV_PORT_WRAP0(LilvNodes*, get_properties) + LILV_PORT_WRAP1(bool, has_property, LilvNode*, property_uri); + LILV_PORT_WRAP1(bool, supports_event, LilvNode*, event_uri); + LILV_PORT_WRAP0(const LilvNode*, get_symbol); + LILV_PORT_WRAP0(LilvNode*, get_name); + LILV_PORT_WRAP0(const LilvNodes*, get_classes); + LILV_PORT_WRAP1(bool, is_a, LilvNode*, port_class); + LILV_PORT_WRAP0(LilvScalePoints*, get_scale_points); + + // TODO: get_range (output parameters) + + const LilvPlugin* parent; + const LilvPort* me; }; struct Plugin { - inline Plugin(const LilvPlugin* c_obj) : me(c_obj) {} - LILV_WRAP_CONVERSION(const LilvPlugin); - - LILV_WRAP0(bool, plugin, verify); - LILV_WRAP0(Node, plugin, get_uri); - LILV_WRAP0(Node, plugin, get_bundle_uri); - LILV_WRAP0(Nodes, plugin, get_data_uris); - LILV_WRAP0(Node, plugin, get_library_uri); - LILV_WRAP0(Node, plugin, get_name); - LILV_WRAP0(PluginClass, plugin, get_class); - LILV_WRAP1(Nodes, plugin, get_value, const Node&, pred); - LILV_WRAP1(bool, plugin, has_feature, const Node&, feature_uri); - LILV_WRAP0(Nodes, plugin, get_supported_features); - LILV_WRAP0(Nodes, plugin, get_required_features); - LILV_WRAP0(Nodes, plugin, get_optional_features); - LILV_WRAP0(unsigned, plugin, get_num_ports); - LILV_WRAP0(bool, plugin, has_latency); - LILV_WRAP0(unsigned, plugin, get_latency_port_index); - LILV_WRAP0(Node, plugin, get_author_name); - LILV_WRAP0(Node, plugin, get_author_email); - LILV_WRAP0(Node, plugin, get_author_homepage); - LILV_WRAP0(bool, plugin, is_replaced); - LILV_WRAP0(Nodes, plugin, get_extension_data); - LILV_WRAP0(UIs, plugin, get_uis); - LILV_WRAP1(Nodes, plugin, get_related, const Node&, type); - - inline Port get_port_by_index(unsigned index) const { - return Port(me, lilv_plugin_get_port_by_index(me, index)); - } - - inline Port get_port_by_symbol(LilvNode* symbol) const { - return Port(me, lilv_plugin_get_port_by_symbol(me, symbol)); - } - - inline void get_port_ranges_float(float* min_values, - float* max_values, - float* def_values) const { - return lilv_plugin_get_port_ranges_float( - me, min_values, max_values, def_values); - } - - inline unsigned get_num_ports_of_class(LilvNode* class_1, ...) const { - va_list args; - va_start(args, class_1); - - const uint32_t count = lilv_plugin_get_num_ports_of_class_va( - me, class_1, args); - - va_end(args); - return count; - } - - const LilvPlugin* me; + inline Plugin(const LilvPlugin* c_obj) + : me(c_obj) + {} + + LILV_WRAP_CONVERSION(const LilvPlugin); + + LILV_WRAP0(bool, plugin, verify); + LILV_WRAP0(Node, plugin, get_uri); + LILV_WRAP0(Node, plugin, get_bundle_uri); + LILV_WRAP0(Nodes, plugin, get_data_uris); + LILV_WRAP0(Node, plugin, get_library_uri); + LILV_WRAP0(Node, plugin, get_name); + LILV_WRAP0(PluginClass, plugin, get_class); + LILV_WRAP1(Nodes, plugin, get_value, const Node&, pred); + LILV_WRAP1(bool, plugin, has_feature, const Node&, feature_uri); + LILV_WRAP0(Nodes, plugin, get_supported_features); + LILV_WRAP0(Nodes, plugin, get_required_features); + LILV_WRAP0(Nodes, plugin, get_optional_features); + LILV_WRAP0(unsigned, plugin, get_num_ports); + LILV_WRAP0(bool, plugin, has_latency); + LILV_WRAP0(unsigned, plugin, get_latency_port_index); + LILV_WRAP0(Node, plugin, get_author_name); + LILV_WRAP0(Node, plugin, get_author_email); + LILV_WRAP0(Node, plugin, get_author_homepage); + LILV_WRAP0(bool, plugin, is_replaced); + LILV_WRAP0(Nodes, plugin, get_extension_data); + LILV_WRAP0(UIs, plugin, get_uis); + LILV_WRAP1(Nodes, plugin, get_related, const Node&, type); + + inline Port get_port_by_index(unsigned index) const + { + return Port(me, lilv_plugin_get_port_by_index(me, index)); + } + + inline Port get_port_by_symbol(LilvNode* symbol) const + { + return Port(me, lilv_plugin_get_port_by_symbol(me, symbol)); + } + + inline void get_port_ranges_float(float* min_values, + float* max_values, + float* def_values) const + { + return lilv_plugin_get_port_ranges_float( + me, min_values, max_values, def_values); + } + + inline unsigned get_num_ports_of_class(LilvNode* class_1, ...) const + { + va_list args; + va_start(args, class_1); + + const uint32_t count = + lilv_plugin_get_num_ports_of_class_va(me, class_1, args); + + va_end(args); + return count; + } + + const LilvPlugin* me; }; struct Plugins { - LILV_WRAP_COLL(Plugins, Plugin, plugins); - LILV_WRAP1(Plugin, plugins, get_by_uri, const LilvNode*, uri); + LILV_WRAP_COLL(Plugins, Plugin, plugins); + LILV_WRAP1(Plugin, plugins, get_by_uri, const LilvNode*, uri); }; struct Instance { - inline Instance(LilvInstance* instance) : me(instance) {} + inline Instance(LilvInstance* instance) + : me(instance) + {} + + LILV_DEPRECATED + inline Instance(Plugin plugin, double sample_rate) + { + me = lilv_plugin_instantiate(plugin, sample_rate, nullptr); + } + + LILV_DEPRECATED inline Instance(Plugin plugin, + double sample_rate, + LV2_Feature* const* features) + { + me = lilv_plugin_instantiate(plugin, sample_rate, features); + } + + static inline Instance* create(Plugin plugin, + double sample_rate, + LV2_Feature* const* features) + { + LilvInstance* me = lilv_plugin_instantiate(plugin, sample_rate, features); + + return me ? new Instance(me) : nullptr; + } + + LILV_WRAP_CONVERSION(LilvInstance); + + LILV_WRAP2_VOID(instance, + connect_port, + unsigned, + port_index, + void*, + data_location); + + LILV_WRAP0_VOID(instance, activate); + LILV_WRAP1_VOID(instance, run, unsigned, sample_count); + LILV_WRAP0_VOID(instance, deactivate); + + inline const void* get_extension_data(const char* uri) const + { + return lilv_instance_get_extension_data(me, uri); + } + + inline const LV2_Descriptor* get_descriptor() const + { + return lilv_instance_get_descriptor(me); + } + + inline LV2_Handle get_handle() const { return lilv_instance_get_handle(me); } + + LilvInstance* me; +}; - LILV_DEPRECATED - inline Instance(Plugin plugin, double sample_rate) { - me = lilv_plugin_instantiate(plugin, sample_rate, nullptr); - } +struct World { + inline World() + : me(lilv_world_new()) + {} - LILV_DEPRECATED inline Instance(Plugin plugin, - double sample_rate, - LV2_Feature* const* features) { - me = lilv_plugin_instantiate(plugin, sample_rate, features); - } + inline ~World() { lilv_world_free(me); } - static inline Instance* create(Plugin plugin, - double sample_rate, - LV2_Feature* const* features) { - LilvInstance* me = lilv_plugin_instantiate( - plugin, sample_rate, features); + World(const World&) = delete; + World& operator=(const World&) = delete; - return me ? new Instance(me) : nullptr; - } + World(World&&) = delete; + World& operator=(World&&) = delete; - LILV_WRAP_CONVERSION(LilvInstance); + inline LilvNode* new_uri(const char* uri) const + { + return lilv_new_uri(me, uri); + } - LILV_WRAP2_VOID(instance, connect_port, - unsigned, port_index, - void*, data_location); + inline LilvNode* new_string(const char* str) const + { + return lilv_new_string(me, str); + } - LILV_WRAP0_VOID(instance, activate); - LILV_WRAP1_VOID(instance, run, unsigned, sample_count); - LILV_WRAP0_VOID(instance, deactivate); + inline LilvNode* new_int(int val) const { return lilv_new_int(me, val); } - inline const void* get_extension_data(const char* uri) const { - return lilv_instance_get_extension_data(me, uri); - } + inline LilvNode* new_float(float val) const + { + return lilv_new_float(me, val); + } - inline const LV2_Descriptor* get_descriptor() const { - return lilv_instance_get_descriptor(me); - } + inline LilvNode* new_bool(bool val) const { return lilv_new_bool(me, val); } - inline LV2_Handle get_handle() const { - return lilv_instance_get_handle(me); - } + inline Nodes find_nodes(const LilvNode* subject, + const LilvNode* predicate, + const LilvNode* object) const + { + return lilv_world_find_nodes(me, subject, predicate, object); + } - LilvInstance* me; -}; + LILV_WRAP2_VOID(world, set_option, const char*, uri, LilvNode*, value); + LILV_WRAP0_VOID(world, load_all); + LILV_WRAP1_VOID(world, load_bundle, LilvNode*, bundle_uri); + LILV_WRAP0(const LilvPluginClass*, world, get_plugin_class); + LILV_WRAP0(const LilvPluginClasses*, world, get_plugin_classes); + LILV_WRAP0(Plugins, world, get_all_plugins); + LILV_WRAP1(int, world, load_resource, const LilvNode*, resource); -struct World { - inline World() : me(lilv_world_new()) {} - inline ~World() { lilv_world_free(me); } - - World(const World&) = delete; - World& operator=(const World&) = delete; - - World(World&&) = delete; - World& operator=(World&&) = delete; - - inline LilvNode* new_uri(const char* uri) const { - return lilv_new_uri(me, uri); - } - inline LilvNode* new_string(const char* str) const { - return lilv_new_string(me, str); - } - inline LilvNode* new_int(int val) const { - return lilv_new_int(me, val); - } - inline LilvNode* new_float(float val) const { - return lilv_new_float(me, val); - } - inline LilvNode* new_bool(bool val) const { - return lilv_new_bool(me, val); - } - inline Nodes find_nodes(const LilvNode* subject, - const LilvNode* predicate, - const LilvNode* object) const { - return lilv_world_find_nodes(me, subject, predicate, object); - } - - LILV_WRAP2_VOID(world, set_option, const char*, uri, LilvNode*, value); - LILV_WRAP0_VOID(world, load_all); - LILV_WRAP1_VOID(world, load_bundle, LilvNode*, bundle_uri); - LILV_WRAP0(const LilvPluginClass*, world, get_plugin_class); - LILV_WRAP0(const LilvPluginClasses*, world, get_plugin_classes); - LILV_WRAP0(Plugins, world, get_all_plugins); - LILV_WRAP1(int, world, load_resource, const LilvNode*, resource); - - LilvWorld* me; + LilvWorld* me; }; } /* namespace Lilv */ diff --git a/src/collections.c b/src/collections.c index 8a25eaa..6cfb986 100644 --- a/src/collections.c +++ b/src/collections.c @@ -28,15 +28,15 @@ int lilv_ptr_cmp(const void* a, const void* b, void* user_data) { - return (intptr_t)a - (intptr_t)b; + return (intptr_t)a - (intptr_t)b; } int lilv_resource_node_cmp(const void* a, const void* b, void* user_data) { - const SordNode* an = ((const LilvNode*)a)->node; - const SordNode* bn = ((const LilvNode*)b)->node; - return (intptr_t)an - (intptr_t)bn; + const SordNode* an = ((const LilvNode*)a)->node; + const SordNode* bn = ((const LilvNode*)b)->node; + return (intptr_t)an - (intptr_t)bn; } /* Generic collection functions */ @@ -44,34 +44,33 @@ lilv_resource_node_cmp(const void* a, const void* b, void* user_data) static inline LilvCollection* lilv_collection_new(ZixComparator cmp, ZixDestroyFunc destructor) { - return zix_tree_new(false, cmp, NULL, destructor); + return zix_tree_new(false, cmp, NULL, destructor); } void lilv_collection_free(LilvCollection* collection) { - if (collection) { - zix_tree_free((ZixTree*)collection); - } + if (collection) { + zix_tree_free((ZixTree*)collection); + } } unsigned lilv_collection_size(const LilvCollection* collection) { - return (collection ? zix_tree_size((const ZixTree*)collection) : 0); + return (collection ? zix_tree_size((const ZixTree*)collection) : 0); } LilvIter* lilv_collection_begin(const LilvCollection* collection) { - return collection ? (LilvIter*)zix_tree_begin((ZixTree*)collection) : NULL; + return collection ? (LilvIter*)zix_tree_begin((ZixTree*)collection) : NULL; } void* -lilv_collection_get(const LilvCollection* collection, - const LilvIter* i) +lilv_collection_get(const LilvCollection* collection, const LilvIter* i) { - return zix_tree_get((const ZixTreeIter*)i); + return zix_tree_get((const ZixTreeIter*)i); } /* Constructors */ @@ -79,29 +78,28 @@ lilv_collection_get(const LilvCollection* collection, LilvScalePoints* lilv_scale_points_new(void) { - return lilv_collection_new(lilv_ptr_cmp, - (ZixDestroyFunc)lilv_scale_point_free); + return lilv_collection_new(lilv_ptr_cmp, + (ZixDestroyFunc)lilv_scale_point_free); } LilvNodes* lilv_nodes_new(void) { - return lilv_collection_new(lilv_ptr_cmp, - (ZixDestroyFunc)lilv_node_free); + return lilv_collection_new(lilv_ptr_cmp, (ZixDestroyFunc)lilv_node_free); } LilvUIs* lilv_uis_new(void) { - return lilv_collection_new(lilv_header_compare_by_uri, - (ZixDestroyFunc)lilv_ui_free); + return lilv_collection_new(lilv_header_compare_by_uri, + (ZixDestroyFunc)lilv_ui_free); } LilvPluginClasses* lilv_plugin_classes_new(void) { - return lilv_collection_new(lilv_header_compare_by_uri, - (ZixDestroyFunc)lilv_plugin_class_free); + return lilv_collection_new(lilv_header_compare_by_uri, + (ZixDestroyFunc)lilv_plugin_class_free); } /* URI based accessors (for collections of things with URIs) */ @@ -110,14 +108,14 @@ const LilvPluginClass* lilv_plugin_classes_get_by_uri(const LilvPluginClasses* classes, const LilvNode* uri) { - return (LilvPluginClass*)lilv_collection_get_by_uri( - (const ZixTree*)classes, uri); + return (LilvPluginClass*)lilv_collection_get_by_uri((const ZixTree*)classes, + uri); } const LilvUI* lilv_uis_get_by_uri(const LilvUIs* uis, const LilvNode* uri) { - return (LilvUI*)lilv_collection_get_by_uri((const ZixTree*)uis, uri); + return (LilvUI*)lilv_collection_get_by_uri((const ZixTree*)uis, uri); } /* Plugins */ @@ -125,14 +123,13 @@ lilv_uis_get_by_uri(const LilvUIs* uis, const LilvNode* uri) LilvPlugins* lilv_plugins_new(void) { - return lilv_collection_new(lilv_header_compare_by_uri, NULL); + return lilv_collection_new(lilv_header_compare_by_uri, NULL); } const LilvPlugin* lilv_plugins_get_by_uri(const LilvPlugins* plugins, const LilvNode* uri) { - return (LilvPlugin*)lilv_collection_get_by_uri( - (const ZixTree*)plugins, uri); + return (LilvPlugin*)lilv_collection_get_by_uri((const ZixTree*)plugins, uri); } /* Nodes */ @@ -140,65 +137,61 @@ lilv_plugins_get_by_uri(const LilvPlugins* plugins, const LilvNode* uri) bool lilv_nodes_contains(const LilvNodes* nodes, const LilvNode* value) { - LILV_FOREACH(nodes, i, nodes) { - if (lilv_node_equals(lilv_nodes_get(nodes, i), value)) { - return true; - } - } + LILV_FOREACH (nodes, i, nodes) { + if (lilv_node_equals(lilv_nodes_get(nodes, i), value)) { + return true; + } + } - return false; + return false; } LilvNodes* lilv_nodes_merge(const LilvNodes* a, const LilvNodes* b) { - LilvNodes* result = lilv_nodes_new(); + LilvNodes* result = lilv_nodes_new(); - LILV_FOREACH(nodes, i, a) - zix_tree_insert((ZixTree*)result, - lilv_node_duplicate(lilv_nodes_get(a, i)), - NULL); + LILV_FOREACH (nodes, i, a) { + zix_tree_insert( + (ZixTree*)result, lilv_node_duplicate(lilv_nodes_get(a, i)), NULL); + } - LILV_FOREACH(nodes, i, b) - zix_tree_insert((ZixTree*)result, - lilv_node_duplicate(lilv_nodes_get(b, i)), - NULL); + LILV_FOREACH (nodes, i, b) { + zix_tree_insert( + (ZixTree*)result, lilv_node_duplicate(lilv_nodes_get(b, i)), NULL); + } - return result; + return result; } /* Iterator */ -#define LILV_COLLECTION_IMPL(prefix, CT, ET) \ -\ -unsigned \ -prefix##_size(const CT* collection) { \ - return lilv_collection_size(collection); \ -} \ -\ -\ -LilvIter* \ -prefix##_begin(const CT* collection) { \ - return lilv_collection_begin(collection); \ -} \ -\ -\ -const ET* \ -prefix##_get(const CT* collection, LilvIter* i) { \ - return (ET*)lilv_collection_get(collection, i); \ -} \ -\ -\ -LilvIter* \ -prefix##_next(const CT* collection, LilvIter* i) { \ - return zix_tree_iter_next((ZixTreeIter*)i); \ -} \ -\ -\ -bool \ -prefix##_is_end(const CT* collection, LilvIter* i) { \ - return zix_tree_iter_is_end((ZixTreeIter*)i); \ -} +#define LILV_COLLECTION_IMPL(prefix, CT, ET) \ + \ + unsigned prefix##_size(const CT* collection) \ + { \ + return lilv_collection_size(collection); \ + } \ + \ + LilvIter* prefix##_begin(const CT* collection) \ + { \ + return lilv_collection_begin(collection); \ + } \ + \ + const ET* prefix##_get(const CT* collection, LilvIter* i) \ + { \ + return (ET*)lilv_collection_get(collection, i); \ + } \ + \ + LilvIter* prefix##_next(const CT* collection, LilvIter* i) \ + { \ + return zix_tree_iter_next((ZixTreeIter*)i); \ + } \ + \ + bool prefix##_is_end(const CT* collection, LilvIter* i) \ + { \ + return zix_tree_iter_is_end((ZixTreeIter*)i); \ + } LILV_COLLECTION_IMPL(lilv_plugin_classes, LilvPluginClasses, LilvPluginClass) LILV_COLLECTION_IMPL(lilv_scale_points, LilvScalePoints, LilvScalePoint) @@ -207,27 +200,32 @@ LILV_COLLECTION_IMPL(lilv_nodes, LilvNodes, LilvNode) LILV_COLLECTION_IMPL(lilv_plugins, LilvPlugins, LilvPlugin) void -lilv_plugin_classes_free(LilvPluginClasses* collection) { - lilv_collection_free(collection); +lilv_plugin_classes_free(LilvPluginClasses* collection) +{ + lilv_collection_free(collection); } void -lilv_scale_points_free(LilvScalePoints* collection) { - lilv_collection_free(collection); +lilv_scale_points_free(LilvScalePoints* collection) +{ + lilv_collection_free(collection); } void -lilv_uis_free(LilvUIs* collection) { - lilv_collection_free(collection); +lilv_uis_free(LilvUIs* collection) +{ + lilv_collection_free(collection); } void -lilv_nodes_free(LilvNodes* collection) { - lilv_collection_free(collection); +lilv_nodes_free(LilvNodes* collection) +{ + lilv_collection_free(collection); } LilvNode* -lilv_nodes_get_first(const LilvNodes* collection) { - return (LilvNode*)lilv_collection_get(collection, - lilv_collection_begin(collection)); +lilv_nodes_get_first(const LilvNodes* collection) +{ + return (LilvNode*)lilv_collection_get(collection, + lilv_collection_begin(collection)); } diff --git a/src/filesystem.c b/src/filesystem.c index dadd977..0d6989b 100644 --- a/src/filesystem.c +++ b/src/filesystem.c @@ -14,12 +14,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define _POSIX_C_SOURCE 200809L /* for fileno */ -#define _BSD_SOURCE 1 /* for realpath, symlink */ -#define _DEFAULT_SOURCE 1 /* for realpath, symlink */ +#define _POSIX_C_SOURCE 200809L /* for fileno */ +#define _BSD_SOURCE 1 /* for realpath, symlink */ +#define _DEFAULT_SOURCE 1 /* for realpath, symlink */ #ifdef __APPLE__ -# define _DARWIN_C_SOURCE 1 /* for flock */ +# define _DARWIN_C_SOURCE 1 /* for flock */ #endif #include "filesystem.h" @@ -27,19 +27,19 @@ #include "lilv_internal.h" #ifdef _WIN32 -# include <windows.h> -# include <direct.h> -# include <io.h> -# define F_OK 0 -# define mkdir(path, flags) _mkdir(path) -# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +# include <direct.h> +# include <io.h> +# include <windows.h> +# define F_OK 0 +# define mkdir(path, flags) _mkdir(path) +# define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) #else -# include <dirent.h> -# include <unistd.h> +# include <dirent.h> +# include <unistd.h> #endif #if defined(HAVE_FLOCK) && defined(HAVE_FILENO) -# include <sys/file.h> +# include <sys/file.h> #endif #include <sys/stat.h> @@ -51,21 +51,21 @@ #include <string.h> #ifndef PAGE_SIZE -# define PAGE_SIZE 4096 +# define PAGE_SIZE 4096 #endif static bool lilv_is_dir_sep(const char c) { - return c == '/' || c == LILV_DIR_SEP[0]; + return c == '/' || c == LILV_DIR_SEP[0]; } #ifdef _WIN32 static inline bool is_windows_path(const char* path) { - return (isalpha(path[0]) && (path[1] == ':' || path[1] == '|') && - (path[2] == '/' || path[2] == '\\')); + return (isalpha(path[0]) && (path[1] == ':' || path[1] == '|') && + (path[2] == '/' || path[2] == '\\')); } #endif @@ -73,217 +73,226 @@ char* lilv_temp_directory_path(void) { #ifdef _WIN32 - DWORD len = GetTempPath(0, NULL); - char* buf = (char*)calloc(len, 1); - if (GetTempPath(len, buf) == 0) { - free(buf); - return NULL; - } - - return buf; + DWORD len = GetTempPath(0, NULL); + char* buf = (char*)calloc(len, 1); + if (GetTempPath(len, buf) == 0) { + free(buf); + return NULL; + } + + return buf; #else - const char* const tmpdir = getenv("TMPDIR"); + const char* const tmpdir = getenv("TMPDIR"); - return tmpdir ? lilv_strdup(tmpdir) : lilv_strdup("/tmp"); + return tmpdir ? lilv_strdup(tmpdir) : lilv_strdup("/tmp"); #endif } bool lilv_path_is_absolute(const char* path) { - if (lilv_is_dir_sep(path[0])) { - return true; - } + if (lilv_is_dir_sep(path[0])) { + return true; + } #ifdef _WIN32 - if (is_windows_path(path)) { - return true; - } + if (is_windows_path(path)) { + return true; + } #endif - return false; + return false; } bool lilv_path_is_child(const char* path, const char* dir) { - if (path && dir) { - const size_t path_len = strlen(path); - const size_t dir_len = strlen(dir); - return dir && path_len >= dir_len && !strncmp(path, dir, dir_len); - } - return false; + if (path && dir) { + const size_t path_len = strlen(path); + const size_t dir_len = strlen(dir); + return dir && path_len >= dir_len && !strncmp(path, dir, dir_len); + } + return false; } char* lilv_path_current(void) { - return getcwd(NULL, 0); + return getcwd(NULL, 0); } 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 = lilv_path_join(cwd, path); - free(cwd); - return abs_path; + if (lilv_path_is_absolute(path)) { + return lilv_strdup(path); + } + + char* cwd = getcwd(NULL, 0); + char* abs_path = lilv_path_join(cwd, path); + free(cwd); + return abs_path; } char* lilv_path_absolute_child(const char* path, const char* parent) { - if (lilv_path_is_absolute(path)) { - return lilv_strdup(path); - } + if (lilv_path_is_absolute(path)) { + return lilv_strdup(path); + } - return lilv_path_join(parent, path); + return lilv_path_join(parent, path); } char* lilv_path_relative_to(const char* path, const char* base) { - const size_t path_len = strlen(path); - const size_t base_len = strlen(base); - const size_t min_len = (path_len < base_len) ? path_len : base_len; - - // Find the last separator common to both paths - size_t last_shared_sep = 0; - for (size_t i = 0; i < min_len && path[i] == base[i]; ++i) { - if (lilv_is_dir_sep(path[i])) { - last_shared_sep = i; - } - } - - if (last_shared_sep == 0) { - // No common components, return path - return lilv_strdup(path); - } - - // Find the number of up references ("..") required - size_t up = 0; - for (size_t i = last_shared_sep + 1; i < base_len; ++i) { - if (lilv_is_dir_sep(base[i])) { - ++up; - } - } + const size_t path_len = strlen(path); + const size_t base_len = strlen(base); + const size_t min_len = (path_len < base_len) ? path_len : base_len; + + // Find the last separator common to both paths + size_t last_shared_sep = 0; + for (size_t i = 0; i < min_len && path[i] == base[i]; ++i) { + if (lilv_is_dir_sep(path[i])) { + last_shared_sep = i; + } + } + + if (last_shared_sep == 0) { + // No common components, return path + return lilv_strdup(path); + } + + // Find the number of up references ("..") required + size_t up = 0; + for (size_t i = last_shared_sep + 1; i < base_len; ++i) { + if (lilv_is_dir_sep(base[i])) { + ++up; + } + } #ifdef _WIN32 - const bool use_slash = strchr(path, '/'); + const bool use_slash = strchr(path, '/'); #else - static const bool use_slash = true; + static const bool use_slash = true; #endif - // Write up references - const size_t suffix_len = path_len - last_shared_sep; - char* rel = (char*)calloc(1, suffix_len + (up * 3) + 1); - for (size_t i = 0; i < up; ++i) { - if (use_slash) { - memcpy(rel + (i * 3), "../", 3); - } else { - memcpy(rel + (i * 3), "..\\", 3); - } - } - - // Write suffix - memcpy(rel + (up * 3), path + last_shared_sep + 1, suffix_len); - return rel; + // Write up references + const size_t suffix_len = path_len - last_shared_sep; + char* rel = (char*)calloc(1, suffix_len + (up * 3) + 1); + for (size_t i = 0; i < up; ++i) { + if (use_slash) { + memcpy(rel + (i * 3), "../", 3); + } else { + memcpy(rel + (i * 3), "..\\", 3); + } + } + + // Write suffix + memcpy(rel + (up * 3), path + last_shared_sep + 1, suffix_len); + return rel; } char* lilv_path_parent(const char* path) { - const char* s = path + strlen(path) - 1; // Last character - for (; s > path && lilv_is_dir_sep(*s); --s) {} // Last non-slash - for (; s > path && !lilv_is_dir_sep(*s); --s) {} // Last internal slash - for (; s > path && lilv_is_dir_sep(*s); --s) {} // Skip duplicates - - if (s == path) { // Hit beginning - return lilv_is_dir_sep(*s) ? lilv_strdup("/") : lilv_strdup("."); - } - - // Pointing to the last character of the result (inclusive) - char* dirname = (char*)malloc(s - path + 2); - memcpy(dirname, path, s - path + 1); - dirname[s - path + 1] = '\0'; - return dirname; + const char* s = path + strlen(path) - 1; // Last character + + // Last non-slash + for (; s > path && lilv_is_dir_sep(*s); --s) { + } + + // Last internal slash + for (; s > path && !lilv_is_dir_sep(*s); --s) { + } + + // Skip duplicates + for (; s > path && lilv_is_dir_sep(*s); --s) { + } + + if (s == path) { // Hit beginning + return lilv_is_dir_sep(*s) ? lilv_strdup("/") : lilv_strdup("."); + } + + // Pointing to the last character of the result (inclusive) + char* dirname = (char*)malloc(s - path + 2); + memcpy(dirname, path, s - path + 1); + dirname[s - path + 1] = '\0'; + return dirname; } char* lilv_path_filename(const char* path) { - const size_t path_len = strlen(path); - size_t last_sep = path_len; - for (size_t i = 0; i < path_len; ++i) { - if (lilv_is_dir_sep(path[i])) { - last_sep = i; - } - } - - if (last_sep >= path_len) { - return lilv_strdup(path); - } - - const size_t ret_len = path_len - last_sep; - char* const ret = (char*)calloc(ret_len + 1, 1); - - strncpy(ret, path + last_sep + 1, ret_len); - return ret; + const size_t path_len = strlen(path); + size_t last_sep = path_len; + for (size_t i = 0; i < path_len; ++i) { + if (lilv_is_dir_sep(path[i])) { + last_sep = i; + } + } + + if (last_sep >= path_len) { + return lilv_strdup(path); + } + + const size_t ret_len = path_len - last_sep; + char* const ret = (char*)calloc(ret_len + 1, 1); + + strncpy(ret, path + last_sep + 1, ret_len); + return ret; } char* lilv_path_join(const char* a, const char* b) { - if (!a) { - return (b && b[0]) ? lilv_strdup(b) : NULL; - } + if (!a) { + return (b && b[0]) ? lilv_strdup(b) : NULL; + } - const size_t a_len = strlen(a); - const size_t b_len = b ? strlen(b) : 0; - const bool a_end_is_sep = a_len > 0 && lilv_is_dir_sep(a[a_len - 1]); - const size_t pre_len = a_len - (a_end_is_sep ? 1 : 0); - char* path = (char*)calloc(1, a_len + b_len + 2); - memcpy(path, a, pre_len); + const size_t a_len = strlen(a); + const size_t b_len = b ? strlen(b) : 0; + const bool a_end_is_sep = a_len > 0 && lilv_is_dir_sep(a[a_len - 1]); + const size_t pre_len = a_len - (a_end_is_sep ? 1 : 0); + char* path = (char*)calloc(1, a_len + b_len + 2); + memcpy(path, a, pre_len); #ifdef _WIN32 - // Use forward slash if it seems that the input paths do - const bool a_has_slash = strchr(a, '/'); - const bool b_has_slash = b && strchr(b, '/'); - if (a_has_slash || b_has_slash) { - path[pre_len] = '/'; - } else { - path[pre_len] = '\\'; - } + // Use forward slash if it seems that the input paths do + const bool a_has_slash = strchr(a, '/'); + const bool b_has_slash = b && strchr(b, '/'); + if (a_has_slash || b_has_slash) { + path[pre_len] = '/'; + } else { + path[pre_len] = '\\'; + } #else - path[pre_len] = '/'; + path[pre_len] = '/'; #endif - if (b) { - memcpy(path + pre_len + 1, - b + (lilv_is_dir_sep(b[0]) ? 1 : 0), - lilv_is_dir_sep(b[0]) ? b_len - 1 : b_len); - } - return path; + if (b) { + memcpy(path + pre_len + 1, + b + (lilv_is_dir_sep(b[0]) ? 1 : 0), + lilv_is_dir_sep(b[0]) ? b_len - 1 : b_len); + } + return path; } char* lilv_path_canonical(const char* path) { - if (!path) { - return NULL; - } + if (!path) { + return NULL; + } #if defined(_WIN32) - char* out = (char*)malloc(MAX_PATH); - GetFullPathName(path, MAX_PATH, out, NULL); - return out; + 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); + char* real_path = realpath(path, NULL); + return real_path ? real_path : lilv_strdup(path); #endif } @@ -291,98 +300,97 @@ bool lilv_path_exists(const char* path) { #ifdef HAVE_LSTAT - struct stat st; - return !lstat(path, &st); + struct stat st; + return !lstat(path, &st); #else - return !access(path, F_OK); + return !access(path, F_OK); #endif } bool lilv_is_directory(const char* path) { - struct stat st; - return !stat(path, &st) && S_ISDIR(st.st_mode); + struct stat st; + return !stat(path, &st) && S_ISDIR(st.st_mode); } int lilv_copy_file(const char* src, const char* dst) { - FILE* in = fopen(src, "r"); - if (!in) { - return errno; - } - - FILE* out = fopen(dst, "w"); - if (!out) { - fclose(in); - return errno; - } - - char* page = (char*)malloc(PAGE_SIZE); - size_t n_read = 0; - int st = 0; - while ((n_read = fread(page, 1, PAGE_SIZE, in)) > 0) { - if (fwrite(page, 1, n_read, out) != n_read) { - st = errno; - break; - } - } - - if (!st && fflush(out)) { - st = errno; - } - - if (!st && (ferror(in) || ferror(out))) { - st = EBADF; - } - - free(page); - fclose(in); - fclose(out); - - return st; + FILE* in = fopen(src, "r"); + if (!in) { + return errno; + } + + FILE* out = fopen(dst, "w"); + if (!out) { + fclose(in); + return errno; + } + + char* page = (char*)malloc(PAGE_SIZE); + size_t n_read = 0; + int st = 0; + while ((n_read = fread(page, 1, PAGE_SIZE, in)) > 0) { + if (fwrite(page, 1, n_read, out) != n_read) { + st = errno; + break; + } + } + + if (!st && fflush(out)) { + st = errno; + } + + if (!st && (ferror(in) || ferror(out))) { + st = EBADF; + } + + free(page); + fclose(in); + fclose(out); + + return st; } int lilv_symlink(const char* oldpath, const char* newpath) { - int ret = 0; - if (strcmp(oldpath, newpath)) { + int ret = 0; + if (strcmp(oldpath, newpath)) { #ifdef _WIN32 - ret = !CreateHardLink(newpath, oldpath, 0); + ret = !CreateHardLink(newpath, oldpath, 0); #else - char* target = lilv_path_relative_to(oldpath, newpath); + char* target = lilv_path_relative_to(oldpath, newpath); - ret = symlink(target, newpath); + ret = symlink(target, newpath); - free(target); + free(target); #endif - } - return ret; + } + return ret; } int lilv_flock(FILE* file, bool lock, bool block) { #ifdef _WIN32 - HANDLE handle = (HANDLE)_get_osfhandle(fileno(file)); - OVERLAPPED overlapped = {0}; - - if (lock) { - const DWORD flags = (LOCKFILE_EXCLUSIVE_LOCK | - (block ? 0 : LOCKFILE_FAIL_IMMEDIATELY)); - - return !LockFileEx( - handle, flags, 0, UINT32_MAX, UINT32_MAX, &overlapped); - } else { - return !UnlockFileEx(handle, 0, UINT32_MAX, UINT32_MAX, &overlapped); - } + HANDLE handle = (HANDLE)_get_osfhandle(fileno(file)); + OVERLAPPED overlapped = {0}; + + if (lock) { + const DWORD flags = + (LOCKFILE_EXCLUSIVE_LOCK | (block ? 0 : LOCKFILE_FAIL_IMMEDIATELY)); + + return !LockFileEx(handle, flags, 0, UINT32_MAX, UINT32_MAX, &overlapped); + } else { + return !UnlockFileEx(handle, 0, UINT32_MAX, UINT32_MAX, &overlapped); + } #elif defined(HAVE_FLOCK) && defined(HAVE_FILENO) - return flock(fileno(file), - (lock ? LOCK_EX : LOCK_UN) | (block ? 0 : LOCK_NB)); + return flock(fileno(file), + (lock ? LOCK_EX : LOCK_UN) | (block ? 0 : LOCK_NB)); #else - return 0; + return 0; #endif } @@ -392,28 +400,28 @@ lilv_dir_for_each(const char* path, void (*f)(const char* path, const char* name, void* data)) { #ifdef _WIN32 - char* pat = lilv_path_join(path, "*"); - WIN32_FIND_DATA fd; - HANDLE fh = FindFirstFile(pat, &fd); - if (fh != INVALID_HANDLE_VALUE) { - do { - if (strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..")) { - f(path, fd.cFileName, data); - } - } while (FindNextFile(fh, &fd)); - } - FindClose(fh); - free(pat); + char* pat = lilv_path_join(path, "*"); + WIN32_FIND_DATA fd; + HANDLE fh = FindFirstFile(pat, &fd); + if (fh != INVALID_HANDLE_VALUE) { + do { + if (strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..")) { + f(path, fd.cFileName, data); + } + } while (FindNextFile(fh, &fd)); + } + FindClose(fh); + free(pat); #else - DIR* dir = opendir(path); - if (dir) { - for (struct dirent* entry = NULL; (entry = readdir(dir));) { - if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) { - f(path, entry->d_name, data); - } - } - closedir(dir); - } + DIR* dir = opendir(path); + if (dir) { + for (struct dirent* entry = NULL; (entry = readdir(dir));) { + if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) { + f(path, entry->d_name, data); + } + } + closedir(dir); + } #endif } @@ -421,131 +429,130 @@ char* lilv_create_temporary_directory(const char* pattern) { #ifdef _WIN32 - static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - static const int n_chars = sizeof(chars) - 1; + static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + static const int n_chars = sizeof(chars) - 1; - const size_t pattern_len = strlen(pattern); - if (pattern_len < 7 || strcmp(pattern + pattern_len - 6, "XXXXXX")) { - errno = EINVAL; - return NULL; - } + const size_t pattern_len = strlen(pattern); + if (pattern_len < 7 || strcmp(pattern + pattern_len - 6, "XXXXXX")) { + errno = EINVAL; + return NULL; + } - char* const tmpdir = lilv_temp_directory_path(); - char* const path_pattern = lilv_path_join(tmpdir, pattern); - const size_t path_pattern_len = strlen(path_pattern); - char* const suffix = path_pattern + path_pattern_len - 6; + char* const tmpdir = lilv_temp_directory_path(); + char* const path_pattern = lilv_path_join(tmpdir, pattern); + const size_t path_pattern_len = strlen(path_pattern); + char* const suffix = path_pattern + path_pattern_len - 6; - free(tmpdir); + free(tmpdir); - for (unsigned attempt = 0; attempt < 128; ++attempt) { - for (unsigned i = 0; i < 6; ++i) { - suffix[i] = chars[rand() % n_chars]; - } + for (unsigned attempt = 0; attempt < 128; ++attempt) { + for (unsigned i = 0; i < 6; ++i) { + suffix[i] = chars[rand() % n_chars]; + } - if (!mkdir(path_pattern, 0700)) { - return path_pattern; - } - } + if (!mkdir(path_pattern, 0700)) { + return path_pattern; + } + } - return NULL; + return NULL; #else - char* const tmpdir = lilv_temp_directory_path(); - char* const path_pattern = lilv_path_join(tmpdir, pattern); + char* const tmpdir = lilv_temp_directory_path(); + char* const path_pattern = lilv_path_join(tmpdir, pattern); - free(tmpdir); - return mkdtemp(path_pattern); // NOLINT (not a leak) + free(tmpdir); + return mkdtemp(path_pattern); // NOLINT (not a leak) #endif } int lilv_create_directories(const char* dir_path) { - char* path = lilv_strdup(dir_path); - const size_t path_len = strlen(path); - size_t i = 1; + char* path = lilv_strdup(dir_path); + const size_t path_len = strlen(path); + size_t i = 1; #ifdef _WIN32 - if (is_windows_path(dir_path)) { - i = 3; - } + if (is_windows_path(dir_path)) { + i = 3; + } #endif - for (; i <= path_len; ++i) { - const char c = path[i]; - if (c == LILV_DIR_SEP[0] || c == '/' || c == '\0') { - path[i] = '\0'; - if (mkdir(path, 0755) && - (errno != EEXIST || !lilv_is_directory(path))) { - free(path); - return errno; - } - path[i] = c; - } - } - - free(path); - return 0; + for (; i <= path_len; ++i) { + const char c = path[i]; + if (c == LILV_DIR_SEP[0] || c == '/' || c == '\0') { + path[i] = '\0'; + if (mkdir(path, 0755) && (errno != EEXIST || !lilv_is_directory(path))) { + free(path); + return errno; + } + path[i] = c; + } + } + + free(path); + return 0; } static off_t lilv_file_size(const char* path) { - struct stat buf; - if (stat(path, &buf)) { - return 0; - } - return buf.st_size; + struct stat buf; + if (stat(path, &buf)) { + return 0; + } + return buf.st_size; } int lilv_remove(const char* path) { #ifdef _WIN32 - if (lilv_is_directory(path)) { - return !RemoveDirectory(path); - } + if (lilv_is_directory(path)) { + return !RemoveDirectory(path); + } #endif - return remove(path); + return remove(path); } bool lilv_file_equals(const char* a_path, const char* b_path) { - if (!strcmp(a_path, b_path)) { - return true; // Paths match - } - - 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)) { - match = true; // Real paths match - } else if (lilv_file_size(a_path) != lilv_file_size(b_path)) { - match = false; // Sizes differ - } else if (!(a_file = fopen(a_real, "rb")) || - !(b_file = fopen(b_real, "rb"))) { - match = false; // Missing file matches nothing - } else { - // TODO: Improve performance by reading chunks - match = true; - while (!feof(a_file) && !feof(b_file)) { - if (fgetc(a_file) != fgetc(b_file)) { - match = false; - break; - } - } - } - - if (a_file) { - fclose(a_file); - } - if (b_file) { - fclose(b_file); - } - free(a_real); - free(b_real); - return match; + if (!strcmp(a_path, b_path)) { + return true; // Paths match + } + + 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)) { + match = true; // Real paths match + } else if (lilv_file_size(a_path) != lilv_file_size(b_path)) { + match = false; // Sizes differ + } else if (!(a_file = fopen(a_real, "rb")) || + !(b_file = fopen(b_real, "rb"))) { + match = false; // Missing file matches nothing + } else { + // TODO: Improve performance by reading chunks + match = true; + while (!feof(a_file) && !feof(b_file)) { + if (fgetc(a_file) != fgetc(b_file)) { + match = false; + break; + } + } + } + + if (a_file) { + fclose(a_file); + } + if (b_file) { + fclose(b_file); + } + free(a_real); + free(b_real); + return match; } diff --git a/src/instance.c b/src/instance.c index 42c13a2..8f5f7fc 100644 --- a/src/instance.c +++ b/src/instance.c @@ -27,90 +27,89 @@ #include <string.h> LilvInstance* -lilv_plugin_instantiate(const LilvPlugin* plugin, - double sample_rate, - const LV2_Feature*const* features) +lilv_plugin_instantiate(const LilvPlugin* plugin, + double sample_rate, + const LV2_Feature* const* features) { - lilv_plugin_load_if_necessary(plugin); - if (plugin->parse_errors) { - return NULL; - } - - LilvInstance* result = NULL; - const LilvNode* const lib_uri = lilv_plugin_get_library_uri(plugin); - const LilvNode* const bundle_uri = lilv_plugin_get_bundle_uri(plugin); - if (!lib_uri || !bundle_uri) { - return NULL; - } - - char* const bundle_path = lilv_file_uri_parse( - lilv_node_as_uri(bundle_uri), NULL); - - LilvLib* lib = lilv_lib_open(plugin->world, lib_uri, bundle_path, features); - if (!lib) { - serd_free(bundle_path); - return NULL; - } - - const LV2_Feature** local_features = NULL; - if (features == NULL) { - local_features = (const LV2_Feature**)malloc(sizeof(LV2_Feature*)); - local_features[0] = NULL; - } - - // Search for plugin by URI - for (uint32_t i = 0; true; ++i) { - const LV2_Descriptor* ld = lilv_lib_get_plugin(lib, i); - if (!ld) { - LILV_ERRORF("No plugin <%s> in <%s>\n", - lilv_node_as_uri(lilv_plugin_get_uri(plugin)), - lilv_node_as_uri(lib_uri)); - lilv_lib_close(lib); - break; // return NULL - } - - if (!strcmp(ld->URI, lilv_node_as_uri(lilv_plugin_get_uri(plugin)))) { - // Create LilvInstance to return - result = (LilvInstance*)malloc(sizeof(LilvInstance)); - result->lv2_descriptor = ld; - result->lv2_handle = ld->instantiate( - ld, sample_rate, bundle_path, - (features) ? features : local_features); - result->pimpl = lib; - break; - } - } - - free(local_features); - serd_free(bundle_path); - - if (result) { - if (result->lv2_handle == NULL) { - // Failed to instantiate - free(result); - lilv_lib_close(lib); - return NULL; - } - - // "Connect" all ports to NULL (catches bugs) - for (uint32_t i = 0; i < lilv_plugin_get_num_ports(plugin); ++i) { - result->lv2_descriptor->connect_port(result->lv2_handle, i, NULL); - } - } - - return result; + lilv_plugin_load_if_necessary(plugin); + if (plugin->parse_errors) { + return NULL; + } + + LilvInstance* result = NULL; + const LilvNode* const lib_uri = lilv_plugin_get_library_uri(plugin); + const LilvNode* const bundle_uri = lilv_plugin_get_bundle_uri(plugin); + if (!lib_uri || !bundle_uri) { + return NULL; + } + + char* const bundle_path = + lilv_file_uri_parse(lilv_node_as_uri(bundle_uri), NULL); + + LilvLib* lib = lilv_lib_open(plugin->world, lib_uri, bundle_path, features); + if (!lib) { + serd_free(bundle_path); + return NULL; + } + + const LV2_Feature** local_features = NULL; + if (features == NULL) { + local_features = (const LV2_Feature**)malloc(sizeof(LV2_Feature*)); + local_features[0] = NULL; + } + + // Search for plugin by URI + for (uint32_t i = 0; true; ++i) { + const LV2_Descriptor* ld = lilv_lib_get_plugin(lib, i); + if (!ld) { + LILV_ERRORF("No plugin <%s> in <%s>\n", + lilv_node_as_uri(lilv_plugin_get_uri(plugin)), + lilv_node_as_uri(lib_uri)); + lilv_lib_close(lib); + break; // return NULL + } + + if (!strcmp(ld->URI, lilv_node_as_uri(lilv_plugin_get_uri(plugin)))) { + // Create LilvInstance to return + result = (LilvInstance*)malloc(sizeof(LilvInstance)); + result->lv2_descriptor = ld; + result->lv2_handle = ld->instantiate( + ld, sample_rate, bundle_path, (features) ? features : local_features); + result->pimpl = lib; + break; + } + } + + free(local_features); + serd_free(bundle_path); + + if (result) { + if (result->lv2_handle == NULL) { + // Failed to instantiate + free(result); + lilv_lib_close(lib); + return NULL; + } + + // "Connect" all ports to NULL (catches bugs) + for (uint32_t i = 0; i < lilv_plugin_get_num_ports(plugin); ++i) { + result->lv2_descriptor->connect_port(result->lv2_handle, i, NULL); + } + } + + return result; } void lilv_instance_free(LilvInstance* instance) { - if (!instance) { - return; - } - - instance->lv2_descriptor->cleanup(instance->lv2_handle); - instance->lv2_descriptor = NULL; - lilv_lib_close((LilvLib*)instance->pimpl); - instance->pimpl = NULL; - free(instance); + if (!instance) { + return; + } + + instance->lv2_descriptor->cleanup(instance->lv2_handle); + instance->lv2_descriptor = NULL; + lilv_lib_close((LilvLib*)instance->pimpl); + instance->pimpl = NULL; + free(instance); } @@ -22,107 +22,106 @@ #include "zix/tree.h" #ifndef _WIN32 -# include <dlfcn.h> +# include <dlfcn.h> #endif #include <stdint.h> #include <stdlib.h> LilvLib* -lilv_lib_open(LilvWorld* world, - const LilvNode* uri, - const char* bundle_path, - const LV2_Feature*const* features) +lilv_lib_open(LilvWorld* world, + const LilvNode* uri, + const char* bundle_path, + const LV2_Feature* const* features) { - ZixTreeIter* i = NULL; - const LilvLib key = { - world, (LilvNode*)uri, (char*)bundle_path, NULL, NULL, NULL, 0 - }; - if (!zix_tree_find(world->libs, &key, &i)) { - LilvLib* llib = (LilvLib*)zix_tree_get(i); - ++llib->refs; - return llib; - } - - const char* const lib_uri = lilv_node_as_uri(uri); - char* const lib_path = (char*)serd_file_uri_parse( - (const uint8_t*)lib_uri, NULL); - if (!lib_path) { - return NULL; - } - - dlerror(); - void* lib = dlopen(lib_path, RTLD_NOW); - if (!lib) { - LILV_ERRORF("Failed to open library %s (%s)\n", lib_path, dlerror()); - serd_free(lib_path); - return NULL; - } - - LV2_Descriptor_Function df = (LV2_Descriptor_Function) - lilv_dlfunc(lib, "lv2_descriptor"); - - LV2_Lib_Descriptor_Function ldf = (LV2_Lib_Descriptor_Function) - lilv_dlfunc(lib, "lv2_lib_descriptor"); - - const LV2_Lib_Descriptor* desc = NULL; - if (ldf) { - desc = ldf(bundle_path, features); - if (!desc) { - LILV_ERRORF("Call to %s:lv2_lib_descriptor failed\n", lib_path); - dlclose(lib); - serd_free(lib_path); - return NULL; - } - } else if (!df) { - LILV_ERRORF("No `lv2_descriptor' or `lv2_lib_descriptor' in %s\n", - lib_path); - dlclose(lib); - serd_free(lib_path); - return NULL; - } - serd_free(lib_path); - - LilvLib* llib = (LilvLib*)malloc(sizeof(LilvLib)); - llib->world = world; - llib->uri = lilv_node_duplicate(uri); - llib->bundle_path = lilv_strdup(bundle_path); - llib->lib = lib; - llib->lv2_descriptor = df; - llib->desc = desc; - llib->refs = 1; - - zix_tree_insert(world->libs, llib, NULL); - return llib; + ZixTreeIter* i = NULL; + const LilvLib key = { + world, (LilvNode*)uri, (char*)bundle_path, NULL, NULL, NULL, 0}; + if (!zix_tree_find(world->libs, &key, &i)) { + LilvLib* llib = (LilvLib*)zix_tree_get(i); + ++llib->refs; + return llib; + } + + const char* const lib_uri = lilv_node_as_uri(uri); + char* const lib_path = + (char*)serd_file_uri_parse((const uint8_t*)lib_uri, NULL); + if (!lib_path) { + return NULL; + } + + dlerror(); + void* lib = dlopen(lib_path, RTLD_NOW); + if (!lib) { + LILV_ERRORF("Failed to open library %s (%s)\n", lib_path, dlerror()); + serd_free(lib_path); + return NULL; + } + + LV2_Descriptor_Function df = + (LV2_Descriptor_Function)lilv_dlfunc(lib, "lv2_descriptor"); + + LV2_Lib_Descriptor_Function ldf = + (LV2_Lib_Descriptor_Function)lilv_dlfunc(lib, "lv2_lib_descriptor"); + + const LV2_Lib_Descriptor* desc = NULL; + if (ldf) { + desc = ldf(bundle_path, features); + if (!desc) { + LILV_ERRORF("Call to %s:lv2_lib_descriptor failed\n", lib_path); + dlclose(lib); + serd_free(lib_path); + return NULL; + } + } else if (!df) { + LILV_ERRORF("No `lv2_descriptor' or `lv2_lib_descriptor' in %s\n", + lib_path); + dlclose(lib); + serd_free(lib_path); + return NULL; + } + serd_free(lib_path); + + LilvLib* llib = (LilvLib*)malloc(sizeof(LilvLib)); + llib->world = world; + llib->uri = lilv_node_duplicate(uri); + llib->bundle_path = lilv_strdup(bundle_path); + llib->lib = lib; + llib->lv2_descriptor = df; + llib->desc = desc; + llib->refs = 1; + + zix_tree_insert(world->libs, llib, NULL); + return llib; } const LV2_Descriptor* lilv_lib_get_plugin(LilvLib* lib, uint32_t index) { - if (lib->lv2_descriptor) { - return lib->lv2_descriptor(index); - } + if (lib->lv2_descriptor) { + return lib->lv2_descriptor(index); + } - if (lib->desc) { - return lib->desc->get_plugin(lib->desc->handle, index); - } + if (lib->desc) { + return lib->desc->get_plugin(lib->desc->handle, index); + } - return NULL; + return NULL; } void lilv_lib_close(LilvLib* lib) { - if (--lib->refs == 0) { - dlclose(lib->lib); - - ZixTreeIter* i = NULL; - if (lib->world->libs && !zix_tree_find(lib->world->libs, lib, &i)) { - zix_tree_remove(lib->world->libs, i); - } - - lilv_node_free(lib->uri); - free(lib->bundle_path); - free(lib); - } + if (--lib->refs == 0) { + dlclose(lib->lib); + + ZixTreeIter* i = NULL; + if (lib->world->libs && !zix_tree_find(lib->world->libs, lib, &i)) { + zix_tree_remove(lib->world->libs, i); + } + + lilv_node_free(lib->uri); + free(lib->bundle_path); + free(lib); + } } diff --git a/src/lilv_internal.h b/src/lilv_internal.h index e5fde7a..55e59d2 100644 --- a/src/lilv_internal.h +++ b/src/lilv_internal.h @@ -34,30 +34,34 @@ extern "C" { #include <stdio.h> #ifdef _WIN32 -# include <windows.h> -# include <direct.h> -# include <stdio.h> -# define dlopen(path, flags) LoadLibrary(path) -# define dlclose(lib) FreeLibrary((HMODULE)lib) -# ifdef _MSC_VER -# define __func__ __FUNCTION__ -# ifndef snprintf -# define snprintf _snprintf -# endif +# include <direct.h> +# include <stdio.h> +# include <windows.h> +# define dlopen(path, flags) LoadLibrary(path) +# define dlclose(lib) FreeLibrary((HMODULE)lib) +# ifdef _MSC_VER +# define __func__ __FUNCTION__ +# ifndef snprintf +# define snprintf _snprintf # endif -#ifndef INFINITY +# endif +# ifndef INFINITY # define INFINITY DBL_MAX + DBL_MAX -#endif -#ifndef NAN +# endif +# ifndef NAN # define NAN INFINITY - INFINITY -#endif -static inline const char* dlerror(void) { return "Unknown error"; } +# endif +static inline const char* +dlerror(void) +{ + return "Unknown error"; +} #else -# include <dlfcn.h> +# include <dlfcn.h> #endif #ifdef LILV_DYN_MANIFEST -# include "lv2/dynmanifest/dynmanifest.h" +# include "lv2/dynmanifest/dynmanifest.h" #endif /* @@ -69,17 +73,17 @@ static inline const char* dlerror(void) { return "Unknown error"; } typedef void LilvCollection; struct LilvPortImpl { - LilvNode* node; ///< RDF node - uint32_t index; ///< lv2:index - LilvNode* symbol; ///< lv2:symbol - LilvNodes* classes; ///< rdf:type + LilvNode* node; ///< RDF node + uint32_t index; ///< lv2:index + LilvNode* symbol; ///< lv2:symbol + LilvNodes* classes; ///< rdf:type }; typedef struct LilvSpecImpl { - SordNode* spec; - SordNode* bundle; - LilvNodes* data_uris; - struct LilvSpecImpl* next; + SordNode* spec; + SordNode* bundle; + LilvNodes* data_uris; + struct LilvSpecImpl* next; } LilvSpec; /** @@ -88,156 +92,156 @@ typedef struct LilvSpecImpl { implement collections using the same comparator. */ struct LilvHeader { - LilvWorld* world; - LilvNode* uri; + LilvWorld* world; + LilvNode* uri; }; #ifdef LILV_DYN_MANIFEST typedef struct { - LilvNode* bundle; - void* lib; - LV2_Dyn_Manifest_Handle handle; - uint32_t refs; + LilvNode* bundle; + void* lib; + LV2_Dyn_Manifest_Handle handle; + uint32_t refs; } LilvDynManifest; #endif typedef struct { - LilvWorld* world; - LilvNode* uri; - char* bundle_path; - void* lib; - LV2_Descriptor_Function lv2_descriptor; - const LV2_Lib_Descriptor* desc; - uint32_t refs; + LilvWorld* world; + LilvNode* uri; + char* bundle_path; + void* lib; + LV2_Descriptor_Function lv2_descriptor; + const LV2_Lib_Descriptor* desc; + uint32_t refs; } LilvLib; struct LilvPluginImpl { - LilvWorld* world; - LilvNode* plugin_uri; - LilvNode* bundle_uri; ///< Bundle plugin was loaded from - LilvNode* binary_uri; ///< lv2:binary + LilvWorld* world; + LilvNode* plugin_uri; + LilvNode* bundle_uri; ///< Bundle plugin was loaded from + LilvNode* binary_uri; ///< lv2:binary #ifdef LILV_DYN_MANIFEST - LilvDynManifest* dynmanifest; + LilvDynManifest* dynmanifest; #endif - const LilvPluginClass* plugin_class; - LilvNodes* data_uris; ///< rdfs::seeAlso - LilvPort** ports; - uint32_t num_ports; - bool loaded; - bool parse_errors; - bool replaced; + const LilvPluginClass* plugin_class; + LilvNodes* data_uris; ///< rdfs::seeAlso + LilvPort** ports; + uint32_t num_ports; + bool loaded; + bool parse_errors; + bool replaced; }; struct LilvPluginClassImpl { - LilvWorld* world; - LilvNode* uri; - LilvNode* parent_uri; - LilvNode* label; + LilvWorld* world; + LilvNode* uri; + LilvNode* parent_uri; + LilvNode* label; }; struct LilvInstancePimpl { - LilvWorld* world; - LilvLib* lib; + LilvWorld* world; + LilvLib* lib; }; typedef struct { - bool dyn_manifest; - bool filter_language; - char* lv2_path; + bool dyn_manifest; + bool filter_language; + char* lv2_path; } LilvOptions; struct LilvWorldImpl { - SordWorld* world; - SordModel* model; - SerdReader* reader; - unsigned n_read_files; - LilvPluginClass* lv2_plugin_class; - LilvPluginClasses* plugin_classes; - LilvSpec* specs; - LilvPlugins* plugins; - LilvPlugins* zombies; - LilvNodes* loaded_files; - ZixTree* libs; - struct { - SordNode* dc_replaces; - SordNode* dman_DynManifest; - SordNode* doap_name; - SordNode* lv2_Plugin; - SordNode* lv2_Specification; - SordNode* lv2_appliesTo; - SordNode* lv2_binary; - SordNode* lv2_default; - SordNode* lv2_designation; - SordNode* lv2_extensionData; - SordNode* lv2_index; - SordNode* lv2_latency; - SordNode* lv2_maximum; - SordNode* lv2_microVersion; - SordNode* lv2_minimum; - SordNode* lv2_minorVersion; - SordNode* lv2_name; - SordNode* lv2_optionalFeature; - SordNode* lv2_port; - SordNode* lv2_portProperty; - SordNode* lv2_reportsLatency; - SordNode* lv2_requiredFeature; - SordNode* lv2_symbol; - SordNode* lv2_prototype; - SordNode* owl_Ontology; - SordNode* pset_value; - SordNode* rdf_a; - SordNode* rdf_value; - SordNode* rdfs_Class; - SordNode* rdfs_label; - SordNode* rdfs_seeAlso; - SordNode* rdfs_subClassOf; - SordNode* xsd_base64Binary; - SordNode* xsd_boolean; - SordNode* xsd_decimal; - SordNode* xsd_double; - SordNode* xsd_integer; - SordNode* null_uri; - } uris; - LilvOptions opt; + SordWorld* world; + SordModel* model; + SerdReader* reader; + unsigned n_read_files; + LilvPluginClass* lv2_plugin_class; + LilvPluginClasses* plugin_classes; + LilvSpec* specs; + LilvPlugins* plugins; + LilvPlugins* zombies; + LilvNodes* loaded_files; + ZixTree* libs; + struct { + SordNode* dc_replaces; + SordNode* dman_DynManifest; + SordNode* doap_name; + SordNode* lv2_Plugin; + SordNode* lv2_Specification; + SordNode* lv2_appliesTo; + SordNode* lv2_binary; + SordNode* lv2_default; + SordNode* lv2_designation; + SordNode* lv2_extensionData; + SordNode* lv2_index; + SordNode* lv2_latency; + SordNode* lv2_maximum; + SordNode* lv2_microVersion; + SordNode* lv2_minimum; + SordNode* lv2_minorVersion; + SordNode* lv2_name; + SordNode* lv2_optionalFeature; + SordNode* lv2_port; + SordNode* lv2_portProperty; + SordNode* lv2_reportsLatency; + SordNode* lv2_requiredFeature; + SordNode* lv2_symbol; + SordNode* lv2_prototype; + SordNode* owl_Ontology; + SordNode* pset_value; + SordNode* rdf_a; + SordNode* rdf_value; + SordNode* rdfs_Class; + SordNode* rdfs_label; + SordNode* rdfs_seeAlso; + SordNode* rdfs_subClassOf; + SordNode* xsd_base64Binary; + SordNode* xsd_boolean; + SordNode* xsd_decimal; + SordNode* xsd_double; + SordNode* xsd_integer; + SordNode* null_uri; + } uris; + LilvOptions opt; }; typedef enum { - LILV_VALUE_URI, - LILV_VALUE_STRING, - LILV_VALUE_INT, - LILV_VALUE_FLOAT, - LILV_VALUE_BOOL, - LILV_VALUE_BLANK, - LILV_VALUE_BLOB + LILV_VALUE_URI, + LILV_VALUE_STRING, + LILV_VALUE_INT, + LILV_VALUE_FLOAT, + LILV_VALUE_BOOL, + LILV_VALUE_BLANK, + LILV_VALUE_BLOB } LilvNodeType; struct LilvNodeImpl { - LilvWorld* world; - SordNode* node; - LilvNodeType type; - union { - int int_val; - float float_val; - bool bool_val; - } val; + LilvWorld* world; + SordNode* node; + LilvNodeType type; + union { + int int_val; + float float_val; + bool bool_val; + } val; }; struct LilvScalePointImpl { - LilvNode* value; - LilvNode* label; + LilvNode* value; + LilvNode* label; }; struct LilvUIImpl { - LilvWorld* world; - LilvNode* uri; - LilvNode* bundle_uri; - LilvNode* binary_uri; - LilvNodes* classes; + LilvWorld* world; + LilvNode* uri; + LilvNode* bundle_uri; + LilvNode* binary_uri; + LilvNodes* classes; }; typedef struct LilvVersion { - int minor; - int micro; + int minor; + int micro; } LilvVersion; /* @@ -246,100 +250,140 @@ typedef struct LilvVersion { * */ -LilvPort* lilv_port_new(LilvWorld* world, - const SordNode* node, - uint32_t index, - const char* symbol); -void lilv_port_free(const LilvPlugin* plugin, LilvPort* port); - -LilvPlugin* lilv_plugin_new(LilvWorld* world, - LilvNode* uri, - LilvNode* bundle_uri); -void lilv_plugin_clear(LilvPlugin* plugin, LilvNode* bundle_uri); -void lilv_plugin_load_if_necessary(const LilvPlugin* plugin); -void lilv_plugin_free(LilvPlugin* plugin); -LilvNode* lilv_plugin_get_unique(const LilvPlugin* plugin, - const SordNode* subject, - const SordNode* predicate); - -void lilv_collection_free(LilvCollection* collection); -unsigned lilv_collection_size(const LilvCollection* collection); -LilvIter* lilv_collection_begin(const LilvCollection* collection); -void* lilv_collection_get(const LilvCollection* collection, - const LilvIter* i); - -LilvPluginClass* lilv_plugin_class_new(LilvWorld* world, - const SordNode* parent_node, - const SordNode* uri, - const char* label); - -void lilv_plugin_class_free(LilvPluginClass* plugin_class); +LilvPort* +lilv_port_new(LilvWorld* world, + const SordNode* node, + uint32_t index, + const char* symbol); +void +lilv_port_free(const LilvPlugin* plugin, LilvPort* port); + +LilvPlugin* +lilv_plugin_new(LilvWorld* world, LilvNode* uri, LilvNode* bundle_uri); + +void +lilv_plugin_clear(LilvPlugin* plugin, LilvNode* bundle_uri); + +void +lilv_plugin_load_if_necessary(const LilvPlugin* plugin); + +void +lilv_plugin_free(LilvPlugin* plugin); + +LilvNode* +lilv_plugin_get_unique(const LilvPlugin* plugin, + const SordNode* subject, + const SordNode* predicate); + +void +lilv_collection_free(LilvCollection* collection); + +unsigned +lilv_collection_size(const LilvCollection* collection); + +LilvIter* +lilv_collection_begin(const LilvCollection* collection); + +void* +lilv_collection_get(const LilvCollection* collection, const LilvIter* i); + +LilvPluginClass* +lilv_plugin_class_new(LilvWorld* world, + const SordNode* parent_node, + const SordNode* uri, + const char* label); + +void +lilv_plugin_class_free(LilvPluginClass* plugin_class); LilvLib* -lilv_lib_open(LilvWorld* world, - const LilvNode* uri, - const char* bundle_path, - const LV2_Feature*const* features); +lilv_lib_open(LilvWorld* world, + const LilvNode* uri, + const char* bundle_path, + const LV2_Feature* const* features); + +const LV2_Descriptor* +lilv_lib_get_plugin(LilvLib* lib, uint32_t index); + +void +lilv_lib_close(LilvLib* lib); + +LilvNodes* +lilv_nodes_new(void); + +LilvPlugins* +lilv_plugins_new(void); -const LV2_Descriptor* lilv_lib_get_plugin(LilvLib* lib, uint32_t index); -void lilv_lib_close(LilvLib* lib); +LilvScalePoints* +lilv_scale_points_new(void); -LilvNodes* lilv_nodes_new(void); -LilvPlugins* lilv_plugins_new(void); -LilvScalePoints* lilv_scale_points_new(void); -LilvPluginClasses* lilv_plugin_classes_new(void); -LilvUIs* lilv_uis_new(void); +LilvPluginClasses* +lilv_plugin_classes_new(void); -LilvNode* lilv_world_get_manifest_uri(LilvWorld* world, - const LilvNode* bundle_uri); +LilvUIs* +lilv_uis_new(void); -const uint8_t* lilv_world_blank_node_prefix(LilvWorld* world); +LilvNode* +lilv_world_get_manifest_uri(LilvWorld* world, const LilvNode* bundle_uri); -SerdStatus lilv_world_load_file(LilvWorld* world, - SerdReader* reader, - const LilvNode* uri); +const uint8_t* +lilv_world_blank_node_prefix(LilvWorld* world); SerdStatus -lilv_world_load_graph(LilvWorld* world, - SordNode* graph, - const LilvNode* uri); +lilv_world_load_file(LilvWorld* world, SerdReader* reader, const LilvNode* uri); + +SerdStatus +lilv_world_load_graph(LilvWorld* world, SordNode* graph, const LilvNode* uri); + +LilvUI* +lilv_ui_new(LilvWorld* world, + LilvNode* uri, + LilvNode* type_uri, + LilvNode* binary_uri); -LilvUI* lilv_ui_new(LilvWorld* world, - LilvNode* uri, - LilvNode* type_uri, - LilvNode* binary_uri); +void +lilv_ui_free(LilvUI* ui); -void lilv_ui_free(LilvUI* ui); +LilvNode* +lilv_node_new(LilvWorld* world, LilvNodeType type, const char* str); -LilvNode* lilv_node_new(LilvWorld* world, LilvNodeType type, const char* str); -LilvNode* lilv_node_new_from_node(LilvWorld* world, const SordNode* node); +LilvNode* +lilv_node_new_from_node(LilvWorld* world, const SordNode* node); -int lilv_header_compare_by_uri(const void* a, const void* b, void* user_data); -int lilv_lib_compare(const void* a, const void* b, void* user_data); +int +lilv_header_compare_by_uri(const void* a, const void* b, void* user_data); -int lilv_ptr_cmp(const void* a, const void* b, void* user_data); -int lilv_resource_node_cmp(const void* a, const void* b, void* user_data); +int +lilv_lib_compare(const void* a, const void* b, void* user_data); + +int +lilv_ptr_cmp(const void* a, const void* b, void* user_data); + +int +lilv_resource_node_cmp(const void* a, const void* b, void* user_data); static inline int lilv_version_cmp(const LilvVersion* a, const LilvVersion* b) { - if (a->minor == b->minor && a->micro == b->micro) { - return 0; - } + if (a->minor == b->minor && a->micro == b->micro) { + return 0; + } - if ((a->minor < b->minor) - || (a->minor == b->minor && a->micro < b->micro)) { - return -1; - } + if ((a->minor < b->minor) || (a->minor == b->minor && a->micro < b->micro)) { + return -1; + } - return 1; + return 1; } struct LilvHeader* lilv_collection_get_by_uri(const ZixTree* seq, const LilvNode* uri); -LilvScalePoint* lilv_scale_point_new(LilvNode* value, LilvNode* label); -void lilv_scale_point_free(LilvScalePoint* point); +LilvScalePoint* +lilv_scale_point_new(LilvNode* value, LilvNode* label); + +void +lilv_scale_point_free(LilvScalePoint* point); SordIter* lilv_world_query_internal(LilvWorld* world, @@ -367,18 +411,27 @@ lilv_world_filter_model(LilvWorld* world, const SordNode* object, const SordNode* graph); -#define FOREACH_MATCH(iter) \ - for (; !sord_iter_end(iter); sord_iter_next(iter)) +#define FOREACH_MATCH(iter) for (; !sord_iter_end(iter); sord_iter_next(iter)) + +LilvNodes* +lilv_nodes_from_stream_objects(LilvWorld* world, + SordIter* stream, + SordQuadIndex field); -LilvNodes* lilv_nodes_from_stream_objects(LilvWorld* world, - SordIter* stream, - SordQuadIndex field); +char* +lilv_strjoin(const char* first, ...); -char* lilv_strjoin(const char* first, ...); -char* lilv_strdup(const char* str); -char* lilv_get_lang(void); -char* lilv_expand(const char* path); -char* lilv_get_latest_copy(const char* path, const char* copy_path); +char* +lilv_strdup(const char* str); + +char* +lilv_get_lang(void); + +char* +lilv_expand(const char* path); + +char* +lilv_get_latest_copy(const char* path, const char* copy_path); char* lilv_find_free_path(const char* in_path, @@ -392,32 +445,30 @@ static inline LilvVoidFunc lilv_dlfunc(void* handle, const char* symbol) { #ifdef _WIN32 - return (LilvVoidFunc)GetProcAddress((HMODULE)handle, symbol); + return (LilvVoidFunc)GetProcAddress((HMODULE)handle, symbol); #else - typedef LilvVoidFunc (*VoidFuncGetter)(void*, const char*); - VoidFuncGetter dlfunc = (VoidFuncGetter)dlsym; - return dlfunc(handle, symbol); + typedef LilvVoidFunc (*VoidFuncGetter)(void*, const char*); + VoidFuncGetter dlfunc = (VoidFuncGetter)dlsym; + return dlfunc(handle, symbol); #endif } #ifdef LILV_DYN_MANIFEST -static const LV2_Feature* const dman_features = { NULL }; +static const LV2_Feature* const dman_features = {NULL}; -void lilv_dynmanifest_free(LilvDynManifest* dynmanifest); +void +lilv_dynmanifest_free(LilvDynManifest* dynmanifest); #endif -#define LILV_ERROR(str) fprintf(stderr, "%s(): error: " str, \ - __func__) -#define LILV_ERRORF(fmt, ...) fprintf(stderr, "%s(): error: " fmt, \ - __func__, __VA_ARGS__) -#define LILV_WARN(str) fprintf(stderr, "%s(): warning: " str, \ - __func__) -#define LILV_WARNF(fmt, ...) fprintf(stderr, "%s(): warning: " fmt, \ - __func__, __VA_ARGS__) -#define LILV_NOTE(str) fprintf(stderr, "%s(): note: " str, \ - __func__) -#define LILV_NOTEF(fmt, ...) fprintf(stderr, "%s(): note: " fmt, \ - __func__, __VA_ARGS__) +#define LILV_ERROR(str) fprintf(stderr, "%s(): error: " str, __func__) +#define LILV_ERRORF(fmt, ...) \ + fprintf(stderr, "%s(): error: " fmt, __func__, __VA_ARGS__) +#define LILV_WARN(str) fprintf(stderr, "%s(): warning: " str, __func__) +#define LILV_WARNF(fmt, ...) \ + fprintf(stderr, "%s(): warning: " fmt, __func__, __VA_ARGS__) +#define LILV_NOTE(str) fprintf(stderr, "%s(): note: " str, __func__) +#define LILV_NOTEF(fmt, ...) \ + fprintf(stderr, "%s(): note: " fmt, __func__, __VA_ARGS__) #ifdef __cplusplus } @@ -31,24 +31,24 @@ static void lilv_node_set_numerics_from_string(LilvNode* val) { - const char* str = (const char*)sord_node_get_string(val->node); - - switch (val->type) { - case LILV_VALUE_URI: - case LILV_VALUE_BLANK: - case LILV_VALUE_STRING: - case LILV_VALUE_BLOB: - break; - case LILV_VALUE_INT: - val->val.int_val = strtol(str, NULL, 10); - break; - case LILV_VALUE_FLOAT: - val->val.float_val = serd_strtod(str, NULL); - break; - case LILV_VALUE_BOOL: - val->val.bool_val = !strcmp(str, "true"); - break; - } + const char* str = (const char*)sord_node_get_string(val->node); + + switch (val->type) { + case LILV_VALUE_URI: + case LILV_VALUE_BLANK: + case LILV_VALUE_STRING: + case LILV_VALUE_BLOB: + break; + case LILV_VALUE_INT: + val->val.int_val = strtol(str, NULL, 10); + break; + case LILV_VALUE_FLOAT: + val->val.float_val = serd_strtod(str, NULL); + break; + case LILV_VALUE_BOOL: + val->val.bool_val = !strcmp(str, "true"); + break; + } } /** Note that if `type` is numeric or boolean, the returned value is corrupt @@ -59,357 +59,355 @@ lilv_node_set_numerics_from_string(LilvNode* val) LilvNode* lilv_node_new(LilvWorld* world, LilvNodeType type, const char* str) { - LilvNode* val = (LilvNode*)malloc(sizeof(LilvNode)); - val->world = world; - val->type = type; - - const uint8_t* ustr = (const uint8_t*)str; - switch (type) { - case LILV_VALUE_URI: - val->node = sord_new_uri(world->world, ustr); - break; - case LILV_VALUE_BLANK: - val->node = sord_new_blank(world->world, ustr); - break; - case LILV_VALUE_STRING: - val->node = sord_new_literal(world->world, NULL, ustr, NULL); - break; - case LILV_VALUE_INT: - val->node = sord_new_literal( - world->world, world->uris.xsd_integer, ustr, NULL); - break; - case LILV_VALUE_FLOAT: - val->node = sord_new_literal( - world->world, world->uris.xsd_decimal, ustr, NULL); - break; - case LILV_VALUE_BOOL: - val->node = sord_new_literal( - world->world, world->uris.xsd_boolean, ustr, NULL); - break; - case LILV_VALUE_BLOB: - val->node = sord_new_literal( - world->world, world->uris.xsd_base64Binary, ustr, NULL); - break; - } - - if (!val->node) { - free(val); - return NULL; - } - - return val; + LilvNode* val = (LilvNode*)malloc(sizeof(LilvNode)); + val->world = world; + val->type = type; + + const uint8_t* ustr = (const uint8_t*)str; + switch (type) { + case LILV_VALUE_URI: + val->node = sord_new_uri(world->world, ustr); + break; + case LILV_VALUE_BLANK: + val->node = sord_new_blank(world->world, ustr); + break; + case LILV_VALUE_STRING: + val->node = sord_new_literal(world->world, NULL, ustr, NULL); + break; + case LILV_VALUE_INT: + val->node = + sord_new_literal(world->world, world->uris.xsd_integer, ustr, NULL); + break; + case LILV_VALUE_FLOAT: + val->node = + sord_new_literal(world->world, world->uris.xsd_decimal, ustr, NULL); + break; + case LILV_VALUE_BOOL: + val->node = + sord_new_literal(world->world, world->uris.xsd_boolean, ustr, NULL); + break; + case LILV_VALUE_BLOB: + val->node = + sord_new_literal(world->world, world->uris.xsd_base64Binary, ustr, NULL); + break; + } + + if (!val->node) { + free(val); + return NULL; + } + + return val; } /** Create a new LilvNode from `node`, or return NULL if impossible */ LilvNode* lilv_node_new_from_node(LilvWorld* world, const SordNode* node) { - if (!node) { - return NULL; - } - - LilvNode* result = NULL; - SordNode* datatype_uri = NULL; - LilvNodeType type = LILV_VALUE_STRING; - - switch (sord_node_get_type(node)) { - case SORD_URI: - result = (LilvNode*)malloc(sizeof(LilvNode)); - result->world = world; - result->type = LILV_VALUE_URI; - result->node = sord_node_copy(node); - break; - case SORD_BLANK: - result = (LilvNode*)malloc(sizeof(LilvNode)); - result->world = world; - result->type = LILV_VALUE_BLANK; - result->node = sord_node_copy(node); - break; - case SORD_LITERAL: - datatype_uri = sord_node_get_datatype(node); - if (datatype_uri) { - if (sord_node_equals(datatype_uri, world->uris.xsd_boolean)) { - type = LILV_VALUE_BOOL; - } else if (sord_node_equals(datatype_uri, world->uris.xsd_decimal) || - sord_node_equals(datatype_uri, world->uris.xsd_double)) { - type = LILV_VALUE_FLOAT; - } else if (sord_node_equals(datatype_uri, world->uris.xsd_integer)) { - type = LILV_VALUE_INT; - } else if (sord_node_equals(datatype_uri, - world->uris.xsd_base64Binary)) { - type = LILV_VALUE_BLOB; - } else { - LILV_ERRORF("Unknown datatype `%s'\n", - sord_node_get_string(datatype_uri)); - } - } - result = lilv_node_new( - world, type, (const char*)sord_node_get_string(node)); - lilv_node_set_numerics_from_string(result); - break; - } - - return result; + if (!node) { + return NULL; + } + + LilvNode* result = NULL; + SordNode* datatype_uri = NULL; + LilvNodeType type = LILV_VALUE_STRING; + + switch (sord_node_get_type(node)) { + case SORD_URI: + result = (LilvNode*)malloc(sizeof(LilvNode)); + result->world = world; + result->type = LILV_VALUE_URI; + result->node = sord_node_copy(node); + break; + case SORD_BLANK: + result = (LilvNode*)malloc(sizeof(LilvNode)); + result->world = world; + result->type = LILV_VALUE_BLANK; + result->node = sord_node_copy(node); + break; + case SORD_LITERAL: + datatype_uri = sord_node_get_datatype(node); + if (datatype_uri) { + if (sord_node_equals(datatype_uri, world->uris.xsd_boolean)) { + type = LILV_VALUE_BOOL; + } else if (sord_node_equals(datatype_uri, world->uris.xsd_decimal) || + sord_node_equals(datatype_uri, world->uris.xsd_double)) { + type = LILV_VALUE_FLOAT; + } else if (sord_node_equals(datatype_uri, world->uris.xsd_integer)) { + type = LILV_VALUE_INT; + } else if (sord_node_equals(datatype_uri, world->uris.xsd_base64Binary)) { + type = LILV_VALUE_BLOB; + } else { + LILV_ERRORF("Unknown datatype `%s'\n", + sord_node_get_string(datatype_uri)); + } + } + result = + lilv_node_new(world, type, (const char*)sord_node_get_string(node)); + lilv_node_set_numerics_from_string(result); + break; + } + + return result; } LilvNode* lilv_new_uri(LilvWorld* world, const char* uri) { - return lilv_node_new(world, LILV_VALUE_URI, uri); + return lilv_node_new(world, LILV_VALUE_URI, uri); } LilvNode* lilv_new_file_uri(LilvWorld* world, const char* host, const char* path) { - char* abs_path = lilv_path_absolute(path); - SerdNode s = serd_node_new_file_uri( - (const uint8_t*)abs_path, (const uint8_t*)host, NULL, true); - - LilvNode* ret = lilv_node_new(world, LILV_VALUE_URI, (const char*)s.buf); - serd_node_free(&s); - free(abs_path); - return ret; + char* abs_path = lilv_path_absolute(path); + SerdNode s = serd_node_new_file_uri( + (const uint8_t*)abs_path, (const uint8_t*)host, NULL, true); + + LilvNode* ret = lilv_node_new(world, LILV_VALUE_URI, (const char*)s.buf); + serd_node_free(&s); + free(abs_path); + return ret; } LilvNode* lilv_new_string(LilvWorld* world, const char* str) { - return lilv_node_new(world, LILV_VALUE_STRING, str); + return lilv_node_new(world, LILV_VALUE_STRING, str); } LilvNode* lilv_new_int(LilvWorld* world, int val) { - char str[32]; - snprintf(str, sizeof(str), "%d", val); - LilvNode* ret = lilv_node_new(world, LILV_VALUE_INT, str); - if (ret) { - ret->val.int_val = val; - } - return ret; + char str[32]; + snprintf(str, sizeof(str), "%d", val); + LilvNode* ret = lilv_node_new(world, LILV_VALUE_INT, str); + if (ret) { + ret->val.int_val = val; + } + return ret; } LilvNode* lilv_new_float(LilvWorld* world, float val) { - char str[32]; - snprintf(str, sizeof(str), "%f", val); - LilvNode* ret = lilv_node_new(world, LILV_VALUE_FLOAT, str); - if (ret) { - ret->val.float_val = val; - } - return ret; + char str[32]; + snprintf(str, sizeof(str), "%f", val); + LilvNode* ret = lilv_node_new(world, LILV_VALUE_FLOAT, str); + if (ret) { + ret->val.float_val = val; + } + return ret; } LilvNode* lilv_new_bool(LilvWorld* world, bool val) { - LilvNode* ret = lilv_node_new(world, LILV_VALUE_BOOL, - val ? "true" : "false"); - if (ret) { - ret->val.bool_val = val; - } - return ret; + LilvNode* ret = lilv_node_new(world, LILV_VALUE_BOOL, val ? "true" : "false"); + if (ret) { + ret->val.bool_val = val; + } + return ret; } LilvNode* lilv_node_duplicate(const LilvNode* val) { - if (!val) { - return NULL; - } - - LilvNode* result = (LilvNode*)malloc(sizeof(LilvNode)); - result->world = val->world; - result->node = sord_node_copy(val->node); - result->val = val->val; - result->type = val->type; - return result; + if (!val) { + return NULL; + } + + LilvNode* result = (LilvNode*)malloc(sizeof(LilvNode)); + result->world = val->world; + result->node = sord_node_copy(val->node); + result->val = val->val; + result->type = val->type; + return result; } void lilv_node_free(LilvNode* val) { - if (val) { - sord_node_free(val->world->world, val->node); - free(val); - } + if (val) { + sord_node_free(val->world->world, val->node); + free(val); + } } bool lilv_node_equals(const LilvNode* value, const LilvNode* other) { - if (value == NULL && other == NULL) { - return true; - } - - if (value == NULL || other == NULL || value->type != other->type) { - return false; - } - - switch (value->type) { - case LILV_VALUE_URI: - case LILV_VALUE_BLANK: - case LILV_VALUE_STRING: - case LILV_VALUE_BLOB: - return sord_node_equals(value->node, other->node); - case LILV_VALUE_INT: - return (value->val.int_val == other->val.int_val); - case LILV_VALUE_FLOAT: - return (value->val.float_val == other->val.float_val); - case LILV_VALUE_BOOL: - return (value->val.bool_val == other->val.bool_val); - } - - return false; /* shouldn't get here */ + if (value == NULL && other == NULL) { + return true; + } + + if (value == NULL || other == NULL || value->type != other->type) { + return false; + } + + switch (value->type) { + case LILV_VALUE_URI: + case LILV_VALUE_BLANK: + case LILV_VALUE_STRING: + case LILV_VALUE_BLOB: + return sord_node_equals(value->node, other->node); + case LILV_VALUE_INT: + return (value->val.int_val == other->val.int_val); + case LILV_VALUE_FLOAT: + return (value->val.float_val == other->val.float_val); + case LILV_VALUE_BOOL: + return (value->val.bool_val == other->val.bool_val); + } + + return false; /* shouldn't get here */ } char* lilv_node_get_turtle_token(const LilvNode* value) { - const char* str = (const char*)sord_node_get_string(value->node); - size_t len = 0; - char* result = NULL; - SerdNode node; - - switch (value->type) { - case LILV_VALUE_URI: - len = strlen(str) + 3; - result = (char*)calloc(len, 1); - snprintf(result, len, "<%s>", str); - break; - case LILV_VALUE_BLANK: - len = strlen(str) + 3; - result = (char*)calloc(len, 1); - snprintf(result, len, "_:%s", str); - break; - case LILV_VALUE_STRING: - case LILV_VALUE_BOOL: - case LILV_VALUE_BLOB: - result = lilv_strdup(str); - break; - case LILV_VALUE_INT: - node = serd_node_new_integer(value->val.int_val); - result = lilv_strdup((char*)node.buf); - serd_node_free(&node); - break; - case LILV_VALUE_FLOAT: - node = serd_node_new_decimal(value->val.float_val, 8); - result = lilv_strdup((char*)node.buf); - serd_node_free(&node); - break; - } - - return result; + const char* str = (const char*)sord_node_get_string(value->node); + size_t len = 0; + char* result = NULL; + SerdNode node; + + switch (value->type) { + case LILV_VALUE_URI: + len = strlen(str) + 3; + result = (char*)calloc(len, 1); + snprintf(result, len, "<%s>", str); + break; + case LILV_VALUE_BLANK: + len = strlen(str) + 3; + result = (char*)calloc(len, 1); + snprintf(result, len, "_:%s", str); + break; + case LILV_VALUE_STRING: + case LILV_VALUE_BOOL: + case LILV_VALUE_BLOB: + result = lilv_strdup(str); + break; + case LILV_VALUE_INT: + node = serd_node_new_integer(value->val.int_val); + result = lilv_strdup((char*)node.buf); + serd_node_free(&node); + break; + case LILV_VALUE_FLOAT: + node = serd_node_new_decimal(value->val.float_val, 8); + result = lilv_strdup((char*)node.buf); + serd_node_free(&node); + break; + } + + return result; } bool lilv_node_is_uri(const LilvNode* value) { - return (value && value->type == LILV_VALUE_URI); + return (value && value->type == LILV_VALUE_URI); } const char* lilv_node_as_uri(const LilvNode* value) { - return (lilv_node_is_uri(value) - ? (const char*)sord_node_get_string(value->node) - : NULL); + return (lilv_node_is_uri(value) + ? (const char*)sord_node_get_string(value->node) + : NULL); } bool lilv_node_is_blank(const LilvNode* value) { - return (value && value->type == LILV_VALUE_BLANK); + return (value && value->type == LILV_VALUE_BLANK); } const char* lilv_node_as_blank(const LilvNode* value) { - return (lilv_node_is_blank(value) - ? (const char*)sord_node_get_string(value->node) - : NULL); + return (lilv_node_is_blank(value) + ? (const char*)sord_node_get_string(value->node) + : NULL); } bool lilv_node_is_literal(const LilvNode* value) { - if (!value) { - return false; - } - - switch (value->type) { - case LILV_VALUE_STRING: - case LILV_VALUE_INT: - case LILV_VALUE_FLOAT: - case LILV_VALUE_BLOB: - return true; - default: - return false; - } + if (!value) { + return false; + } + + switch (value->type) { + case LILV_VALUE_STRING: + case LILV_VALUE_INT: + case LILV_VALUE_FLOAT: + case LILV_VALUE_BLOB: + return true; + default: + return false; + } } bool lilv_node_is_string(const LilvNode* value) { - return (value && value->type == LILV_VALUE_STRING); + return (value && value->type == LILV_VALUE_STRING); } const char* lilv_node_as_string(const LilvNode* value) { - return value ? (const char*)sord_node_get_string(value->node) : NULL; + return value ? (const char*)sord_node_get_string(value->node) : NULL; } bool lilv_node_is_int(const LilvNode* value) { - return (value && value->type == LILV_VALUE_INT); + return (value && value->type == LILV_VALUE_INT); } int lilv_node_as_int(const LilvNode* value) { - return lilv_node_is_int(value) ? value->val.int_val : 0; + return lilv_node_is_int(value) ? value->val.int_val : 0; } bool lilv_node_is_float(const LilvNode* value) { - return (value && value->type == LILV_VALUE_FLOAT); + return (value && value->type == LILV_VALUE_FLOAT); } float lilv_node_as_float(const LilvNode* value) { - if (lilv_node_is_float(value)) { - return value->val.float_val; - } + if (lilv_node_is_float(value)) { + return value->val.float_val; + } - if (lilv_node_is_int(value)) { - return (float)value->val.int_val; - } + if (lilv_node_is_int(value)) { + return (float)value->val.int_val; + } - return NAN; + return NAN; } bool lilv_node_is_bool(const LilvNode* value) { - return (value && value->type == LILV_VALUE_BOOL); + return (value && value->type == LILV_VALUE_BOOL); } bool lilv_node_as_bool(const LilvNode* value) { - return lilv_node_is_bool(value) ? value->val.bool_val : false; + return lilv_node_is_bool(value) ? value->val.bool_val : false; } char* lilv_node_get_path(const LilvNode* value, char** hostname) { - if (lilv_node_is_uri(value)) { - return lilv_file_uri_parse(lilv_node_as_uri(value), hostname); - } - return NULL; + if (lilv_node_is_uri(value)) { + return lilv_file_uri_parse(lilv_node_as_uri(value), hostname); + } + return NULL; } diff --git a/src/plugin.c b/src/plugin.c index c72cc28..84b63e4 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -25,7 +25,7 @@ #include "lv2/ui/ui.h" #ifdef LILV_DYN_MANIFEST -# include "lv2/dynmanifest/dynmanifest.h" +# include "lv2/dynmanifest/dynmanifest.h" #endif #include <math.h> @@ -42,79 +42,79 @@ static void lilv_plugin_init(LilvPlugin* plugin, LilvNode* bundle_uri) { - plugin->bundle_uri = bundle_uri; - plugin->binary_uri = NULL; + plugin->bundle_uri = bundle_uri; + plugin->binary_uri = NULL; #ifdef LILV_DYN_MANIFEST - plugin->dynmanifest = NULL; + plugin->dynmanifest = NULL; #endif - plugin->plugin_class = NULL; - plugin->data_uris = lilv_nodes_new(); - plugin->ports = NULL; - plugin->num_ports = 0; - plugin->loaded = false; - plugin->parse_errors = false; - plugin->replaced = false; + plugin->plugin_class = NULL; + plugin->data_uris = lilv_nodes_new(); + plugin->ports = NULL; + plugin->num_ports = 0; + plugin->loaded = false; + plugin->parse_errors = false; + plugin->replaced = false; } /** Ownership of `uri` and `bundle` is taken */ LilvPlugin* lilv_plugin_new(LilvWorld* world, LilvNode* uri, LilvNode* bundle_uri) { - LilvPlugin* plugin = (LilvPlugin*)malloc(sizeof(LilvPlugin)); + LilvPlugin* plugin = (LilvPlugin*)malloc(sizeof(LilvPlugin)); - plugin->world = world; - plugin->plugin_uri = uri; + plugin->world = world; + plugin->plugin_uri = uri; - lilv_plugin_init(plugin, bundle_uri); - return plugin; + lilv_plugin_init(plugin, bundle_uri); + return plugin; } void lilv_plugin_clear(LilvPlugin* plugin, LilvNode* bundle_uri) { - lilv_node_free(plugin->bundle_uri); - lilv_node_free(plugin->binary_uri); - lilv_nodes_free(plugin->data_uris); - lilv_plugin_init(plugin, bundle_uri); + lilv_node_free(plugin->bundle_uri); + lilv_node_free(plugin->binary_uri); + lilv_nodes_free(plugin->data_uris); + lilv_plugin_init(plugin, bundle_uri); } static void lilv_plugin_free_ports(LilvPlugin* plugin) { - if (plugin->ports) { - for (uint32_t i = 0; i < plugin->num_ports; ++i) { - lilv_port_free(plugin, plugin->ports[i]); - } - free(plugin->ports); - plugin->num_ports = 0; - plugin->ports = NULL; - } + if (plugin->ports) { + for (uint32_t i = 0; i < plugin->num_ports; ++i) { + lilv_port_free(plugin, plugin->ports[i]); + } + free(plugin->ports); + plugin->num_ports = 0; + plugin->ports = NULL; + } } void lilv_plugin_free(LilvPlugin* plugin) { #ifdef LILV_DYN_MANIFEST - if (plugin->dynmanifest && --plugin->dynmanifest->refs == 0) { - lilv_dynmanifest_free(plugin->dynmanifest); - } + if (plugin->dynmanifest && --plugin->dynmanifest->refs == 0) { + lilv_dynmanifest_free(plugin->dynmanifest); + } #endif - lilv_node_free(plugin->plugin_uri); - plugin->plugin_uri = NULL; + lilv_node_free(plugin->plugin_uri); + plugin->plugin_uri = NULL; - lilv_node_free(plugin->bundle_uri); - plugin->bundle_uri = NULL; + lilv_node_free(plugin->bundle_uri); + plugin->bundle_uri = NULL; - lilv_node_free(plugin->binary_uri); - plugin->binary_uri = NULL; + lilv_node_free(plugin->binary_uri); + plugin->binary_uri = NULL; - lilv_plugin_free_ports(plugin); + lilv_plugin_free_ports(plugin); - lilv_nodes_free(plugin->data_uris); - plugin->data_uris = NULL; + lilv_nodes_free(plugin->data_uris); + plugin->data_uris = NULL; - free(plugin); + free(plugin); } static LilvNode* @@ -122,22 +122,22 @@ lilv_plugin_get_one(const LilvPlugin* plugin, const SordNode* subject, const SordNode* predicate) { - /* TODO: This is slower than it could be in some cases, but it's simpler to - use the existing i18n code. */ + /* TODO: This is slower than it could be in some cases, but it's simpler to + use the existing i18n code. */ - SordIter* stream = - lilv_world_query_internal(plugin->world, subject, predicate, NULL); + SordIter* stream = + lilv_world_query_internal(plugin->world, subject, predicate, NULL); - LilvNodes* nodes = lilv_nodes_from_stream_objects( - plugin->world, stream, SORD_OBJECT); + LilvNodes* nodes = + lilv_nodes_from_stream_objects(plugin->world, stream, SORD_OBJECT); - if (nodes) { - LilvNode* value = lilv_node_duplicate(lilv_nodes_get_first(nodes)); - lilv_nodes_free(nodes); - return value; - } + if (nodes) { + LilvNode* value = lilv_node_duplicate(lilv_nodes_get_first(nodes)); + lilv_nodes_free(nodes); + return value; + } - return NULL; + return NULL; } LilvNode* @@ -145,394 +145,391 @@ lilv_plugin_get_unique(const LilvPlugin* plugin, const SordNode* subject, const SordNode* predicate) { - LilvNode* ret = lilv_plugin_get_one(plugin, subject, predicate); - if (!ret) { - LILV_ERRORF("No value found for (%s %s ...) property\n", - sord_node_get_string(subject), - sord_node_get_string(predicate)); - } - return ret; + LilvNode* ret = lilv_plugin_get_one(plugin, subject, predicate); + if (!ret) { + LILV_ERRORF("No value found for (%s %s ...) property\n", + sord_node_get_string(subject), + sord_node_get_string(predicate)); + } + return ret; } static void lilv_plugin_load(LilvPlugin* plugin) { - SordNode* bundle_uri_node = plugin->bundle_uri->node; - const SerdNode* bundle_uri_snode = sord_node_to_serd_node(bundle_uri_node); - - SerdEnv* env = serd_env_new(bundle_uri_snode); - SerdReader* reader = sord_new_reader(plugin->world->model, env, SERD_TURTLE, - bundle_uri_node); - - SordModel* prots = lilv_world_filter_model( - plugin->world, - plugin->world->model, - plugin->plugin_uri->node, - plugin->world->uris.lv2_prototype, - NULL, NULL); - SordModel* skel = sord_new(plugin->world->world, SORD_SPO, false); - SordIter* iter = sord_begin(prots); - for (; !sord_iter_end(iter); sord_iter_next(iter)) { - const SordNode* t = sord_iter_get_node(iter, SORD_OBJECT); - LilvNode* prototype = lilv_node_new_from_node(plugin->world, t); - - lilv_world_load_resource(plugin->world, prototype); - - SordIter* statements = sord_search( - plugin->world->model, prototype->node, NULL, NULL, NULL); - FOREACH_MATCH(statements) { - SordQuad quad; - sord_iter_get(statements, quad); - quad[0] = plugin->plugin_uri->node; - sord_add(skel, quad); - } - - sord_iter_free(statements); - lilv_node_free(prototype); - } - sord_iter_free(iter); - - for (iter = sord_begin(skel); !sord_iter_end(iter); sord_iter_next(iter)) { - SordQuad quad; - sord_iter_get(iter, quad); - sord_add(plugin->world->model, quad); - } - sord_iter_free(iter); - sord_free(skel); - sord_free(prots); - - // Parse all the plugin's data files into RDF model - SerdStatus st = SERD_SUCCESS; - LILV_FOREACH(nodes, i, plugin->data_uris) { - const LilvNode* data_uri = lilv_nodes_get(plugin->data_uris, i); - - serd_env_set_base_uri(env, sord_node_to_serd_node(data_uri->node)); - st = lilv_world_load_file(plugin->world, reader, data_uri); - if (st > SERD_FAILURE) { - break; - } - } - - if (st > SERD_FAILURE) { - plugin->loaded = true; - plugin->parse_errors = true; - serd_reader_free(reader); - serd_env_free(env); - return; - } + SordNode* bundle_uri_node = plugin->bundle_uri->node; + const SerdNode* bundle_uri_snode = sord_node_to_serd_node(bundle_uri_node); + + SerdEnv* env = serd_env_new(bundle_uri_snode); + SerdReader* reader = + sord_new_reader(plugin->world->model, env, SERD_TURTLE, bundle_uri_node); + + SordModel* prots = lilv_world_filter_model(plugin->world, + plugin->world->model, + plugin->plugin_uri->node, + plugin->world->uris.lv2_prototype, + NULL, + NULL); + SordModel* skel = sord_new(plugin->world->world, SORD_SPO, false); + SordIter* iter = sord_begin(prots); + for (; !sord_iter_end(iter); sord_iter_next(iter)) { + const SordNode* t = sord_iter_get_node(iter, SORD_OBJECT); + LilvNode* prototype = lilv_node_new_from_node(plugin->world, t); + + lilv_world_load_resource(plugin->world, prototype); + + SordIter* statements = + sord_search(plugin->world->model, prototype->node, NULL, NULL, NULL); + FOREACH_MATCH (statements) { + SordQuad quad; + sord_iter_get(statements, quad); + quad[0] = plugin->plugin_uri->node; + sord_add(skel, quad); + } + + sord_iter_free(statements); + lilv_node_free(prototype); + } + sord_iter_free(iter); + + for (iter = sord_begin(skel); !sord_iter_end(iter); sord_iter_next(iter)) { + SordQuad quad; + sord_iter_get(iter, quad); + sord_add(plugin->world->model, quad); + } + sord_iter_free(iter); + sord_free(skel); + sord_free(prots); + + // Parse all the plugin's data files into RDF model + SerdStatus st = SERD_SUCCESS; + LILV_FOREACH (nodes, i, plugin->data_uris) { + const LilvNode* data_uri = lilv_nodes_get(plugin->data_uris, i); + + serd_env_set_base_uri(env, sord_node_to_serd_node(data_uri->node)); + st = lilv_world_load_file(plugin->world, reader, data_uri); + if (st > SERD_FAILURE) { + break; + } + } + + if (st > SERD_FAILURE) { + plugin->loaded = true; + plugin->parse_errors = true; + serd_reader_free(reader); + serd_env_free(env); + return; + } #ifdef LILV_DYN_MANIFEST - // Load and parse dynamic manifest data, if this is a library - if (plugin->dynmanifest) { - typedef int (*GetDataFunc)(LV2_Dyn_Manifest_Handle handle, - FILE* fp, - const char* uri); - GetDataFunc get_data_func = (GetDataFunc)lilv_dlfunc( - plugin->dynmanifest->lib, "lv2_dyn_manifest_get_data"); - if (get_data_func) { - const SordNode* bundle = plugin->dynmanifest->bundle->node; - serd_env_set_base_uri(env, sord_node_to_serd_node(bundle)); - FILE* fd = tmpfile(); - get_data_func(plugin->dynmanifest->handle, fd, - lilv_node_as_string(plugin->plugin_uri)); - rewind(fd); - serd_reader_add_blank_prefix( - reader, lilv_world_blank_node_prefix(plugin->world)); - serd_reader_read_file_handle( - reader, fd, (const uint8_t*)"(dyn-manifest)"); - fclose(fd); - } - } + // Load and parse dynamic manifest data, if this is a library + if (plugin->dynmanifest) { + typedef int (*GetDataFunc)( + LV2_Dyn_Manifest_Handle handle, FILE * fp, const char* uri); + GetDataFunc get_data_func = (GetDataFunc)lilv_dlfunc( + plugin->dynmanifest->lib, "lv2_dyn_manifest_get_data"); + if (get_data_func) { + const SordNode* bundle = plugin->dynmanifest->bundle->node; + serd_env_set_base_uri(env, sord_node_to_serd_node(bundle)); + FILE* fd = tmpfile(); + get_data_func(plugin->dynmanifest->handle, + fd, + lilv_node_as_string(plugin->plugin_uri)); + rewind(fd); + serd_reader_add_blank_prefix(reader, + lilv_world_blank_node_prefix(plugin->world)); + serd_reader_read_file_handle( + reader, fd, (const uint8_t*)"(dyn-manifest)"); + fclose(fd); + } + } #endif - serd_reader_free(reader); - serd_env_free(env); + serd_reader_free(reader); + serd_env_free(env); - plugin->loaded = true; + plugin->loaded = true; } static bool is_symbol(const char* str) { - for (const char* s = str; *s; ++s) { - if (!((*s >= 'a' && *s <= 'z') || - (*s >= 'A' && *s <= 'Z') || - (s > str && *s >= '0' && *s <= '9') || - *s == '_')) { - return false; - } - } - return true; + for (const char* s = str; *s; ++s) { + if (!((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') || + (s > str && *s >= '0' && *s <= '9') || *s == '_')) { + return false; + } + } + return true; } static void lilv_plugin_load_ports_if_necessary(const LilvPlugin* const_plugin) { - LilvPlugin* plugin = (LilvPlugin*)const_plugin; - - lilv_plugin_load_if_necessary(plugin); - - if (!plugin->ports) { - plugin->ports = (LilvPort**)malloc(sizeof(LilvPort*)); - plugin->ports[0] = NULL; - - SordIter* ports = lilv_world_query_internal( - plugin->world, - plugin->plugin_uri->node, - plugin->world->uris.lv2_port, - NULL); - - FOREACH_MATCH(ports) { - const SordNode* port = sord_iter_get_node(ports, SORD_OBJECT); - LilvNode* index = lilv_plugin_get_unique( - plugin, port, plugin->world->uris.lv2_index); - LilvNode* symbol = lilv_plugin_get_unique( - plugin, port, plugin->world->uris.lv2_symbol); - - if (!lilv_node_is_string(symbol) || - !is_symbol((const char*)sord_node_get_string(symbol->node))) { - LILV_ERRORF("Plugin <%s> port symbol `%s' is invalid\n", - lilv_node_as_uri(plugin->plugin_uri), - lilv_node_as_string(symbol)); - lilv_node_free(symbol); - lilv_node_free(index); - lilv_plugin_free_ports(plugin); - break; - } - - if (!lilv_node_is_int(index)) { - LILV_ERRORF("Plugin <%s> port index is not an integer\n", - lilv_node_as_uri(plugin->plugin_uri)); - lilv_node_free(symbol); - lilv_node_free(index); - lilv_plugin_free_ports(plugin); - break; - } - - uint32_t this_index = lilv_node_as_int(index); - LilvPort* this_port = NULL; - if (plugin->num_ports > this_index) { - this_port = plugin->ports[this_index]; - } else { - plugin->ports = (LilvPort**)realloc( - plugin->ports, (this_index + 1) * sizeof(LilvPort*)); - memset(plugin->ports + plugin->num_ports, '\0', - (this_index - plugin->num_ports) * sizeof(LilvPort*)); - plugin->num_ports = this_index + 1; - } - - // Havn't seen this port yet, add it to array - if (!this_port) { - this_port = lilv_port_new(plugin->world, - port, - this_index, - lilv_node_as_string(symbol)); - plugin->ports[this_index] = this_port; - } - - SordIter* types = lilv_world_query_internal( - plugin->world, port, plugin->world->uris.rdf_a, NULL); - FOREACH_MATCH(types) { - const SordNode* type = sord_iter_get_node(types, SORD_OBJECT); - if (sord_node_get_type(type) == SORD_URI) { - zix_tree_insert( - (ZixTree*)this_port->classes, - lilv_node_new_from_node(plugin->world, type), NULL); - } else { - LILV_WARNF("Plugin <%s> port type is not a URI\n", - lilv_node_as_uri(plugin->plugin_uri)); - } - } - sord_iter_free(types); - - lilv_node_free(symbol); - lilv_node_free(index); - } - sord_iter_free(ports); - - // Check sanity - for (uint32_t i = 0; i < plugin->num_ports; ++i) { - if (!plugin->ports[i]) { - LILV_ERRORF("Plugin <%s> is missing port %u/%u\n", - lilv_node_as_uri(plugin->plugin_uri), i, plugin->num_ports); - lilv_plugin_free_ports(plugin); - break; - } - } - } + LilvPlugin* plugin = (LilvPlugin*)const_plugin; + + lilv_plugin_load_if_necessary(plugin); + + if (!plugin->ports) { + plugin->ports = (LilvPort**)malloc(sizeof(LilvPort*)); + plugin->ports[0] = NULL; + + SordIter* ports = lilv_world_query_internal(plugin->world, + plugin->plugin_uri->node, + plugin->world->uris.lv2_port, + NULL); + + FOREACH_MATCH (ports) { + const SordNode* port = sord_iter_get_node(ports, SORD_OBJECT); + + LilvNode* index = + lilv_plugin_get_unique(plugin, port, plugin->world->uris.lv2_index); + + LilvNode* symbol = + lilv_plugin_get_unique(plugin, port, plugin->world->uris.lv2_symbol); + + if (!lilv_node_is_string(symbol) || + !is_symbol((const char*)sord_node_get_string(symbol->node))) { + LILV_ERRORF("Plugin <%s> port symbol `%s' is invalid\n", + lilv_node_as_uri(plugin->plugin_uri), + lilv_node_as_string(symbol)); + lilv_node_free(symbol); + lilv_node_free(index); + lilv_plugin_free_ports(plugin); + break; + } + + if (!lilv_node_is_int(index)) { + LILV_ERRORF("Plugin <%s> port index is not an integer\n", + lilv_node_as_uri(plugin->plugin_uri)); + lilv_node_free(symbol); + lilv_node_free(index); + lilv_plugin_free_ports(plugin); + break; + } + + uint32_t this_index = lilv_node_as_int(index); + LilvPort* this_port = NULL; + if (plugin->num_ports > this_index) { + this_port = plugin->ports[this_index]; + } else { + plugin->ports = (LilvPort**)realloc( + plugin->ports, (this_index + 1) * sizeof(LilvPort*)); + memset(plugin->ports + plugin->num_ports, + '\0', + (this_index - plugin->num_ports) * sizeof(LilvPort*)); + plugin->num_ports = this_index + 1; + } + + // Havn't seen this port yet, add it to array + if (!this_port) { + this_port = lilv_port_new( + plugin->world, port, this_index, lilv_node_as_string(symbol)); + plugin->ports[this_index] = this_port; + } + + SordIter* types = lilv_world_query_internal( + plugin->world, port, plugin->world->uris.rdf_a, NULL); + FOREACH_MATCH (types) { + const SordNode* type = sord_iter_get_node(types, SORD_OBJECT); + if (sord_node_get_type(type) == SORD_URI) { + zix_tree_insert((ZixTree*)this_port->classes, + lilv_node_new_from_node(plugin->world, type), + NULL); + } else { + LILV_WARNF("Plugin <%s> port type is not a URI\n", + lilv_node_as_uri(plugin->plugin_uri)); + } + } + sord_iter_free(types); + + lilv_node_free(symbol); + lilv_node_free(index); + } + sord_iter_free(ports); + + // Check sanity + for (uint32_t i = 0; i < plugin->num_ports; ++i) { + if (!plugin->ports[i]) { + LILV_ERRORF("Plugin <%s> is missing port %u/%u\n", + lilv_node_as_uri(plugin->plugin_uri), + i, + plugin->num_ports); + lilv_plugin_free_ports(plugin); + break; + } + } + } } void lilv_plugin_load_if_necessary(const LilvPlugin* plugin) { - if (!plugin->loaded) { - lilv_plugin_load((LilvPlugin*)plugin); - } + if (!plugin->loaded) { + lilv_plugin_load((LilvPlugin*)plugin); + } } const LilvNode* lilv_plugin_get_uri(const LilvPlugin* plugin) { - return plugin->plugin_uri; + return plugin->plugin_uri; } const LilvNode* lilv_plugin_get_bundle_uri(const LilvPlugin* plugin) { - return plugin->bundle_uri; + return plugin->bundle_uri; } const LilvNode* lilv_plugin_get_library_uri(const LilvPlugin* plugin) { - lilv_plugin_load_if_necessary((LilvPlugin*)plugin); - if (!plugin->binary_uri) { - // <plugin> lv2:binary ?binary - SordIter* i = lilv_world_query_internal(plugin->world, - plugin->plugin_uri->node, - plugin->world->uris.lv2_binary, - NULL); - FOREACH_MATCH(i) { - const SordNode* binary_node = sord_iter_get_node(i, SORD_OBJECT); - if (sord_node_get_type(binary_node) == SORD_URI) { - ((LilvPlugin*)plugin)->binary_uri = - lilv_node_new_from_node(plugin->world, binary_node); - break; - } - } - sord_iter_free(i); - } - if (!plugin->binary_uri) { - LILV_WARNF("Plugin <%s> has no lv2:binary\n", - lilv_node_as_uri(lilv_plugin_get_uri(plugin))); - } - return plugin->binary_uri; + lilv_plugin_load_if_necessary((LilvPlugin*)plugin); + if (!plugin->binary_uri) { + // <plugin> lv2:binary ?binary + SordIter* i = lilv_world_query_internal(plugin->world, + plugin->plugin_uri->node, + plugin->world->uris.lv2_binary, + NULL); + FOREACH_MATCH (i) { + const SordNode* binary_node = sord_iter_get_node(i, SORD_OBJECT); + if (sord_node_get_type(binary_node) == SORD_URI) { + ((LilvPlugin*)plugin)->binary_uri = + lilv_node_new_from_node(plugin->world, binary_node); + break; + } + } + sord_iter_free(i); + } + if (!plugin->binary_uri) { + LILV_WARNF("Plugin <%s> has no lv2:binary\n", + lilv_node_as_uri(lilv_plugin_get_uri(plugin))); + } + return plugin->binary_uri; } const LilvNodes* lilv_plugin_get_data_uris(const LilvPlugin* plugin) { - return plugin->data_uris; + return plugin->data_uris; } const LilvPluginClass* lilv_plugin_get_class(const LilvPlugin* plugin) { - lilv_plugin_load_if_necessary((LilvPlugin*)plugin); - if (!plugin->plugin_class) { - // <plugin> a ?class - SordIter* c = lilv_world_query_internal(plugin->world, - plugin->plugin_uri->node, - plugin->world->uris.rdf_a, - NULL); - FOREACH_MATCH(c) { - const SordNode* class_node = sord_iter_get_node(c, SORD_OBJECT); - if (sord_node_get_type(class_node) != SORD_URI) { - continue; - } - - LilvNode* klass = lilv_node_new_from_node(plugin->world, class_node); - if (!lilv_node_equals(klass, plugin->world->lv2_plugin_class->uri)) { - const LilvPluginClass* pclass = lilv_plugin_classes_get_by_uri( - plugin->world->plugin_classes, klass); - - if (pclass) { - ((LilvPlugin*)plugin)->plugin_class = pclass; - lilv_node_free(klass); - break; - } - } - - lilv_node_free(klass); - } - sord_iter_free(c); - - if (plugin->plugin_class == NULL) { - ((LilvPlugin*)plugin)->plugin_class = - plugin->world->lv2_plugin_class; - } - } - return plugin->plugin_class; + lilv_plugin_load_if_necessary((LilvPlugin*)plugin); + if (!plugin->plugin_class) { + // <plugin> a ?class + SordIter* c = lilv_world_query_internal( + plugin->world, plugin->plugin_uri->node, plugin->world->uris.rdf_a, NULL); + FOREACH_MATCH (c) { + const SordNode* class_node = sord_iter_get_node(c, SORD_OBJECT); + if (sord_node_get_type(class_node) != SORD_URI) { + continue; + } + + LilvNode* klass = lilv_node_new_from_node(plugin->world, class_node); + if (!lilv_node_equals(klass, plugin->world->lv2_plugin_class->uri)) { + const LilvPluginClass* pclass = + lilv_plugin_classes_get_by_uri(plugin->world->plugin_classes, klass); + + if (pclass) { + ((LilvPlugin*)plugin)->plugin_class = pclass; + lilv_node_free(klass); + break; + } + } + + lilv_node_free(klass); + } + sord_iter_free(c); + + if (plugin->plugin_class == NULL) { + ((LilvPlugin*)plugin)->plugin_class = plugin->world->lv2_plugin_class; + } + } + return plugin->plugin_class; } static LilvNodes* lilv_plugin_get_value_internal(const LilvPlugin* plugin, const SordNode* predicate) { - lilv_plugin_load_if_necessary(plugin); - return lilv_world_find_nodes_internal( - plugin->world, plugin->plugin_uri->node, predicate, NULL); + lilv_plugin_load_if_necessary(plugin); + return lilv_world_find_nodes_internal( + plugin->world, plugin->plugin_uri->node, predicate, NULL); } bool lilv_plugin_verify(const LilvPlugin* plugin) { - lilv_plugin_load_if_necessary(plugin); - if (plugin->parse_errors) { - return false; - } - - LilvNode* rdf_type = lilv_new_uri(plugin->world, LILV_NS_RDF "type"); - LilvNodes* results = lilv_plugin_get_value(plugin, rdf_type); - lilv_node_free(rdf_type); - if (!results) { - return false; - } - - lilv_nodes_free(results); - results = lilv_plugin_get_value_internal(plugin, - plugin->world->uris.doap_name); - if (!results) { - return false; - } - - lilv_nodes_free(results); - LilvNode* lv2_port = lilv_new_uri(plugin->world, LV2_CORE__port); - results = lilv_plugin_get_value(plugin, lv2_port); - lilv_node_free(lv2_port); - if (!results) { - return false; - } - - lilv_nodes_free(results); - return true; + lilv_plugin_load_if_necessary(plugin); + if (plugin->parse_errors) { + return false; + } + + LilvNode* rdf_type = lilv_new_uri(plugin->world, LILV_NS_RDF "type"); + LilvNodes* results = lilv_plugin_get_value(plugin, rdf_type); + lilv_node_free(rdf_type); + if (!results) { + return false; + } + + lilv_nodes_free(results); + results = + lilv_plugin_get_value_internal(plugin, plugin->world->uris.doap_name); + if (!results) { + return false; + } + + lilv_nodes_free(results); + LilvNode* lv2_port = lilv_new_uri(plugin->world, LV2_CORE__port); + results = lilv_plugin_get_value(plugin, lv2_port); + lilv_node_free(lv2_port); + if (!results) { + return false; + } + + lilv_nodes_free(results); + return true; } LilvNode* lilv_plugin_get_name(const LilvPlugin* plugin) { - LilvNodes* results = lilv_plugin_get_value_internal( - plugin, plugin->world->uris.doap_name); - - LilvNode* ret = NULL; - if (results) { - LilvNode* val = lilv_nodes_get_first(results); - if (lilv_node_is_string(val)) { - ret = lilv_node_duplicate(val); - } - lilv_nodes_free(results); - } - - if (!ret) { - LILV_WARNF("Plugin <%s> has no (mandatory) doap:name\n", - lilv_node_as_string(lilv_plugin_get_uri(plugin))); - } - - return ret; + LilvNodes* results = + lilv_plugin_get_value_internal(plugin, plugin->world->uris.doap_name); + + LilvNode* ret = NULL; + if (results) { + LilvNode* val = lilv_nodes_get_first(results); + if (lilv_node_is_string(val)) { + ret = lilv_node_duplicate(val); + } + lilv_nodes_free(results); + } + + if (!ret) { + LILV_WARNF("Plugin <%s> has no (mandatory) doap:name\n", + lilv_node_as_string(lilv_plugin_get_uri(plugin))); + } + + return ret; } LilvNodes* -lilv_plugin_get_value(const LilvPlugin* plugin, - const LilvNode* predicate) +lilv_plugin_get_value(const LilvPlugin* plugin, const LilvNode* predicate) { - lilv_plugin_load_if_necessary(plugin); - return lilv_world_find_nodes(plugin->world, plugin->plugin_uri, predicate, NULL); + lilv_plugin_load_if_necessary(plugin); + return lilv_world_find_nodes( + plugin->world, plugin->plugin_uri, predicate, NULL); } uint32_t lilv_plugin_get_num_ports(const LilvPlugin* plugin) { - lilv_plugin_load_ports_if_necessary(plugin); - return plugin->num_ports; + lilv_plugin_load_ports_if_necessary(plugin); + return plugin->num_ports; } void @@ -541,45 +538,45 @@ lilv_plugin_get_port_ranges_float(const LilvPlugin* plugin, float* max_values, float* def_values) { - lilv_plugin_load_ports_if_necessary(plugin); - LilvNode* min = NULL; - LilvNode* max = NULL; - LilvNode* def = NULL; - LilvNode** minptr = min_values ? &min : NULL; - LilvNode** maxptr = max_values ? &max : NULL; - LilvNode** defptr = def_values ? &def : NULL; - - for (uint32_t i = 0; i < plugin->num_ports; ++i) { - lilv_port_get_range(plugin, plugin->ports[i], defptr, minptr, maxptr); - - if (min_values) { - if (lilv_node_is_float(min) || lilv_node_is_int(min)) { - min_values[i] = lilv_node_as_float(min); - } else { - min_values[i] = NAN; - } - } - - if (max_values) { - if (lilv_node_is_float(max) || lilv_node_is_int(max)) { - max_values[i] = lilv_node_as_float(max); - } else { - max_values[i] = NAN; - } - } - - if (def_values) { - if (lilv_node_is_float(def) || lilv_node_is_int(def)) { - def_values[i] = lilv_node_as_float(def); - } else { - def_values[i] = NAN; - } - } - - lilv_node_free(def); - lilv_node_free(min); - lilv_node_free(max); - } + lilv_plugin_load_ports_if_necessary(plugin); + LilvNode* min = NULL; + LilvNode* max = NULL; + LilvNode* def = NULL; + LilvNode** minptr = min_values ? &min : NULL; + LilvNode** maxptr = max_values ? &max : NULL; + LilvNode** defptr = def_values ? &def : NULL; + + for (uint32_t i = 0; i < plugin->num_ports; ++i) { + lilv_port_get_range(plugin, plugin->ports[i], defptr, minptr, maxptr); + + if (min_values) { + if (lilv_node_is_float(min) || lilv_node_is_int(min)) { + min_values[i] = lilv_node_as_float(min); + } else { + min_values[i] = NAN; + } + } + + if (max_values) { + if (lilv_node_is_float(max) || lilv_node_is_int(max)) { + max_values[i] = lilv_node_as_float(max); + } else { + max_values[i] = NAN; + } + } + + if (def_values) { + if (lilv_node_is_float(def) || lilv_node_is_int(def)) { + def_values[i] = lilv_node_as_float(def); + } else { + def_values[i] = NAN; + } + } + + lilv_node_free(def); + lilv_node_free(min); + lilv_node_free(max); + } } uint32_t @@ -587,112 +584,115 @@ lilv_plugin_get_num_ports_of_class_va(const LilvPlugin* plugin, const LilvNode* class_1, va_list args) { - lilv_plugin_load_ports_if_necessary(plugin); - - uint32_t count = 0; - - // Build array of classes from args so we can walk it several times - size_t n_classes = 0; - const LilvNode** classes = NULL; - for (LilvNode* c = NULL; (c = va_arg(args, LilvNode*)); ) { - classes = (const LilvNode**)realloc( - classes, ++n_classes * sizeof(LilvNode*)); - classes[n_classes - 1] = c; - } - - // Check each port against every type - for (unsigned i = 0; i < plugin->num_ports; ++i) { - LilvPort* port = plugin->ports[i]; - if (port && lilv_port_is_a(plugin, port, class_1)) { - bool matches = true; - for (size_t j = 0; j < n_classes; ++j) { - if (!lilv_port_is_a(plugin, port, classes[j])) { - matches = false; - break; - } - } - - if (matches) { - ++count; - } - } - } - - free(classes); - return count; + lilv_plugin_load_ports_if_necessary(plugin); + + uint32_t count = 0; + + // Build array of classes from args so we can walk it several times + size_t n_classes = 0; + const LilvNode** classes = NULL; + for (LilvNode* c = NULL; (c = va_arg(args, LilvNode*));) { + classes = + (const LilvNode**)realloc(classes, ++n_classes * sizeof(LilvNode*)); + classes[n_classes - 1] = c; + } + + // Check each port against every type + for (unsigned i = 0; i < plugin->num_ports; ++i) { + LilvPort* port = plugin->ports[i]; + if (port && lilv_port_is_a(plugin, port, class_1)) { + bool matches = true; + for (size_t j = 0; j < n_classes; ++j) { + if (!lilv_port_is_a(plugin, port, classes[j])) { + matches = false; + break; + } + } + + if (matches) { + ++count; + } + } + } + + free(classes); + return count; } uint32_t lilv_plugin_get_num_ports_of_class(const LilvPlugin* plugin, - const LilvNode* class_1, ...) + const LilvNode* class_1, + ...) { - va_list args; - va_start(args, class_1); + va_list args; + va_start(args, class_1); - uint32_t count = lilv_plugin_get_num_ports_of_class_va(plugin, class_1, args); + uint32_t count = lilv_plugin_get_num_ports_of_class_va(plugin, class_1, args); - va_end(args); - return count; + va_end(args); + return count; } bool lilv_plugin_has_latency(const LilvPlugin* plugin) { - lilv_plugin_load_if_necessary(plugin); - SordIter* ports = lilv_world_query_internal( - plugin->world, - plugin->plugin_uri->node, - plugin->world->uris.lv2_port, - NULL); - - bool ret = false; - FOREACH_MATCH(ports) { - const SordNode* port = sord_iter_get_node(ports, SORD_OBJECT); - SordIter* prop = lilv_world_query_internal( - plugin->world, - port, - plugin->world->uris.lv2_portProperty, - plugin->world->uris.lv2_reportsLatency); - SordIter* des = lilv_world_query_internal( - plugin->world, - port, - plugin->world->uris.lv2_designation, - plugin->world->uris.lv2_latency); - const bool latent = !sord_iter_end(prop) || !sord_iter_end(des); - sord_iter_free(prop); - sord_iter_free(des); - if (latent) { - ret = true; - break; - } - } - sord_iter_free(ports); - - return ret; + lilv_plugin_load_if_necessary(plugin); + SordIter* ports = lilv_world_query_internal(plugin->world, + plugin->plugin_uri->node, + plugin->world->uris.lv2_port, + NULL); + + bool ret = false; + FOREACH_MATCH (ports) { + const SordNode* port = sord_iter_get_node(ports, SORD_OBJECT); + + SordIter* prop = + lilv_world_query_internal(plugin->world, + port, + plugin->world->uris.lv2_portProperty, + plugin->world->uris.lv2_reportsLatency); + + SordIter* des = + lilv_world_query_internal(plugin->world, + port, + plugin->world->uris.lv2_designation, + plugin->world->uris.lv2_latency); + + const bool latent = !sord_iter_end(prop) || !sord_iter_end(des); + sord_iter_free(prop); + sord_iter_free(des); + if (latent) { + ret = true; + break; + } + } + sord_iter_free(ports); + + return ret; } static const LilvPort* lilv_plugin_get_port_by_property(const LilvPlugin* plugin, const SordNode* port_property) { - lilv_plugin_load_ports_if_necessary(plugin); - for (uint32_t i = 0; i < plugin->num_ports; ++i) { - LilvPort* port = plugin->ports[i]; - SordIter* iter = lilv_world_query_internal( - plugin->world, - port->node->node, - plugin->world->uris.lv2_portProperty, - port_property); - - const bool found = !sord_iter_end(iter); - sord_iter_free(iter); - - if (found) { - return port; - } - } - - return NULL; + lilv_plugin_load_ports_if_necessary(plugin); + for (uint32_t i = 0; i < plugin->num_ports; ++i) { + LilvPort* port = plugin->ports[i]; + SordIter* iter = + lilv_world_query_internal(plugin->world, + port->node->node, + plugin->world->uris.lv2_portProperty, + port_property); + + const bool found = !sord_iter_end(iter); + sord_iter_free(iter); + + if (found) { + return port; + } + } + + return NULL; } const LilvPort* @@ -700,377 +700,353 @@ lilv_plugin_get_port_by_designation(const LilvPlugin* plugin, const LilvNode* port_class, const LilvNode* designation) { - LilvWorld* world = plugin->world; - lilv_plugin_load_ports_if_necessary(plugin); - for (uint32_t i = 0; i < plugin->num_ports; ++i) { - LilvPort* port = plugin->ports[i]; - SordIter* iter = lilv_world_query_internal( - world, - port->node->node, - world->uris.lv2_designation, - designation->node); - - const bool found = !sord_iter_end(iter) && - (!port_class || lilv_port_is_a(plugin, port, port_class)); - sord_iter_free(iter); - - if (found) { - return port; - } - } - - return NULL; + LilvWorld* world = plugin->world; + lilv_plugin_load_ports_if_necessary(plugin); + for (uint32_t i = 0; i < plugin->num_ports; ++i) { + LilvPort* port = plugin->ports[i]; + SordIter* iter = lilv_world_query_internal( + world, port->node->node, world->uris.lv2_designation, designation->node); + + const bool found = + !sord_iter_end(iter) && + (!port_class || lilv_port_is_a(plugin, port, port_class)); + sord_iter_free(iter); + + if (found) { + return port; + } + } + + return NULL; } uint32_t lilv_plugin_get_latency_port_index(const LilvPlugin* plugin) { - LilvNode* lv2_OutputPort = - lilv_new_uri(plugin->world, LV2_CORE__OutputPort); - LilvNode* lv2_latency = - lilv_new_uri(plugin->world, LV2_CORE__latency); + LilvNode* lv2_OutputPort = lilv_new_uri(plugin->world, LV2_CORE__OutputPort); + LilvNode* lv2_latency = lilv_new_uri(plugin->world, LV2_CORE__latency); - const LilvPort* prop_port = lilv_plugin_get_port_by_property( - plugin, plugin->world->uris.lv2_reportsLatency); - const LilvPort* des_port = lilv_plugin_get_port_by_designation( - plugin, lv2_OutputPort, lv2_latency); + const LilvPort* prop_port = lilv_plugin_get_port_by_property( + plugin, plugin->world->uris.lv2_reportsLatency); + const LilvPort* des_port = + lilv_plugin_get_port_by_designation(plugin, lv2_OutputPort, lv2_latency); - lilv_node_free(lv2_latency); - lilv_node_free(lv2_OutputPort); + lilv_node_free(lv2_latency); + lilv_node_free(lv2_OutputPort); - if (prop_port) { - return prop_port->index; - } + if (prop_port) { + return prop_port->index; + } - if (des_port) { - return des_port->index; - } + if (des_port) { + return des_port->index; + } - return (uint32_t)-1; + return (uint32_t)-1; } bool -lilv_plugin_has_feature(const LilvPlugin* plugin, - const LilvNode* feature) +lilv_plugin_has_feature(const LilvPlugin* plugin, const LilvNode* feature) { - lilv_plugin_load_if_necessary(plugin); - const SordNode* predicates[] = { plugin->world->uris.lv2_requiredFeature, - plugin->world->uris.lv2_optionalFeature, - NULL }; - - for (const SordNode** pred = predicates; *pred; ++pred) { - if (lilv_world_ask_internal( - plugin->world, plugin->plugin_uri->node, *pred, feature->node)) { - return true; - } - } - return false; + lilv_plugin_load_if_necessary(plugin); + const SordNode* predicates[] = {plugin->world->uris.lv2_requiredFeature, + plugin->world->uris.lv2_optionalFeature, + NULL}; + + for (const SordNode** pred = predicates; *pred; ++pred) { + if (lilv_world_ask_internal( + plugin->world, plugin->plugin_uri->node, *pred, feature->node)) { + return true; + } + } + return false; } LilvNodes* lilv_plugin_get_supported_features(const LilvPlugin* plugin) { - LilvNodes* optional = lilv_plugin_get_optional_features(plugin); - LilvNodes* required = lilv_plugin_get_required_features(plugin); - LilvNodes* result = lilv_nodes_merge(optional, required); - lilv_nodes_free(optional); - lilv_nodes_free(required); - return result; + LilvNodes* optional = lilv_plugin_get_optional_features(plugin); + LilvNodes* required = lilv_plugin_get_required_features(plugin); + LilvNodes* result = lilv_nodes_merge(optional, required); + lilv_nodes_free(optional); + lilv_nodes_free(required); + return result; } LilvNodes* lilv_plugin_get_optional_features(const LilvPlugin* plugin) { - lilv_plugin_load_if_necessary(plugin); - return lilv_world_find_nodes_internal(plugin->world, - plugin->plugin_uri->node, - plugin->world->uris.lv2_optionalFeature, - NULL); + lilv_plugin_load_if_necessary(plugin); + return lilv_world_find_nodes_internal(plugin->world, + plugin->plugin_uri->node, + plugin->world->uris.lv2_optionalFeature, + NULL); } LilvNodes* lilv_plugin_get_required_features(const LilvPlugin* plugin) { - lilv_plugin_load_if_necessary(plugin); - return lilv_world_find_nodes_internal(plugin->world, - plugin->plugin_uri->node, - plugin->world->uris.lv2_requiredFeature, - NULL); + lilv_plugin_load_if_necessary(plugin); + return lilv_world_find_nodes_internal(plugin->world, + plugin->plugin_uri->node, + plugin->world->uris.lv2_requiredFeature, + NULL); } bool -lilv_plugin_has_extension_data(const LilvPlugin* plugin, - const LilvNode* uri) +lilv_plugin_has_extension_data(const LilvPlugin* plugin, const LilvNode* uri) { - if (!lilv_node_is_uri(uri)) { - LILV_ERRORF("Extension data `%s' is not a URI\n", - sord_node_get_string(uri->node)); - return false; - } - - lilv_plugin_load_if_necessary(plugin); - return lilv_world_ask_internal( - plugin->world, - plugin->plugin_uri->node, - plugin->world->uris.lv2_extensionData, - uri->node); + if (!lilv_node_is_uri(uri)) { + LILV_ERRORF("Extension data `%s' is not a URI\n", + sord_node_get_string(uri->node)); + return false; + } + + lilv_plugin_load_if_necessary(plugin); + return lilv_world_ask_internal(plugin->world, + plugin->plugin_uri->node, + plugin->world->uris.lv2_extensionData, + uri->node); } LilvNodes* lilv_plugin_get_extension_data(const LilvPlugin* plugin) { - return lilv_plugin_get_value_internal(plugin, plugin->world->uris.lv2_extensionData); + return lilv_plugin_get_value_internal(plugin, + plugin->world->uris.lv2_extensionData); } const LilvPort* -lilv_plugin_get_port_by_index(const LilvPlugin* plugin, - uint32_t index) +lilv_plugin_get_port_by_index(const LilvPlugin* plugin, uint32_t index) { - lilv_plugin_load_ports_if_necessary(plugin); - if (index < plugin->num_ports) { - return plugin->ports[index]; - } + lilv_plugin_load_ports_if_necessary(plugin); + if (index < plugin->num_ports) { + return plugin->ports[index]; + } - return NULL; + return NULL; } const LilvPort* -lilv_plugin_get_port_by_symbol(const LilvPlugin* plugin, - const LilvNode* symbol) +lilv_plugin_get_port_by_symbol(const LilvPlugin* plugin, const LilvNode* symbol) { - lilv_plugin_load_ports_if_necessary(plugin); - for (uint32_t i = 0; i < plugin->num_ports; ++i) { - LilvPort* port = plugin->ports[i]; - if (lilv_node_equals(port->symbol, symbol)) { - return port; - } - } - - return NULL; + lilv_plugin_load_ports_if_necessary(plugin); + for (uint32_t i = 0; i < plugin->num_ports; ++i) { + LilvPort* port = plugin->ports[i]; + if (lilv_node_equals(port->symbol, symbol)) { + return port; + } + } + + return NULL; } LilvNode* lilv_plugin_get_project(const LilvPlugin* plugin) { - lilv_plugin_load_if_necessary(plugin); + lilv_plugin_load_if_necessary(plugin); - SordNode* lv2_project = sord_new_uri(plugin->world->world, - (const uint8_t*)LV2_CORE__project); + SordNode* lv2_project = + sord_new_uri(plugin->world->world, (const uint8_t*)LV2_CORE__project); - SordIter* projects = lilv_world_query_internal(plugin->world, - plugin->plugin_uri->node, - lv2_project, - NULL); + SordIter* projects = lilv_world_query_internal( + plugin->world, plugin->plugin_uri->node, lv2_project, NULL); - sord_node_free(plugin->world->world, lv2_project); + sord_node_free(plugin->world->world, lv2_project); - if (sord_iter_end(projects)) { - sord_iter_free(projects); - return NULL; - } + if (sord_iter_end(projects)) { + sord_iter_free(projects); + return NULL; + } - const SordNode* project = sord_iter_get_node(projects, SORD_OBJECT); + const SordNode* project = sord_iter_get_node(projects, SORD_OBJECT); - sord_iter_free(projects); - return lilv_node_new_from_node(plugin->world, project); + sord_iter_free(projects); + return lilv_node_new_from_node(plugin->world, project); } static const SordNode* lilv_plugin_get_author(const LilvPlugin* plugin) { - lilv_plugin_load_if_necessary(plugin); + lilv_plugin_load_if_necessary(plugin); - SordNode* doap_maintainer = sord_new_uri( - plugin->world->world, NS_DOAP "maintainer"); + SordNode* doap_maintainer = + sord_new_uri(plugin->world->world, NS_DOAP "maintainer"); - SordIter* maintainers = lilv_world_query_internal( - plugin->world, - plugin->plugin_uri->node, - doap_maintainer, - NULL); + SordIter* maintainers = lilv_world_query_internal( + plugin->world, plugin->plugin_uri->node, doap_maintainer, NULL); - if (sord_iter_end(maintainers)) { - sord_iter_free(maintainers); + if (sord_iter_end(maintainers)) { + sord_iter_free(maintainers); - LilvNode* project = lilv_plugin_get_project(plugin); - if (!project) { - sord_node_free(plugin->world->world, doap_maintainer); - return NULL; - } + LilvNode* project = lilv_plugin_get_project(plugin); + if (!project) { + sord_node_free(plugin->world->world, doap_maintainer); + return NULL; + } - maintainers = lilv_world_query_internal( - plugin->world, - project->node, - doap_maintainer, - NULL); + maintainers = lilv_world_query_internal( + plugin->world, project->node, doap_maintainer, NULL); - lilv_node_free(project); - } + lilv_node_free(project); + } - sord_node_free(plugin->world->world, doap_maintainer); + sord_node_free(plugin->world->world, doap_maintainer); - if (sord_iter_end(maintainers)) { - sord_iter_free(maintainers); - return NULL; - } + if (sord_iter_end(maintainers)) { + sord_iter_free(maintainers); + return NULL; + } - const SordNode* author = sord_iter_get_node(maintainers, SORD_OBJECT); + const SordNode* author = sord_iter_get_node(maintainers, SORD_OBJECT); - sord_iter_free(maintainers); - return author; + sord_iter_free(maintainers); + return author; } static LilvNode* lilv_plugin_get_author_property(const LilvPlugin* plugin, const uint8_t* uri) { - const SordNode* author = lilv_plugin_get_author(plugin); - if (author) { - SordWorld* sworld = plugin->world->world; - SordNode* pred = sord_new_uri(sworld, uri); - LilvNode* ret = lilv_plugin_get_one(plugin, author, pred); - sord_node_free(sworld, pred); - return ret; - } - return NULL; + const SordNode* author = lilv_plugin_get_author(plugin); + if (author) { + SordWorld* sworld = plugin->world->world; + SordNode* pred = sord_new_uri(sworld, uri); + LilvNode* ret = lilv_plugin_get_one(plugin, author, pred); + sord_node_free(sworld, pred); + return ret; + } + return NULL; } LilvNode* lilv_plugin_get_author_name(const LilvPlugin* plugin) { - return lilv_plugin_get_author_property(plugin, NS_FOAF "name"); + return lilv_plugin_get_author_property(plugin, NS_FOAF "name"); } LilvNode* lilv_plugin_get_author_email(const LilvPlugin* plugin) { - return lilv_plugin_get_author_property(plugin, NS_FOAF "mbox"); + return lilv_plugin_get_author_property(plugin, NS_FOAF "mbox"); } LilvNode* lilv_plugin_get_author_homepage(const LilvPlugin* plugin) { - return lilv_plugin_get_author_property(plugin, NS_FOAF "homepage"); + return lilv_plugin_get_author_property(plugin, NS_FOAF "homepage"); } bool lilv_plugin_is_replaced(const LilvPlugin* plugin) { - return plugin->replaced; + return plugin->replaced; } LilvUIs* lilv_plugin_get_uis(const LilvPlugin* plugin) { - lilv_plugin_load_if_necessary(plugin); - - SordNode* ui_ui_node = sord_new_uri(plugin->world->world, - (const uint8_t*)LV2_UI__ui); - SordNode* ui_binary_node = sord_new_uri(plugin->world->world, - (const uint8_t*)LV2_UI__binary); - - LilvUIs* result = lilv_uis_new(); - SordIter* uis = lilv_world_query_internal(plugin->world, - plugin->plugin_uri->node, - ui_ui_node, - NULL); - - FOREACH_MATCH(uis) { - const SordNode* ui = sord_iter_get_node(uis, SORD_OBJECT); - - LilvNode* type = lilv_plugin_get_unique(plugin, ui, plugin->world->uris.rdf_a); - LilvNode* binary = lilv_plugin_get_one(plugin, ui, plugin->world->uris.lv2_binary); - if (!binary) { - binary = lilv_plugin_get_unique(plugin, ui, ui_binary_node); - } - - if (sord_node_get_type(ui) != SORD_URI - || !lilv_node_is_uri(type) - || !lilv_node_is_uri(binary)) { - lilv_node_free(binary); - lilv_node_free(type); - LILV_ERRORF("Corrupt UI <%s>\n", sord_node_get_string(ui)); - continue; - } - - LilvUI* lilv_ui = lilv_ui_new( - plugin->world, - lilv_node_new_from_node(plugin->world, ui), - type, - binary); - - zix_tree_insert((ZixTree*)result, lilv_ui, NULL); - } - sord_iter_free(uis); - - sord_node_free(plugin->world->world, ui_binary_node); - sord_node_free(plugin->world->world, ui_ui_node); - - if (lilv_uis_size(result) > 0) { - return result; - } - - lilv_uis_free(result); - return NULL; + lilv_plugin_load_if_necessary(plugin); + + SordNode* ui_ui_node = + sord_new_uri(plugin->world->world, (const uint8_t*)LV2_UI__ui); + SordNode* ui_binary_node = + sord_new_uri(plugin->world->world, (const uint8_t*)LV2_UI__binary); + + LilvUIs* result = lilv_uis_new(); + SordIter* uis = lilv_world_query_internal( + plugin->world, plugin->plugin_uri->node, ui_ui_node, NULL); + + FOREACH_MATCH (uis) { + const SordNode* ui = sord_iter_get_node(uis, SORD_OBJECT); + + LilvNode* type = + lilv_plugin_get_unique(plugin, ui, plugin->world->uris.rdf_a); + LilvNode* binary = + lilv_plugin_get_one(plugin, ui, plugin->world->uris.lv2_binary); + if (!binary) { + binary = lilv_plugin_get_unique(plugin, ui, ui_binary_node); + } + + if (sord_node_get_type(ui) != SORD_URI || !lilv_node_is_uri(type) || + !lilv_node_is_uri(binary)) { + lilv_node_free(binary); + lilv_node_free(type); + LILV_ERRORF("Corrupt UI <%s>\n", sord_node_get_string(ui)); + continue; + } + + LilvUI* lilv_ui = lilv_ui_new( + plugin->world, lilv_node_new_from_node(plugin->world, ui), type, binary); + + zix_tree_insert((ZixTree*)result, lilv_ui, NULL); + } + sord_iter_free(uis); + + sord_node_free(plugin->world->world, ui_binary_node); + sord_node_free(plugin->world->world, ui_ui_node); + + if (lilv_uis_size(result) > 0) { + return result; + } + + lilv_uis_free(result); + return NULL; } LilvNodes* lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type) { - lilv_plugin_load_if_necessary(plugin); - - LilvWorld* const world = plugin->world; - LilvNodes* const related = lilv_world_find_nodes_internal( - world, - NULL, - world->uris.lv2_appliesTo, - lilv_plugin_get_uri(plugin)->node); - - if (!type) { - return related; - } - - LilvNodes* matches = lilv_nodes_new(); - LILV_FOREACH(nodes, i, related) { - LilvNode* node = (LilvNode*)lilv_collection_get((ZixTree*)related, i); - if (lilv_world_ask_internal( - world, node->node, world->uris.rdf_a, type->node)) { - zix_tree_insert((ZixTree*)matches, - lilv_node_new_from_node(world, node->node), - NULL); - } - } - - lilv_nodes_free(related); - return matches; + lilv_plugin_load_if_necessary(plugin); + + LilvWorld* const world = plugin->world; + LilvNodes* const related = lilv_world_find_nodes_internal( + world, NULL, world->uris.lv2_appliesTo, lilv_plugin_get_uri(plugin)->node); + + if (!type) { + return related; + } + + LilvNodes* matches = lilv_nodes_new(); + LILV_FOREACH (nodes, i, related) { + LilvNode* node = (LilvNode*)lilv_collection_get((ZixTree*)related, i); + if (lilv_world_ask_internal( + world, node->node, world->uris.rdf_a, type->node)) { + zix_tree_insert( + (ZixTree*)matches, lilv_node_new_from_node(world, node->node), NULL); + } + } + + lilv_nodes_free(related); + return matches; } static SerdEnv* new_lv2_env(const SerdNode* base) { - SerdEnv* env = serd_env_new(base); + SerdEnv* env = serd_env_new(base); #define USTR(s) ((const uint8_t*)(s)) - serd_env_set_prefix_from_strings(env, USTR("doap"), USTR(LILV_NS_DOAP)); - serd_env_set_prefix_from_strings(env, USTR("foaf"), USTR(LILV_NS_FOAF)); - serd_env_set_prefix_from_strings(env, USTR("lv2"), USTR(LILV_NS_LV2)); - serd_env_set_prefix_from_strings(env, USTR("owl"), USTR(LILV_NS_OWL)); - serd_env_set_prefix_from_strings(env, USTR("rdf"), USTR(LILV_NS_RDF)); - serd_env_set_prefix_from_strings(env, USTR("rdfs"), USTR(LILV_NS_RDFS)); - serd_env_set_prefix_from_strings(env, USTR("xsd"), USTR(LILV_NS_XSD)); - - return env; + + serd_env_set_prefix_from_strings(env, USTR("doap"), USTR(LILV_NS_DOAP)); + serd_env_set_prefix_from_strings(env, USTR("foaf"), USTR(LILV_NS_FOAF)); + serd_env_set_prefix_from_strings(env, USTR("lv2"), USTR(LILV_NS_LV2)); + serd_env_set_prefix_from_strings(env, USTR("owl"), USTR(LILV_NS_OWL)); + serd_env_set_prefix_from_strings(env, USTR("rdf"), USTR(LILV_NS_RDF)); + serd_env_set_prefix_from_strings(env, USTR("rdfs"), USTR(LILV_NS_RDFS)); + serd_env_set_prefix_from_strings(env, USTR("xsd"), USTR(LILV_NS_XSD)); + + return env; } static void maybe_write_prefixes(SerdWriter* writer, SerdEnv* env, FILE* file) { - fseek(file, 0, SEEK_END); - if (ftell(file) == 0) { - serd_env_foreach( - env, (SerdPrefixSink)serd_writer_set_prefix, writer); - } else { - fprintf(file, "\n"); - } + fseek(file, 0, SEEK_END); + if (ftell(file) == 0) { + serd_env_foreach(env, (SerdPrefixSink)serd_writer_set_prefix, writer); + } else { + fprintf(file, "\n"); + } } void @@ -1079,37 +1055,37 @@ lilv_plugin_write_description(LilvWorld* world, const LilvNode* base_uri, FILE* plugin_file) { - const LilvNode* subject = lilv_plugin_get_uri(plugin); - const uint32_t num_ports = lilv_plugin_get_num_ports(plugin); - const SerdNode* base = sord_node_to_serd_node(base_uri->node); - SerdEnv* env = new_lv2_env(base); - - SerdWriter* writer = serd_writer_new( - SERD_TURTLE, - (SerdStyle)(SERD_STYLE_ABBREVIATED|SERD_STYLE_CURIED), - env, - NULL, - serd_file_sink, - plugin_file); - - // Write prefixes if this is a new file - maybe_write_prefixes(writer, env, plugin_file); - - // Write plugin description - SordIter* plug_iter = lilv_world_query_internal( - world, subject->node, NULL, NULL); - sord_write_iter(plug_iter, writer); - - // Write port descriptions - for (uint32_t i = 0; i < num_ports; ++i) { - const LilvPort* port = plugin->ports[i]; - SordIter* port_iter = lilv_world_query_internal( - world, port->node->node, NULL, NULL); - sord_write_iter(port_iter, writer); - } - - serd_writer_free(writer); - serd_env_free(env); + const LilvNode* subject = lilv_plugin_get_uri(plugin); + const uint32_t num_ports = lilv_plugin_get_num_ports(plugin); + const SerdNode* base = sord_node_to_serd_node(base_uri->node); + SerdEnv* env = new_lv2_env(base); + + SerdWriter* writer = + serd_writer_new(SERD_TURTLE, + (SerdStyle)(SERD_STYLE_ABBREVIATED | SERD_STYLE_CURIED), + env, + NULL, + serd_file_sink, + plugin_file); + + // Write prefixes if this is a new file + maybe_write_prefixes(writer, env, plugin_file); + + // Write plugin description + SordIter* plug_iter = + lilv_world_query_internal(world, subject->node, NULL, NULL); + sord_write_iter(plug_iter, writer); + + // Write port descriptions + for (uint32_t i = 0; i < num_ports; ++i) { + const LilvPort* port = plugin->ports[i]; + SordIter* port_iter = + lilv_world_query_internal(world, port->node->node, NULL, NULL); + sord_write_iter(port_iter, writer); + } + + serd_writer_free(writer); + serd_env_free(env); } void @@ -1119,36 +1095,44 @@ lilv_plugin_write_manifest_entry(LilvWorld* world, FILE* manifest_file, const char* plugin_file_path) { - const LilvNode* subject = lilv_plugin_get_uri(plugin); - const SerdNode* base = sord_node_to_serd_node(base_uri->node); - SerdEnv* env = new_lv2_env(base); - - SerdWriter* writer = serd_writer_new( - SERD_TURTLE, - (SerdStyle)(SERD_STYLE_ABBREVIATED|SERD_STYLE_CURIED), - env, - NULL, - serd_file_sink, - manifest_file); - - // Write prefixes if this is a new file - maybe_write_prefixes(writer, env, manifest_file); - - // Write manifest entry - serd_writer_write_statement( - writer, 0, NULL, - sord_node_to_serd_node(subject->node), - sord_node_to_serd_node(plugin->world->uris.rdf_a), - sord_node_to_serd_node(plugin->world->uris.lv2_Plugin), 0, 0); - - const SerdNode file_node = serd_node_from_string( - SERD_URI, (const uint8_t*)plugin_file_path); - serd_writer_write_statement( - writer, 0, NULL, - sord_node_to_serd_node(subject->node), - sord_node_to_serd_node(plugin->world->uris.rdfs_seeAlso), - &file_node, 0, 0); - - serd_writer_free(writer); - serd_env_free(env); + const LilvNode* subject = lilv_plugin_get_uri(plugin); + const SerdNode* base = sord_node_to_serd_node(base_uri->node); + SerdEnv* env = new_lv2_env(base); + + SerdWriter* writer = + serd_writer_new(SERD_TURTLE, + (SerdStyle)(SERD_STYLE_ABBREVIATED | SERD_STYLE_CURIED), + env, + NULL, + serd_file_sink, + manifest_file); + + // Write prefixes if this is a new file + maybe_write_prefixes(writer, env, manifest_file); + + // Write manifest entry + serd_writer_write_statement( + writer, + 0, + NULL, + sord_node_to_serd_node(subject->node), + sord_node_to_serd_node(plugin->world->uris.rdf_a), + sord_node_to_serd_node(plugin->world->uris.lv2_Plugin), + 0, + 0); + + const SerdNode file_node = + serd_node_from_string(SERD_URI, (const uint8_t*)plugin_file_path); + serd_writer_write_statement( + writer, + 0, + NULL, + sord_node_to_serd_node(subject->node), + sord_node_to_serd_node(plugin->world->uris.rdfs_seeAlso), + &file_node, + 0, + 0); + + serd_writer_free(writer); + serd_env_free(env); } diff --git a/src/pluginclass.c b/src/pluginclass.c index 538722f..546b53b 100644 --- a/src/pluginclass.c +++ b/src/pluginclass.c @@ -29,64 +29,63 @@ lilv_plugin_class_new(LilvWorld* world, const SordNode* uri, const char* label) { - LilvPluginClass* pc = (LilvPluginClass*)malloc(sizeof(LilvPluginClass)); - pc->world = world; - pc->uri = lilv_node_new_from_node(world, uri); - pc->label = lilv_node_new(world, LILV_VALUE_STRING, label); - pc->parent_uri = (parent_node - ? lilv_node_new_from_node(world, parent_node) - : NULL); - return pc; + LilvPluginClass* pc = (LilvPluginClass*)malloc(sizeof(LilvPluginClass)); + pc->world = world; + pc->uri = lilv_node_new_from_node(world, uri); + pc->label = lilv_node_new(world, LILV_VALUE_STRING, label); + pc->parent_uri = + (parent_node ? lilv_node_new_from_node(world, parent_node) : NULL); + return pc; } void lilv_plugin_class_free(LilvPluginClass* plugin_class) { - if (!plugin_class) { - return; - } + if (!plugin_class) { + return; + } - lilv_node_free(plugin_class->uri); - lilv_node_free(plugin_class->parent_uri); - lilv_node_free(plugin_class->label); - free(plugin_class); + lilv_node_free(plugin_class->uri); + lilv_node_free(plugin_class->parent_uri); + lilv_node_free(plugin_class->label); + free(plugin_class); } const LilvNode* lilv_plugin_class_get_parent_uri(const LilvPluginClass* plugin_class) { - return plugin_class->parent_uri ? plugin_class->parent_uri : NULL; + return plugin_class->parent_uri ? plugin_class->parent_uri : NULL; } const LilvNode* lilv_plugin_class_get_uri(const LilvPluginClass* plugin_class) { - return plugin_class->uri; + return plugin_class->uri; } const LilvNode* lilv_plugin_class_get_label(const LilvPluginClass* plugin_class) { - return plugin_class->label; + return plugin_class->label; } LilvPluginClasses* lilv_plugin_class_get_children(const LilvPluginClass* plugin_class) { - // Returned list doesn't own categories - LilvPluginClasses* all = plugin_class->world->plugin_classes; - LilvPluginClasses* result = zix_tree_new(false, lilv_ptr_cmp, NULL, NULL); + // Returned list doesn't own categories + LilvPluginClasses* all = plugin_class->world->plugin_classes; + LilvPluginClasses* result = zix_tree_new(false, lilv_ptr_cmp, NULL, NULL); - for (ZixTreeIter* i = zix_tree_begin((ZixTree*)all); - i != zix_tree_end((ZixTree*)all); - i = zix_tree_iter_next(i)) { - const LilvPluginClass* c = (LilvPluginClass*)zix_tree_get(i); - const LilvNode* parent = lilv_plugin_class_get_parent_uri(c); - if (parent && lilv_node_equals(lilv_plugin_class_get_uri(plugin_class), - parent)) { - zix_tree_insert((ZixTree*)result, (LilvPluginClass*)c, NULL); - } - } + for (ZixTreeIter* i = zix_tree_begin((ZixTree*)all); + i != zix_tree_end((ZixTree*)all); + i = zix_tree_iter_next(i)) { + const LilvPluginClass* c = (LilvPluginClass*)zix_tree_get(i); + const LilvNode* parent = lilv_plugin_class_get_parent_uri(c); + if (parent && + lilv_node_equals(lilv_plugin_class_get_uri(plugin_class), parent)) { + zix_tree_insert((ZixTree*)result, (LilvPluginClass*)c, NULL); + } + } - return result; + return result; } @@ -36,23 +36,23 @@ lilv_port_new(LilvWorld* world, uint32_t index, const char* symbol) { - LilvPort* port = (LilvPort*)malloc(sizeof(LilvPort)); - port->node = lilv_node_new_from_node(world, node); - port->index = index; - port->symbol = lilv_node_new(world, LILV_VALUE_STRING, symbol); - port->classes = lilv_nodes_new(); - return port; + LilvPort* port = (LilvPort*)malloc(sizeof(LilvPort)); + port->node = lilv_node_new_from_node(world, node); + port->index = index; + port->symbol = lilv_node_new(world, LILV_VALUE_STRING, symbol); + port->classes = lilv_nodes_new(); + return port; } void lilv_port_free(const LilvPlugin* plugin, LilvPort* port) { - if (port) { - lilv_node_free(port->node); - lilv_nodes_free(port->classes); - lilv_node_free(port->symbol); - free(port); - } + if (port) { + lilv_node_free(port->node); + lilv_nodes_free(port->classes); + lilv_node_free(port->symbol); + free(port); + } } bool @@ -60,13 +60,13 @@ lilv_port_is_a(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* port_class) { - LILV_FOREACH(nodes, i, port->classes) { - if (lilv_node_equals(lilv_nodes_get(port->classes, i), port_class)) { - return true; - } - } + LILV_FOREACH (nodes, i, port->classes) { + if (lilv_node_equals(lilv_nodes_get(port->classes, i), port_class)) { + return true; + } + } - return false; + return false; } bool @@ -74,10 +74,10 @@ lilv_port_has_property(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* property) { - return lilv_world_ask_internal(plugin->world, - port->node->node, - plugin->world->uris.lv2_portProperty, - property->node); + return lilv_world_ask_internal(plugin->world, + port->node->node, + plugin->world->uris.lv2_portProperty, + property->node); } bool @@ -85,19 +85,19 @@ lilv_port_supports_event(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* event_type) { - const uint8_t* predicates[] = { (const uint8_t*)LV2_EVENT__supportsEvent, - (const uint8_t*)LV2_ATOM__supports, - NULL }; - - for (const uint8_t** pred = predicates; *pred; ++pred) { - if (lilv_world_ask_internal(plugin->world, - port->node->node, - sord_new_uri(plugin->world->world, *pred), - event_type->node)) { - return true; - } - } - return false; + const uint8_t* predicates[] = {(const uint8_t*)LV2_EVENT__supportsEvent, + (const uint8_t*)LV2_ATOM__supports, + NULL}; + + for (const uint8_t** pred = predicates; *pred; ++pred) { + if (lilv_world_ask_internal(plugin->world, + port->node->node, + sord_new_uri(plugin->world->world, *pred), + event_type->node)) { + return true; + } + } + return false; } static LilvNodes* @@ -105,17 +105,14 @@ lilv_port_get_value_by_node(const LilvPlugin* plugin, const LilvPort* port, const SordNode* predicate) { - return lilv_world_find_nodes_internal(plugin->world, - port->node->node, - predicate, - NULL); + return lilv_world_find_nodes_internal( + plugin->world, port->node->node, predicate, NULL); } const LilvNode* -lilv_port_get_node(const LilvPlugin* plugin, - const LilvPort* port) +lilv_port_get_node(const LilvPlugin* plugin, const LilvPort* port) { - return port->node; + return port->node; } LilvNodes* @@ -123,13 +120,13 @@ lilv_port_get_value(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* predicate) { - if (!lilv_node_is_uri(predicate)) { - LILV_ERRORF("Predicate `%s' is not a URI\n", - sord_node_get_string(predicate->node)); - return NULL; - } + if (!lilv_node_is_uri(predicate)) { + LILV_ERRORF("Predicate `%s' is not a URI\n", + sord_node_get_string(predicate->node)); + return NULL; + } - return lilv_port_get_value_by_node(plugin, port, predicate->node); + return lilv_port_get_value_by_node(plugin, port, predicate->node); } LilvNode* @@ -137,58 +134,54 @@ lilv_port_get(const LilvPlugin* plugin, const LilvPort* port, const LilvNode* predicate) { - LilvNodes* values = lilv_port_get_value(plugin, port, predicate); + LilvNodes* values = lilv_port_get_value(plugin, port, predicate); - LilvNode* value = lilv_node_duplicate( - values ? lilv_nodes_get_first(values) : NULL); + LilvNode* value = + lilv_node_duplicate(values ? lilv_nodes_get_first(values) : NULL); - lilv_nodes_free(values); - return value; + lilv_nodes_free(values); + return value; } uint32_t -lilv_port_get_index(const LilvPlugin* plugin, - const LilvPort* port) +lilv_port_get_index(const LilvPlugin* plugin, const LilvPort* port) { - return port->index; + return port->index; } const LilvNode* -lilv_port_get_symbol(const LilvPlugin* plugin, - const LilvPort* port) +lilv_port_get_symbol(const LilvPlugin* plugin, const LilvPort* port) { - return port->symbol; + return port->symbol; } LilvNode* -lilv_port_get_name(const LilvPlugin* plugin, - const LilvPort* port) +lilv_port_get_name(const LilvPlugin* plugin, const LilvPort* port) { - LilvNodes* results = lilv_port_get_value_by_node( - plugin, port, plugin->world->uris.lv2_name); - - LilvNode* ret = NULL; - if (results) { - LilvNode* val = lilv_nodes_get_first(results); - if (lilv_node_is_string(val)) { - ret = lilv_node_duplicate(val); - } - lilv_nodes_free(results); - } - - if (!ret) { - LILV_WARNF("Plugin <%s> port has no (mandatory) doap:name\n", - lilv_node_as_string(lilv_plugin_get_uri(plugin))); - } - - return ret; + LilvNodes* results = + lilv_port_get_value_by_node(plugin, port, plugin->world->uris.lv2_name); + + LilvNode* ret = NULL; + if (results) { + LilvNode* val = lilv_nodes_get_first(results); + if (lilv_node_is_string(val)) { + ret = lilv_node_duplicate(val); + } + lilv_nodes_free(results); + } + + if (!ret) { + LILV_WARNF("Plugin <%s> port has no (mandatory) doap:name\n", + lilv_node_as_string(lilv_plugin_get_uri(plugin))); + } + + return ret; } const LilvNodes* -lilv_port_get_classes(const LilvPlugin* plugin, - const LilvPort* port) +lilv_port_get_classes(const LilvPlugin* plugin, const LilvPort* port) { - return port->classes; + return port->classes; } void @@ -198,76 +191,70 @@ lilv_port_get_range(const LilvPlugin* plugin, LilvNode** min, LilvNode** max) { - if (def) { - LilvNodes* defaults = lilv_port_get_value_by_node( - plugin, port, plugin->world->uris.lv2_default); - *def = defaults - ? lilv_node_duplicate(lilv_nodes_get_first(defaults)) - : NULL; - lilv_nodes_free(defaults); - } - if (min) { - LilvNodes* minimums = lilv_port_get_value_by_node( - plugin, port, plugin->world->uris.lv2_minimum); - *min = minimums - ? lilv_node_duplicate(lilv_nodes_get_first(minimums)) - : NULL; - lilv_nodes_free(minimums); - } - if (max) { - LilvNodes* maximums = lilv_port_get_value_by_node( - plugin, port, plugin->world->uris.lv2_maximum); - *max = maximums - ? lilv_node_duplicate(lilv_nodes_get_first(maximums)) - : NULL; - lilv_nodes_free(maximums); - } + if (def) { + LilvNodes* defaults = lilv_port_get_value_by_node( + plugin, port, plugin->world->uris.lv2_default); + *def = + defaults ? lilv_node_duplicate(lilv_nodes_get_first(defaults)) : NULL; + lilv_nodes_free(defaults); + } + + if (min) { + LilvNodes* minimums = lilv_port_get_value_by_node( + plugin, port, plugin->world->uris.lv2_minimum); + *min = + minimums ? lilv_node_duplicate(lilv_nodes_get_first(minimums)) : NULL; + lilv_nodes_free(minimums); + } + + if (max) { + LilvNodes* maximums = lilv_port_get_value_by_node( + plugin, port, plugin->world->uris.lv2_maximum); + *max = + maximums ? lilv_node_duplicate(lilv_nodes_get_first(maximums)) : NULL; + lilv_nodes_free(maximums); + } } LilvScalePoints* -lilv_port_get_scale_points(const LilvPlugin* plugin, - const LilvPort* port) +lilv_port_get_scale_points(const LilvPlugin* plugin, const LilvPort* port) { - SordIter* points = lilv_world_query_internal( - plugin->world, - port->node->node, - sord_new_uri(plugin->world->world, (const uint8_t*)LV2_CORE__scalePoint), - NULL); - - LilvScalePoints* ret = NULL; - if (!sord_iter_end(points)) { - ret = lilv_scale_points_new(); - } - - FOREACH_MATCH(points) { - const SordNode* point = sord_iter_get_node(points, SORD_OBJECT); - - LilvNode* value = lilv_plugin_get_unique(plugin, - point, - plugin->world->uris.rdf_value); - - LilvNode* label = lilv_plugin_get_unique(plugin, - point, - plugin->world->uris.rdfs_label); - - if (value && label) { - zix_tree_insert( - (ZixTree*)ret, lilv_scale_point_new(value, label), NULL); - } - } - sord_iter_free(points); - - assert(!ret || lilv_nodes_size(ret) > 0); - return ret; + SordIter* points = lilv_world_query_internal( + plugin->world, + port->node->node, + sord_new_uri(plugin->world->world, (const uint8_t*)LV2_CORE__scalePoint), + NULL); + + LilvScalePoints* ret = NULL; + if (!sord_iter_end(points)) { + ret = lilv_scale_points_new(); + } + + FOREACH_MATCH (points) { + const SordNode* point = sord_iter_get_node(points, SORD_OBJECT); + + LilvNode* value = + lilv_plugin_get_unique(plugin, point, plugin->world->uris.rdf_value); + + LilvNode* label = + lilv_plugin_get_unique(plugin, point, plugin->world->uris.rdfs_label); + + if (value && label) { + zix_tree_insert((ZixTree*)ret, lilv_scale_point_new(value, label), NULL); + } + } + sord_iter_free(points); + + assert(!ret || lilv_nodes_size(ret) > 0); + return ret; } LilvNodes* -lilv_port_get_properties(const LilvPlugin* plugin, - const LilvPort* port) +lilv_port_get_properties(const LilvPlugin* plugin, const LilvPort* port) { - LilvNode* pred = lilv_node_new_from_node( - plugin->world, plugin->world->uris.lv2_portProperty); - LilvNodes* ret = lilv_port_get_value(plugin, port, pred); - lilv_node_free(pred); - return ret; + LilvNode* pred = lilv_node_new_from_node( + plugin->world, plugin->world->uris.lv2_portProperty); + LilvNodes* ret = lilv_port_get_value(plugin, port, pred); + lilv_node_free(pred); + return ret; } diff --git a/src/query.c b/src/query.c index 5081a9a..1e3e29b 100644 --- a/src/query.c +++ b/src/query.c @@ -24,32 +24,32 @@ #include <string.h> typedef enum { - LILV_LANG_MATCH_NONE, ///< Language does not match at all - LILV_LANG_MATCH_PARTIAL, ///< Partial (language, but not country) match - LILV_LANG_MATCH_EXACT ///< Exact (language and country) match + LILV_LANG_MATCH_NONE, ///< Language does not match at all + LILV_LANG_MATCH_PARTIAL, ///< Partial (language, but not country) match + LILV_LANG_MATCH_EXACT ///< Exact (language and country) match } LilvLangMatch; static LilvLangMatch lilv_lang_matches(const char* a, const char* b) { - if (!a || !b) { - return LILV_LANG_MATCH_NONE; - } + if (!a || !b) { + return LILV_LANG_MATCH_NONE; + } - if (!strcmp(a, b)) { - return LILV_LANG_MATCH_EXACT; - } + if (!strcmp(a, b)) { + return LILV_LANG_MATCH_EXACT; + } - const char* a_dash = strchr(a, '-'); - const size_t a_lang_len = a_dash ? (size_t)(a_dash - a) : strlen(a); - const char* b_dash = strchr(b, '-'); - const size_t b_lang_len = b_dash ? (size_t)(b_dash - b) : strlen(b); + const char* a_dash = strchr(a, '-'); + const size_t a_lang_len = a_dash ? (size_t)(a_dash - a) : strlen(a); + const char* b_dash = strchr(b, '-'); + const size_t b_lang_len = b_dash ? (size_t)(b_dash - b) : strlen(b); - if (a_lang_len == b_lang_len && !strncmp(a, b, a_lang_len)) { - return LILV_LANG_MATCH_PARTIAL; - } + if (a_lang_len == b_lang_len && !strncmp(a, b, a_lang_len)) { + return LILV_LANG_MATCH_PARTIAL; + } - return LILV_LANG_MATCH_NONE; + return LILV_LANG_MATCH_NONE; } static LilvNodes* @@ -57,66 +57,64 @@ lilv_nodes_from_stream_objects_i18n(LilvWorld* world, SordIter* stream, SordQuadIndex field) { - LilvNodes* values = lilv_nodes_new(); - const SordNode* nolang = NULL; // Untranslated value - const SordNode* partial = NULL; // Partial language match - char* syslang = lilv_get_lang(); - FOREACH_MATCH(stream) { - const SordNode* value = sord_iter_get_node(stream, field); - if (sord_node_get_type(value) == SORD_LITERAL) { - const char* lang = sord_node_get_language(value); - - if (!lang) { - nolang = value; - } else { - switch (lilv_lang_matches(lang, syslang)) { - case LILV_LANG_MATCH_EXACT: - // Exact language match, add to results - zix_tree_insert((ZixTree*)values, - lilv_node_new_from_node(world, value), - NULL); - break; - case LILV_LANG_MATCH_PARTIAL: - // Partial language match, save in case we find no exact - partial = value; - break; - case LILV_LANG_MATCH_NONE: - break; - } - } - } else { - zix_tree_insert((ZixTree*)values, - lilv_node_new_from_node(world, value), - NULL); - } - } - sord_iter_free(stream); - free(syslang); - - if (lilv_nodes_size(values) > 0) { - return values; - } - - const SordNode* best = nolang; - if (syslang && partial) { - // Partial language match for system language - best = partial; - } else if (!best) { - // No languages matches at all, and no untranslated value - // Use any value, if possible - best = partial; - } - - if (best) { - zix_tree_insert( - (ZixTree*)values, lilv_node_new_from_node(world, best), NULL); - } else { - // No matches whatsoever - lilv_nodes_free(values); - values = NULL; - } - - return values; + LilvNodes* values = lilv_nodes_new(); + const SordNode* nolang = NULL; // Untranslated value + const SordNode* partial = NULL; // Partial language match + char* syslang = lilv_get_lang(); + FOREACH_MATCH (stream) { + const SordNode* value = sord_iter_get_node(stream, field); + if (sord_node_get_type(value) == SORD_LITERAL) { + const char* lang = sord_node_get_language(value); + + if (!lang) { + nolang = value; + } else { + switch (lilv_lang_matches(lang, syslang)) { + case LILV_LANG_MATCH_EXACT: + // Exact language match, add to results + zix_tree_insert( + (ZixTree*)values, lilv_node_new_from_node(world, value), NULL); + break; + case LILV_LANG_MATCH_PARTIAL: + // Partial language match, save in case we find no exact + partial = value; + break; + case LILV_LANG_MATCH_NONE: + break; + } + } + } else { + zix_tree_insert( + (ZixTree*)values, lilv_node_new_from_node(world, value), NULL); + } + } + sord_iter_free(stream); + free(syslang); + + if (lilv_nodes_size(values) > 0) { + return values; + } + + const SordNode* best = nolang; + if (syslang && partial) { + // Partial language match for system language + best = partial; + } else if (!best) { + // No languages matches at all, and no untranslated value + // Use any value, if possible + best = partial; + } + + if (best) { + zix_tree_insert( + (ZixTree*)values, lilv_node_new_from_node(world, best), NULL); + } else { + // No matches whatsoever + lilv_nodes_free(values); + values = NULL; + } + + return values; } LilvNodes* @@ -124,23 +122,23 @@ lilv_nodes_from_stream_objects(LilvWorld* world, SordIter* stream, SordQuadIndex field) { - if (sord_iter_end(stream)) { - sord_iter_free(stream); - return NULL; - } - - if (world->opt.filter_language) { - return lilv_nodes_from_stream_objects_i18n(world, stream, field); - } - - LilvNodes* values = lilv_nodes_new(); - FOREACH_MATCH(stream) { - const SordNode* value = sord_iter_get_node(stream, field); - LilvNode* node = lilv_node_new_from_node(world, value); - if (node) { - zix_tree_insert((ZixTree*)values, node, NULL); - } - } - sord_iter_free(stream); - return values; + if (sord_iter_end(stream)) { + sord_iter_free(stream); + return NULL; + } + + if (world->opt.filter_language) { + return lilv_nodes_from_stream_objects_i18n(world, stream, field); + } + + LilvNodes* values = lilv_nodes_new(); + FOREACH_MATCH (stream) { + const SordNode* value = sord_iter_get_node(stream, field); + LilvNode* node = lilv_node_new_from_node(world, value); + if (node) { + zix_tree_insert((ZixTree*)values, node, NULL); + } + } + sord_iter_free(stream); + return values; } diff --git a/src/scalepoint.c b/src/scalepoint.c index 31e33c2..0989223 100644 --- a/src/scalepoint.c +++ b/src/scalepoint.c @@ -24,30 +24,30 @@ LilvScalePoint* lilv_scale_point_new(LilvNode* value, LilvNode* label) { - LilvScalePoint* point = (LilvScalePoint*)malloc(sizeof(LilvScalePoint)); - point->value = value; - point->label = label; - return point; + LilvScalePoint* point = (LilvScalePoint*)malloc(sizeof(LilvScalePoint)); + point->value = value; + point->label = label; + return point; } void lilv_scale_point_free(LilvScalePoint* point) { - if (point) { - lilv_node_free(point->value); - lilv_node_free(point->label); - free(point); - } + if (point) { + lilv_node_free(point->value); + lilv_node_free(point->label); + free(point); + } } const LilvNode* lilv_scale_point_get_value(const LilvScalePoint* point) { - return point->value; + return point->value; } const LilvNode* lilv_scale_point_get_label(const LilvScalePoint* point) { - return point->label; + return point->label; } diff --git a/src/state.c b/src/state.c index f30cfd4..a47fc9c 100644 --- a/src/state.c +++ b/src/state.c @@ -41,87 +41,86 @@ #define USTR(s) ((const uint8_t*)(s)) typedef struct { - void* value; ///< Value/Object - size_t size; ///< Size of value - uint32_t key; ///< Key/Predicate (URID) - uint32_t type; ///< Type of value (URID) - uint32_t flags; ///< State flags (POD, etc) + void* value; ///< Value/Object + size_t size; ///< Size of value + uint32_t key; ///< Key/Predicate (URID) + uint32_t type; ///< Type of value (URID) + uint32_t flags; ///< State flags (POD, etc) } Property; typedef struct { - char* symbol; ///< Symbol of port - LV2_Atom* atom; ///< Value in port + char* symbol; ///< Symbol of port + LV2_Atom* atom; ///< Value in port } PortValue; typedef struct { - char* abs; ///< Absolute path of actual file - char* rel; ///< Abstract path (relative path in state dir) + char* abs; ///< Absolute path of actual file + char* rel; ///< Abstract path (relative path in state dir) } PathMap; typedef struct { - size_t n; - Property* props; + size_t n; + Property* props; } PropertyArray; struct LilvStateImpl { - LilvNode* plugin_uri; ///< Plugin URI - LilvNode* uri; ///< State/preset URI - char* dir; ///< Save directory (if saved) - char* scratch_dir; ///< Directory for files created by plugin - char* copy_dir; ///< Directory for snapshots of external files - char* link_dir; ///< Directory for links to external files - char* label; ///< State/Preset label - ZixTree* abs2rel; ///< PathMap sorted by abs - ZixTree* rel2abs; ///< PathMap sorted by rel - PropertyArray props; ///< State properties - PropertyArray metadata; ///< State metadata - PortValue* values; ///< Port values - uint32_t atom_Path; ///< atom:Path URID - uint32_t n_values; ///< Number of port values + LilvNode* plugin_uri; ///< Plugin URI + LilvNode* uri; ///< State/preset URI + char* dir; ///< Save directory (if saved) + char* scratch_dir; ///< Directory for files created by plugin + char* copy_dir; ///< Directory for snapshots of external files + char* link_dir; ///< Directory for links to external files + char* label; ///< State/Preset label + ZixTree* abs2rel; ///< PathMap sorted by abs + ZixTree* rel2abs; ///< PathMap sorted by rel + PropertyArray props; ///< State properties + PropertyArray metadata; ///< State metadata + PortValue* values; ///< Port values + uint32_t atom_Path; ///< atom:Path URID + uint32_t n_values; ///< Number of port values }; static int abs_cmp(const void* a, const void* b, void* user_data) { - return strcmp(((const PathMap*)a)->abs, ((const PathMap*)b)->abs); + return strcmp(((const PathMap*)a)->abs, ((const PathMap*)b)->abs); } static int rel_cmp(const void* a, const void* b, void* user_data) { - return strcmp(((const PathMap*)a)->rel, ((const PathMap*)b)->rel); + return strcmp(((const PathMap*)a)->rel, ((const PathMap*)b)->rel); } static int property_cmp(const void* a, const void* b) { - const uint32_t a_key = ((const Property*)a)->key; - const uint32_t b_key = ((const Property*)b)->key; + const uint32_t a_key = ((const Property*)a)->key; + const uint32_t b_key = ((const Property*)b)->key; - if (a_key < b_key) { - return -1; - } + if (a_key < b_key) { + return -1; + } - if (b_key < a_key) { - return 1; - } + if (b_key < a_key) { + return 1; + } - return 0; + return 0; } static int value_cmp(const void* a, const void* b) { - return strcmp(((const PortValue*)a)->symbol, - ((const PortValue*)b)->symbol); + return strcmp(((const PortValue*)a)->symbol, ((const PortValue*)b)->symbol); } static void path_rel_free(void* ptr) { - free(((PathMap*)ptr)->abs); - free(((PathMap*)ptr)->rel); - free(ptr); + free(((PathMap*)ptr)->abs); + free(((PathMap*)ptr)->rel); + free(ptr); } static PortValue* @@ -131,30 +130,30 @@ append_port_value(LilvState* state, uint32_t size, uint32_t type) { - PortValue* pv = NULL; - if (value) { - state->values = (PortValue*)realloc( - state->values, (++state->n_values) * sizeof(PortValue)); - - pv = &state->values[state->n_values - 1]; - pv->symbol = lilv_strdup(port_symbol); - pv->atom = (LV2_Atom*)malloc(sizeof(LV2_Atom) + size); - pv->atom->size = size; - pv->atom->type = type; - memcpy(pv->atom + 1, value, size); - } - return pv; + PortValue* pv = NULL; + if (value) { + state->values = (PortValue*)realloc( + state->values, (++state->n_values) * sizeof(PortValue)); + + pv = &state->values[state->n_values - 1]; + pv->symbol = lilv_strdup(port_symbol); + pv->atom = (LV2_Atom*)malloc(sizeof(LV2_Atom) + size); + pv->atom->size = size; + pv->atom->type = type; + memcpy(pv->atom + 1, value, size); + } + return pv; } static const char* lilv_state_rel2abs(const LilvState* state, const char* path) { - ZixTreeIter* iter = NULL; - const PathMap key = { NULL, (char*)path }; - if (state->rel2abs && !zix_tree_find(state->rel2abs, &key, &iter)) { - return ((const PathMap*)zix_tree_get(iter))->abs; - } - return path; + ZixTreeIter* iter = NULL; + const PathMap key = {NULL, (char*)path}; + if (state->rel2abs && !zix_tree_find(state->rel2abs, &key, &iter)) { + return ((const PathMap*)zix_tree_get(iter))->abs; + } + return path; } static void @@ -166,37 +165,37 @@ append_property(LilvState* state, uint32_t type, uint32_t flags) { - array->props = (Property*)realloc( - array->props, (++array->n) * sizeof(Property)); - - Property* const prop = &array->props[array->n - 1]; - if ((flags & LV2_STATE_IS_POD) || type == state->atom_Path) { - prop->value = malloc(size); - memcpy(prop->value, value, size); - } else { - prop->value = (void*)value; - } - - prop->size = size; - prop->key = key; - prop->type = type; - prop->flags = flags; + array->props = + (Property*)realloc(array->props, (++array->n) * sizeof(Property)); + + Property* const prop = &array->props[array->n - 1]; + if ((flags & LV2_STATE_IS_POD) || type == state->atom_Path) { + prop->value = malloc(size); + memcpy(prop->value, value, size); + } else { + prop->value = (void*)value; + } + + prop->size = size; + prop->key = key; + prop->type = type; + prop->flags = flags; } static const Property* find_property(const LilvState* const state, const uint32_t key) { - if (!state->props.props) { - return NULL; - } + if (!state->props.props) { + return NULL; + } - const Property search_key = {NULL, 0, key, 0, 0}; + const Property search_key = {NULL, 0, key, 0, 0}; - return (const Property*)bsearch(&search_key, - state->props.props, - state->props.n, - sizeof(Property), - property_cmp); + return (const Property*)bsearch(&search_key, + state->props.props, + state->props.n, + sizeof(Property), + property_cmp); } static LV2_State_Status @@ -207,18 +206,18 @@ store_callback(LV2_State_Handle handle, uint32_t type, uint32_t flags) { - LilvState* const state = (LilvState*)handle; + LilvState* const state = (LilvState*)handle; - if (!key) { - return LV2_STATE_ERR_UNKNOWN; // TODO: Add status for bad arguments - } + if (!key) { + return LV2_STATE_ERR_UNKNOWN; // TODO: Add status for bad arguments + } - if (find_property((const LilvState*)handle, key)) { - return LV2_STATE_ERR_UNKNOWN; // TODO: Add status for duplicate keys - } + if (find_property((const LilvState*)handle, key)) { + return LV2_STATE_ERR_UNKNOWN; // TODO: Add status for duplicate keys + } - append_property(state, &state->props, key, value, size, type, flags); - return LV2_STATE_SUCCESS; + append_property(state, &state->props, key, value, size, type, flags); + return LV2_STATE_SUCCESS; } static const void* @@ -228,130 +227,127 @@ retrieve_callback(LV2_State_Handle handle, uint32_t* type, uint32_t* flags) { - const Property* const prop = find_property((const LilvState*)handle, key); - - if (prop) { - *size = prop->size; - *type = prop->type; - *flags = prop->flags; - return prop->value; - } - return NULL; + const Property* const prop = find_property((const LilvState*)handle, key); + + if (prop) { + *size = prop->size; + *type = prop->type; + *flags = prop->flags; + return prop->value; + } + return NULL; } static bool path_exists(const char* path, const void* ignored) { - return lilv_path_exists(path); + return lilv_path_exists(path); } static bool lilv_state_has_path(const char* path, const void* state) { - return lilv_state_rel2abs((const LilvState*)state, path) != path; + return lilv_state_rel2abs((const LilvState*)state, path) != path; } static char* make_path(LV2_State_Make_Path_Handle handle, const char* path) { - LilvState* state = (LilvState*)handle; - lilv_create_directories(state->dir); + LilvState* state = (LilvState*)handle; + lilv_create_directories(state->dir); - return lilv_path_join(state->dir, path); + return lilv_path_join(state->dir, path); } static char* -abstract_path(LV2_State_Map_Path_Handle handle, - const char* abs_path) +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; - - if (abs_path[0] == '\0') { - return lilv_strdup(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); - return lilv_strdup(pm->rel); - } - - if (lilv_path_is_child(real_path, state->dir)) { - // File in state directory (loaded, or created by plugin during save) - path = lilv_path_relative_to(real_path, state->dir); - } else if (lilv_path_is_child(real_path, state->scratch_dir)) { - // File created by plugin earlier - path = lilv_path_relative_to(real_path, state->scratch_dir); - if (state->copy_dir) { - int st = lilv_create_directories(state->copy_dir); - if (st) { - LILV_ERRORF("Error creating directory %s (%s)\n", - state->copy_dir, strerror(st)); - } - - char* cpath = lilv_path_join(state->copy_dir, path); - char* copy = lilv_get_latest_copy(real_path, cpath); - if (!copy || !lilv_file_equals(real_path, copy)) { - // No recent enough copy, make a new one - free(copy); - copy = lilv_find_free_path(cpath, path_exists, NULL); - if ((st = lilv_copy_file(real_path, copy))) { - LILV_ERRORF("Error copying state file %s (%s)\n", - copy, strerror(st)); - } - } - free(real_path); - free(cpath); - - // Refer to the latest copy in plugin state - real_path = copy; - } - } else if (state->link_dir) { - // New path outside state directory, make a link - char* const name = lilv_path_filename(real_path); - - // Find a free name in the (virtual) state directory - path = lilv_find_free_path(name, lilv_state_has_path, state); - - free(name); - } else { - // No link directory, preserve absolute path - path = lilv_strdup(abs_path); - } - - // Add record to path mapping - PathMap* pm = (PathMap*)malloc(sizeof(PathMap)); - pm->abs = real_path; - pm->rel = lilv_strdup(path); - zix_tree_insert(state->abs2rel, pm, NULL); - zix_tree_insert(state->rel2abs, pm, NULL); - - return 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; + + if (abs_path[0] == '\0') { + return lilv_strdup(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); + return lilv_strdup(pm->rel); + } + + if (lilv_path_is_child(real_path, state->dir)) { + // File in state directory (loaded, or created by plugin during save) + path = lilv_path_relative_to(real_path, state->dir); + } else if (lilv_path_is_child(real_path, state->scratch_dir)) { + // File created by plugin earlier + path = lilv_path_relative_to(real_path, state->scratch_dir); + if (state->copy_dir) { + int st = lilv_create_directories(state->copy_dir); + if (st) { + LILV_ERRORF( + "Error creating directory %s (%s)\n", state->copy_dir, strerror(st)); + } + + char* cpath = lilv_path_join(state->copy_dir, path); + char* copy = lilv_get_latest_copy(real_path, cpath); + if (!copy || !lilv_file_equals(real_path, copy)) { + // No recent enough copy, make a new one + free(copy); + copy = lilv_find_free_path(cpath, path_exists, NULL); + if ((st = lilv_copy_file(real_path, copy))) { + LILV_ERRORF("Error copying state file %s (%s)\n", copy, strerror(st)); + } + } + free(real_path); + free(cpath); + + // Refer to the latest copy in plugin state + real_path = copy; + } + } else if (state->link_dir) { + // New path outside state directory, make a link + char* const name = lilv_path_filename(real_path); + + // Find a free name in the (virtual) state directory + path = lilv_find_free_path(name, lilv_state_has_path, state); + + free(name); + } else { + // No link directory, preserve absolute path + path = lilv_strdup(abs_path); + } + + // Add record to path mapping + PathMap* pm = (PathMap*)malloc(sizeof(PathMap)); + pm->abs = real_path; + pm->rel = lilv_strdup(path); + zix_tree_insert(state->abs2rel, pm, NULL); + zix_tree_insert(state->rel2abs, pm, NULL); + + return path; } static char* -absolute_path(LV2_State_Map_Path_Handle handle, - const char* state_path) +absolute_path(LV2_State_Map_Path_Handle handle, const char* state_path) { - LilvState* state = (LilvState*)handle; - char* path = NULL; - if (lilv_path_is_absolute(state_path)) { - // Absolute path, return identical path - path = lilv_strdup(state_path); - } else if (state->dir) { - // Relative path inside state directory - path = lilv_path_join(state->dir, state_path); - } else { - // State has not been saved, unmap - path = lilv_strdup(lilv_state_rel2abs(state, state_path)); - } - - return path; + LilvState* state = (LilvState*)handle; + char* path = NULL; + if (lilv_path_is_absolute(state_path)) { + // Absolute path, return identical path + path = lilv_strdup(state_path); + } else if (state->dir) { + // Relative path inside state directory + path = lilv_path_join(state->dir, state_path); + } else { + // State has not been saved, unmap + path = lilv_strdup(lilv_state_rel2abs(state, state_path)); + } + + return path; } /** Return a new features array with built-in features added to `features`. */ @@ -361,138 +357,145 @@ add_features(const LV2_Feature* const* features, 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 + 4, sizeof(LV2_Feature*)); - - if (features) { - memcpy(ret, features, n_features * sizeof(LV2_Feature*)); - } - - size_t i = n_features; - if (map) { - ret[i++] = map; - } - if (make) { - ret[i++] = make; - } - if (free) { - ret[i++] = free; - } - - return ret; + size_t n_features = 0; + for (; features && features[n_features]; ++n_features) { + } + + const LV2_Feature** ret = + (const LV2_Feature**)calloc(n_features + 4, sizeof(LV2_Feature*)); + + if (features) { + memcpy(ret, features, n_features * sizeof(LV2_Feature*)); + } + + size_t i = n_features; + if (map) { + ret[i++] = map; + } + if (make) { + ret[i++] = make; + } + if (free) { + ret[i++] = free; + } + + return ret; } /// Return the canonical path for a directory with a trailing separator static char* real_dir(const char* path) { - char* abs_path = lilv_path_canonical(path); - char* base = lilv_path_join(abs_path, NULL); - free(abs_path); - return base; + char* abs_path = lilv_path_canonical(path); + char* base = lilv_path_join(abs_path, NULL); + free(abs_path); + return base; } static const char* state_strerror(LV2_State_Status st) { - switch (st) { - case LV2_STATE_SUCCESS: return "Completed successfully"; - case LV2_STATE_ERR_BAD_TYPE: return "Unsupported type"; - case LV2_STATE_ERR_BAD_FLAGS: return "Unsupported flags"; - case LV2_STATE_ERR_NO_FEATURE: return "Missing features"; - case LV2_STATE_ERR_NO_PROPERTY: return "Missing property"; - default: return "Unknown error"; - } + switch (st) { + case LV2_STATE_SUCCESS: + return "Completed successfully"; + case LV2_STATE_ERR_BAD_TYPE: + return "Unsupported type"; + case LV2_STATE_ERR_BAD_FLAGS: + return "Unsupported flags"; + case LV2_STATE_ERR_NO_FEATURE: + return "Missing features"; + case LV2_STATE_ERR_NO_PROPERTY: + return "Missing property"; + default: + return "Unknown error"; + } } static void lilv_free_path(LV2_State_Free_Path_Handle handle, char* path) { - lilv_free(path); + lilv_free(path); } LilvState* -lilv_state_new_from_instance(const LilvPlugin* plugin, - LilvInstance* instance, - LV2_URID_Map* map, - const char* scratch_dir, - const char* copy_dir, - const char* link_dir, - const char* save_dir, - LilvGetPortValueFunc get_value, - void* user_data, - uint32_t flags, - const LV2_Feature *const * features) +lilv_state_new_from_instance(const LilvPlugin* plugin, + LilvInstance* instance, + LV2_URID_Map* map, + const char* scratch_dir, + const char* copy_dir, + const char* link_dir, + const char* save_dir, + LilvGetPortValueFunc get_value, + void* user_data, + uint32_t flags, + const LV2_Feature* const* features) { - const LV2_Feature** sfeatures = NULL; - LilvWorld* const world = plugin->world; - LilvState* const state = (LilvState*)calloc(1, sizeof(LilvState)); - state->plugin_uri = lilv_node_duplicate(lilv_plugin_get_uri(plugin)); - state->abs2rel = zix_tree_new(false, abs_cmp, NULL, path_rel_free); - state->rel2abs = zix_tree_new(false, rel_cmp, 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->atom_Path = map->map(map->handle, LV2_ATOM__Path); - - LV2_State_Map_Path pmap = { state, abstract_path, absolute_path }; - 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, - &pfree_feature); - - // Store port values - if (get_value) { - LilvNode* lv2_ControlPort = lilv_new_uri(world, LILV_URI_CONTROL_PORT); - LilvNode* lv2_InputPort = lilv_new_uri(world, LILV_URI_INPUT_PORT); - for (uint32_t i = 0; i < plugin->num_ports; ++i) { - const LilvPort* const port = plugin->ports[i]; - if (lilv_port_is_a(plugin, port, lv2_ControlPort) - && lilv_port_is_a(plugin, port, lv2_InputPort)) { - uint32_t size = 0; - uint32_t type = 0; - const char* sym = lilv_node_as_string(port->symbol); - const void* value = get_value(sym, user_data, &size, &type); - append_port_value(state, sym, value, size, type); - } - } - lilv_node_free(lv2_ControlPort); - lilv_node_free(lv2_InputPort); - } - - // Store properties - const LV2_Descriptor* desc = instance->lv2_descriptor; - const LV2_State_Interface* iface = (desc->extension_data) - ? (const LV2_State_Interface*)desc->extension_data(LV2_STATE__interface) - : NULL; - - if (iface) { - LV2_State_Status st = iface->save( - instance->lv2_handle, store_callback, state, flags, features); - if (st) { - LILV_ERRORF("Error saving plugin state: %s\n", state_strerror(st)); - free(state->props.props); - state->props.props = NULL; - state->props.n = 0; - } else { - qsort(state->props.props, state->props.n, sizeof(Property), property_cmp); - } - } - - if (state->values) { - qsort(state->values, state->n_values, sizeof(PortValue), value_cmp); - } - - free(sfeatures); - return state; + const LV2_Feature** sfeatures = NULL; + LilvWorld* const world = plugin->world; + LilvState* const state = (LilvState*)calloc(1, sizeof(LilvState)); + state->plugin_uri = lilv_node_duplicate(lilv_plugin_get_uri(plugin)); + state->abs2rel = zix_tree_new(false, abs_cmp, NULL, path_rel_free); + state->rel2abs = zix_tree_new(false, rel_cmp, 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->atom_Path = map->map(map->handle, LV2_ATOM__Path); + + LV2_State_Map_Path pmap = {state, abstract_path, absolute_path}; + 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, &pfree_feature); + + // Store port values + if (get_value) { + LilvNode* lv2_ControlPort = lilv_new_uri(world, LILV_URI_CONTROL_PORT); + LilvNode* lv2_InputPort = lilv_new_uri(world, LILV_URI_INPUT_PORT); + for (uint32_t i = 0; i < plugin->num_ports; ++i) { + const LilvPort* const port = plugin->ports[i]; + if (lilv_port_is_a(plugin, port, lv2_ControlPort) && + lilv_port_is_a(plugin, port, lv2_InputPort)) { + uint32_t size = 0; + uint32_t type = 0; + const char* sym = lilv_node_as_string(port->symbol); + const void* value = get_value(sym, user_data, &size, &type); + append_port_value(state, sym, value, size, type); + } + } + lilv_node_free(lv2_ControlPort); + lilv_node_free(lv2_InputPort); + } + + // Store properties + const LV2_Descriptor* desc = instance->lv2_descriptor; + const LV2_State_Interface* iface = + (desc->extension_data) + ? (const LV2_State_Interface*)desc->extension_data(LV2_STATE__interface) + : NULL; + + if (iface) { + LV2_State_Status st = + iface->save(instance->lv2_handle, store_callback, state, flags, features); + if (st) { + LILV_ERRORF("Error saving plugin state: %s\n", state_strerror(st)); + free(state->props.props); + state->props.props = NULL; + state->props.n = 0; + } else { + qsort(state->props.props, state->props.n, sizeof(Property), property_cmp); + } + } + + if (state->values) { + qsort(state->values, state->n_values, sizeof(PortValue), value_cmp); + } + + free(sfeatures); + return state; } void @@ -500,209 +503,209 @@ lilv_state_emit_port_values(const LilvState* state, LilvSetPortValueFunc set_value, void* user_data) { - for (uint32_t i = 0; i < state->n_values; ++i) { - const PortValue* value = &state->values[i]; - const LV2_Atom* atom = value->atom; - set_value(value->symbol, user_data, atom + 1, atom->size, atom->type); - } + for (uint32_t i = 0; i < state->n_values; ++i) { + const PortValue* value = &state->values[i]; + const LV2_Atom* atom = value->atom; + set_value(value->symbol, user_data, atom + 1, atom->size, atom->type); + } } void -lilv_state_restore(const LilvState* state, - LilvInstance* instance, - LilvSetPortValueFunc set_value, - void* user_data, - uint32_t flags, - const LV2_Feature *const * features) +lilv_state_restore(const LilvState* state, + LilvInstance* instance, + LilvSetPortValueFunc set_value, + void* user_data, + uint32_t flags, + const LV2_Feature* const* features) { - if (!state) { - LILV_ERROR("lilv_state_restore() called on NULL state\n"); - return; - } - - LV2_State_Map_Path map_path = { - (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) { - const LV2_State_Interface* iface = (const LV2_State_Interface*) - desc->extension_data(LV2_STATE__interface); - - if (iface && iface->restore) { - const LV2_Feature** sfeatures = add_features( - features, &map_feature, NULL, &free_feature); - - iface->restore(instance->lv2_handle, retrieve_callback, - (LV2_State_Handle)state, flags, sfeatures); - - free(sfeatures); - } - } - } - - - if (set_value) { - lilv_state_emit_port_values(state, set_value, user_data); - } + if (!state) { + LILV_ERROR("lilv_state_restore() called on NULL state\n"); + return; + } + + LV2_State_Map_Path map_path = { + (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) { + const LV2_State_Interface* iface = + (const LV2_State_Interface*)desc->extension_data(LV2_STATE__interface); + + if (iface && iface->restore) { + const LV2_Feature** sfeatures = + add_features(features, &map_feature, NULL, &free_feature); + + iface->restore(instance->lv2_handle, + retrieve_callback, + (LV2_State_Handle)state, + flags, + sfeatures); + + free(sfeatures); + } + } + } + + if (set_value) { + lilv_state_emit_port_values(state, set_value, user_data); + } } static void set_state_dir_from_model(LilvState* state, const SordNode* graph) { - if (!state->dir && graph) { - const char* uri = (const char*)sord_node_get_string(graph); - char* path = lilv_file_uri_parse(uri, NULL); - - state->dir = lilv_path_join(path, NULL); - free(path); - } - assert(!state->dir || lilv_path_is_absolute(state->dir)); + if (!state->dir && graph) { + const char* uri = (const char*)sord_node_get_string(graph); + char* path = lilv_file_uri_parse(uri, NULL); + + state->dir = lilv_path_join(path, NULL); + free(path); + } + assert(!state->dir || lilv_path_is_absolute(state->dir)); } static LilvState* -new_state_from_model(LilvWorld* world, - LV2_URID_Map* map, - SordModel* model, - const SordNode* node, - const char* dir) +new_state_from_model(LilvWorld* world, + LV2_URID_Map* map, + SordModel* model, + const SordNode* node, + const char* dir) { - // Check that we know at least something about this state subject - if (!sord_ask(model, node, 0, 0, 0)) { - return NULL; - } - - // Allocate state - LilvState* const state = (LilvState*)calloc(1, sizeof(LilvState)); - state->dir = lilv_path_join(dir, NULL); - state->atom_Path = map->map(map->handle, LV2_ATOM__Path); - state->uri = lilv_node_new_from_node(world, node); - - // Get the plugin URI this state applies to - SordIter* i = sord_search(model, node, world->uris.lv2_appliesTo, 0, 0); - if (i) { - const SordNode* object = sord_iter_get_node(i, SORD_OBJECT); - const SordNode* graph = sord_iter_get_node(i, SORD_GRAPH); - state->plugin_uri = lilv_node_new_from_node(world, object); - set_state_dir_from_model(state, graph); - sord_iter_free(i); - } else if (sord_ask(model, - node, - world->uris.rdf_a, - world->uris.lv2_Plugin, 0)) { - // Loading plugin description as state (default state) - state->plugin_uri = lilv_node_new_from_node(world, node); - } else { - LILV_ERRORF("State %s missing lv2:appliesTo property\n", - sord_node_get_string(node)); - } - - // Get the state label - i = sord_search(model, node, world->uris.rdfs_label, NULL, NULL); - if (i) { - const SordNode* object = sord_iter_get_node(i, SORD_OBJECT); - const SordNode* graph = sord_iter_get_node(i, SORD_GRAPH); - state->label = lilv_strdup((const char*)sord_node_get_string(object)); - set_state_dir_from_model(state, graph); - sord_iter_free(i); - } - - Sratom* sratom = sratom_new(map); - SerdChunk chunk = { NULL, 0 }; - LV2_Atom_Forge forge; - lv2_atom_forge_init(&forge, map); - lv2_atom_forge_set_sink( - &forge, sratom_forge_sink, sratom_forge_deref, &chunk); - - // Get port values - SordIter* ports = sord_search(model, node, world->uris.lv2_port, 0, 0); - FOREACH_MATCH(ports) { - const SordNode* port = sord_iter_get_node(ports, SORD_OBJECT); - - SordNode* label = sord_get(model, port, world->uris.rdfs_label, 0, 0); - SordNode* symbol = sord_get(model, port, world->uris.lv2_symbol, 0, 0); - SordNode* value = sord_get(model, port, world->uris.pset_value, 0, 0); - if (!value) { - value = sord_get(model, port, world->uris.lv2_default, 0, 0); - } - if (!symbol) { - LILV_ERRORF("State `%s' port missing symbol.\n", - sord_node_get_string(node)); - } else if (value) { - chunk.len = 0; - sratom_read(sratom, &forge, world->world, model, value); - const LV2_Atom* atom = (const LV2_Atom*)chunk.buf; - - append_port_value(state, - (const char*)sord_node_get_string(symbol), - LV2_ATOM_BODY_CONST(atom), - atom->size, atom->type); - - if (label) { - lilv_state_set_label(state, - (const char*)sord_node_get_string(label)); - } - } - sord_node_free(world->world, value); - sord_node_free(world->world, symbol); - sord_node_free(world->world, label); - } - sord_iter_free(ports); - - // Get properties - SordNode* statep = sord_new_uri(world->world, USTR(LV2_STATE__state)); - SordNode* state_node = sord_get(model, node, statep, NULL, NULL); - if (state_node) { - SordIter* props = sord_search(model, state_node, 0, 0, 0); - FOREACH_MATCH(props) { - const SordNode* p = sord_iter_get_node(props, SORD_PREDICATE); - const SordNode* o = sord_iter_get_node(props, SORD_OBJECT); - const char* key = (const char*)sord_node_get_string(p); - - chunk.len = 0; - lv2_atom_forge_set_sink( - &forge, sratom_forge_sink, sratom_forge_deref, &chunk); - - sratom_read(sratom, &forge, world->world, model, o); - const LV2_Atom* atom = (const LV2_Atom*)chunk.buf; - uint32_t flags = LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE; - Property prop = { NULL, 0, 0, 0, flags }; - - prop.key = map->map(map->handle, key); - prop.type = atom->type; - prop.size = atom->size; - prop.value = malloc(atom->size); - memcpy(prop.value, LV2_ATOM_BODY_CONST(atom), atom->size); - if (atom->type == forge.Path) { - prop.flags = LV2_STATE_IS_POD; - } - - if (prop.value) { - state->props.props = (Property*)realloc( - state->props.props, (++state->props.n) * sizeof(Property)); - state->props.props[state->props.n - 1] = prop; - } - } - sord_iter_free(props); - } - sord_node_free(world->world, state_node); - sord_node_free(world->world, statep); - - serd_free((void*)chunk.buf); - sratom_free(sratom); - - if (state->props.props) { - qsort(state->props.props, state->props.n, sizeof(Property), property_cmp); - } - if (state->values) { - qsort(state->values, state->n_values, sizeof(PortValue), value_cmp); - } - - return state; + // Check that we know at least something about this state subject + if (!sord_ask(model, node, 0, 0, 0)) { + return NULL; + } + + // Allocate state + LilvState* const state = (LilvState*)calloc(1, sizeof(LilvState)); + state->dir = lilv_path_join(dir, NULL); + state->atom_Path = map->map(map->handle, LV2_ATOM__Path); + state->uri = lilv_node_new_from_node(world, node); + + // Get the plugin URI this state applies to + SordIter* i = sord_search(model, node, world->uris.lv2_appliesTo, 0, 0); + if (i) { + const SordNode* object = sord_iter_get_node(i, SORD_OBJECT); + const SordNode* graph = sord_iter_get_node(i, SORD_GRAPH); + state->plugin_uri = lilv_node_new_from_node(world, object); + set_state_dir_from_model(state, graph); + sord_iter_free(i); + } else if (sord_ask( + model, node, world->uris.rdf_a, world->uris.lv2_Plugin, 0)) { + // Loading plugin description as state (default state) + state->plugin_uri = lilv_node_new_from_node(world, node); + } else { + LILV_ERRORF("State %s missing lv2:appliesTo property\n", + sord_node_get_string(node)); + } + + // Get the state label + i = sord_search(model, node, world->uris.rdfs_label, NULL, NULL); + if (i) { + const SordNode* object = sord_iter_get_node(i, SORD_OBJECT); + const SordNode* graph = sord_iter_get_node(i, SORD_GRAPH); + state->label = lilv_strdup((const char*)sord_node_get_string(object)); + set_state_dir_from_model(state, graph); + sord_iter_free(i); + } + + Sratom* sratom = sratom_new(map); + SerdChunk chunk = {NULL, 0}; + LV2_Atom_Forge forge; + lv2_atom_forge_init(&forge, map); + lv2_atom_forge_set_sink( + &forge, sratom_forge_sink, sratom_forge_deref, &chunk); + + // Get port values + SordIter* ports = sord_search(model, node, world->uris.lv2_port, 0, 0); + FOREACH_MATCH (ports) { + const SordNode* port = sord_iter_get_node(ports, SORD_OBJECT); + + SordNode* label = sord_get(model, port, world->uris.rdfs_label, 0, 0); + SordNode* symbol = sord_get(model, port, world->uris.lv2_symbol, 0, 0); + SordNode* value = sord_get(model, port, world->uris.pset_value, 0, 0); + if (!value) { + value = sord_get(model, port, world->uris.lv2_default, 0, 0); + } + if (!symbol) { + LILV_ERRORF("State `%s' port missing symbol.\n", + sord_node_get_string(node)); + } else if (value) { + chunk.len = 0; + sratom_read(sratom, &forge, world->world, model, value); + const LV2_Atom* atom = (const LV2_Atom*)chunk.buf; + + append_port_value(state, + (const char*)sord_node_get_string(symbol), + LV2_ATOM_BODY_CONST(atom), + atom->size, + atom->type); + + if (label) { + lilv_state_set_label(state, (const char*)sord_node_get_string(label)); + } + } + sord_node_free(world->world, value); + sord_node_free(world->world, symbol); + sord_node_free(world->world, label); + } + sord_iter_free(ports); + + // Get properties + SordNode* statep = sord_new_uri(world->world, USTR(LV2_STATE__state)); + SordNode* state_node = sord_get(model, node, statep, NULL, NULL); + if (state_node) { + SordIter* props = sord_search(model, state_node, 0, 0, 0); + FOREACH_MATCH (props) { + const SordNode* p = sord_iter_get_node(props, SORD_PREDICATE); + const SordNode* o = sord_iter_get_node(props, SORD_OBJECT); + const char* key = (const char*)sord_node_get_string(p); + + chunk.len = 0; + lv2_atom_forge_set_sink( + &forge, sratom_forge_sink, sratom_forge_deref, &chunk); + + sratom_read(sratom, &forge, world->world, model, o); + const LV2_Atom* atom = (const LV2_Atom*)chunk.buf; + uint32_t flags = LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE; + Property prop = {NULL, 0, 0, 0, flags}; + + prop.key = map->map(map->handle, key); + prop.type = atom->type; + prop.size = atom->size; + prop.value = malloc(atom->size); + memcpy(prop.value, LV2_ATOM_BODY_CONST(atom), atom->size); + if (atom->type == forge.Path) { + prop.flags = LV2_STATE_IS_POD; + } + + if (prop.value) { + state->props.props = (Property*)realloc( + state->props.props, (++state->props.n) * sizeof(Property)); + state->props.props[state->props.n - 1] = prop; + } + } + sord_iter_free(props); + } + sord_node_free(world->world, state_node); + sord_node_free(world->world, statep); + + serd_free((void*)chunk.buf); + sratom_free(sratom); + + if (state->props.props) { + qsort(state->props.props, state->props.n, sizeof(Property), property_cmp); + } + if (state->values) { + qsort(state->values, state->n_values, sizeof(PortValue), value_cmp); + } + + return state; } LilvState* @@ -710,13 +713,13 @@ lilv_state_new_from_world(LilvWorld* world, LV2_URID_Map* map, const LilvNode* node) { - if (!lilv_node_is_uri(node) && !lilv_node_is_blank(node)) { - LILV_ERRORF("Subject `%s' is not a URI or blank node.\n", - lilv_node_as_string(node)); - return NULL; - } + if (!lilv_node_is_uri(node) && !lilv_node_is_blank(node)) { + LILV_ERRORF("Subject `%s' is not a URI or blank node.\n", + lilv_node_as_string(node)); + return NULL; + } - return new_state_from_model(world, map, world->model, node->node, NULL); + return new_state_from_model(world, map, world->model, node->node, NULL); } LilvState* @@ -725,127 +728,123 @@ lilv_state_new_from_file(LilvWorld* world, const LilvNode* subject, const char* path) { - if (subject && !lilv_node_is_uri(subject) - && !lilv_node_is_blank(subject)) { - LILV_ERRORF("Subject `%s' is not a URI or blank node.\n", - lilv_node_as_string(subject)); - return NULL; - } - - uint8_t* abs_path = (uint8_t*)lilv_path_absolute(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); - SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); - - serd_reader_read_file(reader, node.buf); - - SordNode* subject_node = (subject) - ? subject->node - : 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* dir_path = lilv_path_join(real_path, NULL); - LilvState* state = - new_state_from_model(world, map, model, subject_node, dir_path); - free(dir_path); - free(real_path); - free(dirname); - - serd_node_free(&node); - free(abs_path); - serd_reader_free(reader); - sord_free(model); - serd_env_free(env); - return state; + if (subject && !lilv_node_is_uri(subject) && !lilv_node_is_blank(subject)) { + LILV_ERRORF("Subject `%s' is not a URI or blank node.\n", + lilv_node_as_string(subject)); + return NULL; + } + + uint8_t* abs_path = (uint8_t*)lilv_path_absolute(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); + SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); + + serd_reader_read_file(reader, node.buf); + + SordNode* subject_node = + (subject) ? subject->node + : 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* dir_path = lilv_path_join(real_path, NULL); + LilvState* state = + new_state_from_model(world, map, model, subject_node, dir_path); + free(dir_path); + free(real_path); + free(dirname); + + serd_node_free(&node); + free(abs_path); + serd_reader_free(reader); + sord_free(model); + serd_env_free(env); + return state; } static void set_prefixes(SerdEnv* env) { #define SET_PSET(e, p, u) serd_env_set_prefix_from_strings(e, p, u) - SET_PSET(env, USTR("atom"), USTR(LV2_ATOM_PREFIX)); - SET_PSET(env, USTR("lv2"), USTR(LV2_CORE_PREFIX)); - SET_PSET(env, USTR("pset"), USTR(LV2_PRESETS_PREFIX)); - SET_PSET(env, USTR("rdf"), USTR(LILV_NS_RDF)); - SET_PSET(env, USTR("rdfs"), USTR(LILV_NS_RDFS)); - SET_PSET(env, USTR("state"), USTR(LV2_STATE_PREFIX)); - SET_PSET(env, USTR("xsd"), USTR(LILV_NS_XSD)); + SET_PSET(env, USTR("atom"), USTR(LV2_ATOM_PREFIX)); + SET_PSET(env, USTR("lv2"), USTR(LV2_CORE_PREFIX)); + SET_PSET(env, USTR("pset"), USTR(LV2_PRESETS_PREFIX)); + SET_PSET(env, USTR("rdf"), USTR(LILV_NS_RDF)); + SET_PSET(env, USTR("rdfs"), USTR(LILV_NS_RDFS)); + SET_PSET(env, USTR("state"), USTR(LV2_STATE_PREFIX)); + SET_PSET(env, USTR("xsd"), USTR(LILV_NS_XSD)); } LilvState* -lilv_state_new_from_string(LilvWorld* world, - LV2_URID_Map* map, - const char* str) +lilv_state_new_from_string(LilvWorld* world, LV2_URID_Map* map, const char* str) { - if (!str) { - return NULL; - } + if (!str) { + return NULL; + } - SerdNode base = SERD_NODE_NULL; - SerdEnv* env = serd_env_new(&base); - SordModel* model = sord_new(world->world, SORD_SPO|SORD_OPS, false); - SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); + SerdNode base = SERD_NODE_NULL; + SerdEnv* env = serd_env_new(&base); + SordModel* model = sord_new(world->world, SORD_SPO | SORD_OPS, false); + SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); - set_prefixes(env); - serd_reader_read_string(reader, USTR(str)); + set_prefixes(env); + serd_reader_read_string(reader, USTR(str)); - SordNode* o = sord_new_uri(world->world, USTR(LV2_PRESETS__Preset)); - SordNode* s = sord_get(model, NULL, world->uris.rdf_a, o, NULL); + SordNode* o = sord_new_uri(world->world, USTR(LV2_PRESETS__Preset)); + SordNode* s = sord_get(model, NULL, world->uris.rdf_a, o, NULL); - LilvState* state = new_state_from_model(world, map, model, s, NULL); + LilvState* state = new_state_from_model(world, map, model, s, NULL); - sord_node_free(world->world, s); - sord_node_free(world->world, o); - serd_reader_free(reader); - sord_free(model); - serd_env_free(env); + sord_node_free(world->world, s); + sord_node_free(world->world, o); + serd_reader_free(reader); + sord_free(model); + serd_env_free(env); - return state; + return state; } static SerdWriter* ttl_writer(SerdSink sink, void* stream, const SerdNode* base, SerdEnv** new_env) { - SerdURI base_uri = SERD_URI_NULL; - if (base && base->buf) { - serd_uri_parse(base->buf, &base_uri); - } - - SerdEnv* env = *new_env ? *new_env : serd_env_new(base); - set_prefixes(env); - - SerdWriter* writer = serd_writer_new( - SERD_TURTLE, - (SerdStyle)(SERD_STYLE_RESOLVED | - SERD_STYLE_ABBREVIATED| - SERD_STYLE_CURIED), - env, - &base_uri, - sink, - stream); - - if (!*new_env) { - *new_env = env; - } - - return writer; + SerdURI base_uri = SERD_URI_NULL; + if (base && base->buf) { + serd_uri_parse(base->buf, &base_uri); + } + + SerdEnv* env = *new_env ? *new_env : serd_env_new(base); + set_prefixes(env); + + SerdWriter* writer = + serd_writer_new(SERD_TURTLE, + (SerdStyle)(SERD_STYLE_RESOLVED | SERD_STYLE_ABBREVIATED | + SERD_STYLE_CURIED), + env, + &base_uri, + sink, + stream); + + if (!*new_env) { + *new_env = env; + } + + return writer; } static SerdWriter* ttl_file_writer(FILE* fd, const SerdNode* node, SerdEnv** env) { - SerdWriter* writer = ttl_writer(serd_file_sink, fd, node, env); + SerdWriter* writer = ttl_writer(serd_file_sink, fd, node, env); - fseek(fd, 0, SEEK_END); - if (ftell(fd) == 0) { - serd_env_foreach(*env, (SerdPrefixSink)serd_writer_set_prefix, writer); - } else { - fprintf(fd, "\n"); - } + fseek(fd, 0, SEEK_END); + if (ftell(fd) == 0) { + serd_env_foreach(*env, (SerdPrefixSink)serd_writer_set_prefix, writer); + } else { + fprintf(fd, "\n"); + } - return writer; + return writer; } static void @@ -856,28 +855,28 @@ add_to_model(SordWorld* world, const SerdNode p, const SerdNode o) { - SordNode* ss = sord_node_from_serd_node(world, env, &s, NULL, NULL); - SordNode* sp = sord_node_from_serd_node(world, env, &p, NULL, NULL); - SordNode* so = sord_node_from_serd_node(world, env, &o, NULL, NULL); + SordNode* ss = sord_node_from_serd_node(world, env, &s, NULL, NULL); + SordNode* sp = sord_node_from_serd_node(world, env, &p, NULL, NULL); + SordNode* so = sord_node_from_serd_node(world, env, &o, NULL, NULL); - SordQuad quad = { ss, sp, so, NULL }; - sord_add(model, quad); + SordQuad quad = {ss, sp, so, NULL}; + sord_add(model, quad); - sord_node_free(world, ss); - sord_node_free(world, sp); - sord_node_free(world, so); + sord_node_free(world, ss); + sord_node_free(world, sp); + sord_node_free(world, so); } static void remove_manifest_entry(SordWorld* world, SordModel* model, const char* subject) { - SordNode* s = sord_new_uri(world, USTR(subject)); - SordIter* i = sord_search(model, s, NULL, NULL, NULL); - while (!sord_iter_end(i)) { - sord_erase(model, i); - } - sord_iter_free(i); - sord_node_free(world, s); + SordNode* s = sord_new_uri(world, USTR(subject)); + SordIter* i = sord_search(model, s, NULL, NULL, NULL); + while (!sord_iter_end(i)) { + sord_erase(model, i); + } + sord_iter_free(i); + sord_node_free(world, s); } static int @@ -886,22 +885,21 @@ write_manifest(LilvWorld* world, SordModel* model, const SerdNode* file_uri) { - char* const path = (char*)serd_file_uri_parse(file_uri->buf, NULL); - FILE* const wfd = fopen(path, "w"); - if (!wfd) { - LILV_ERRORF("Failed to open %s for writing (%s)\n", - path, strerror(errno)); - - serd_free(path); - return 1; - } - - SerdWriter* writer = ttl_file_writer(wfd, file_uri, &env); - sord_write(model, writer, NULL); - serd_writer_free(writer); - fclose(wfd); - serd_free(path); - return 0; + char* const path = (char*)serd_file_uri_parse(file_uri->buf, NULL); + FILE* const wfd = fopen(path, "w"); + if (!wfd) { + LILV_ERRORF("Failed to open %s for writing (%s)\n", path, strerror(errno)); + + serd_free(path); + return 1; + } + + SerdWriter* writer = ttl_file_writer(wfd, file_uri, &env); + sord_write(model, writer, NULL); + serd_writer_free(writer); + fclose(wfd); + serd_free(path); + return 0; } static int @@ -911,114 +909,119 @@ add_state_to_manifest(LilvWorld* lworld, const char* state_uri, const char* state_path) { - SordWorld* world = lworld->world; - SerdNode manifest = serd_node_new_file_uri(USTR(manifest_path), 0, 0, 1); - SerdNode file = serd_node_new_file_uri(USTR(state_path), 0, 0, 1); - SerdEnv* env = serd_env_new(&manifest); - SordModel* model = sord_new(world, SORD_SPO, false); - - if (lilv_path_exists(manifest_path)) { - // Read manifest into model - SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); - SerdStatus st = serd_reader_read_file(reader, manifest.buf); - if (st) { - LILV_WARNF("Failed to read manifest (%s)\n", serd_strerror(st)); - } - serd_reader_free(reader); - } - - // Choose state URI (use file URI if not given) - if (!state_uri) { - state_uri = (const char*)file.buf; - } - - // Remove any existing manifest entries for this state - remove_manifest_entry(world, model, state_uri); - - // Add manifest entry for this state to model - SerdNode s = serd_node_from_string(SERD_URI, USTR(state_uri)); - - // <state> a pset:Preset - add_to_model(world, env, model, - s, - serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type")), - serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset))); - - // <state> a pset:Preset - add_to_model(world, env, model, - s, - serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type")), - serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset))); - - // <state> rdfs:seeAlso <file> - add_to_model(world, env, model, - s, - serd_node_from_string(SERD_URI, USTR(LILV_NS_RDFS "seeAlso")), - file); - - // <state> lv2:appliesTo <plugin> - add_to_model(world, env, model, - s, - serd_node_from_string(SERD_URI, USTR(LV2_CORE__appliesTo)), - serd_node_from_string(SERD_URI, - USTR(lilv_node_as_string(plugin_uri)))); - - /* Re-open manifest for locked writing. We need to do this because it may - need to be truncated, and the file can only be open once on Windows. */ - - FILE* wfd = fopen(manifest_path, "wb"); - int r = 0; - if (!wfd) { - LILV_ERRORF("Failed to open %s for writing (%s)\n", - manifest_path, - strerror(errno)); - r = 1; - } - - SerdWriter* writer = ttl_file_writer(wfd, &manifest, &env); - lilv_flock(wfd, true, true); - sord_write(model, writer, NULL); - lilv_flock(wfd, false, true); - serd_writer_free(writer); - fclose(wfd); - - sord_free(model); - serd_node_free(&file); - serd_node_free(&manifest); - serd_env_free(env); - - return r; + SordWorld* world = lworld->world; + SerdNode manifest = serd_node_new_file_uri(USTR(manifest_path), 0, 0, 1); + SerdNode file = serd_node_new_file_uri(USTR(state_path), 0, 0, 1); + SerdEnv* env = serd_env_new(&manifest); + SordModel* model = sord_new(world, SORD_SPO, false); + + if (lilv_path_exists(manifest_path)) { + // Read manifest into model + SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); + SerdStatus st = serd_reader_read_file(reader, manifest.buf); + if (st) { + LILV_WARNF("Failed to read manifest (%s)\n", serd_strerror(st)); + } + serd_reader_free(reader); + } + + // Choose state URI (use file URI if not given) + if (!state_uri) { + state_uri = (const char*)file.buf; + } + + // Remove any existing manifest entries for this state + remove_manifest_entry(world, model, state_uri); + + // Add manifest entry for this state to model + SerdNode s = serd_node_from_string(SERD_URI, USTR(state_uri)); + + // <state> a pset:Preset + add_to_model(world, + env, + model, + s, + serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type")), + serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset))); + + // <state> a pset:Preset + add_to_model(world, + env, + model, + s, + serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type")), + serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset))); + + // <state> rdfs:seeAlso <file> + add_to_model(world, + env, + model, + s, + serd_node_from_string(SERD_URI, USTR(LILV_NS_RDFS "seeAlso")), + file); + + // <state> lv2:appliesTo <plugin> + add_to_model( + world, + env, + model, + s, + serd_node_from_string(SERD_URI, USTR(LV2_CORE__appliesTo)), + serd_node_from_string(SERD_URI, USTR(lilv_node_as_string(plugin_uri)))); + + /* Re-open manifest for locked writing. We need to do this because it may + need to be truncated, and the file can only be open once on Windows. */ + + FILE* wfd = fopen(manifest_path, "wb"); + int r = 0; + if (!wfd) { + LILV_ERRORF( + "Failed to open %s for writing (%s)\n", manifest_path, strerror(errno)); + r = 1; + } + + SerdWriter* writer = ttl_file_writer(wfd, &manifest, &env); + lilv_flock(wfd, true, true); + sord_write(model, writer, NULL); + lilv_flock(wfd, false, true); + serd_writer_free(writer); + fclose(wfd); + + sord_free(model); + serd_node_free(&file); + serd_node_free(&manifest); + serd_env_free(env); + + return r; } static bool link_exists(const char* path, const void* data) { - const char* target = (const char*)data; - if (!lilv_path_exists(path)) { - return false; - } - char* real_path = lilv_path_canonical(path); - bool matches = !strcmp(real_path, target); - free(real_path); - return !matches; + const char* target = (const char*)data; + if (!lilv_path_exists(path)) { + return false; + } + char* real_path = lilv_path_canonical(path); + bool matches = !strcmp(real_path, target); + free(real_path); + return !matches; } static int maybe_symlink(const char* oldpath, const char* newpath) { - if (link_exists(newpath, oldpath)) { - return 0; - } - - const int st = lilv_symlink(oldpath, newpath); - if (st) { - LILV_ERRORF("Failed to link %s => %s (%s)\n", - newpath, - oldpath, - strerror(errno)); - } - - return st; + if (link_exists(newpath, oldpath)) { + return 0; + } + + const int st = lilv_symlink(oldpath, newpath); + if (st) { + LILV_ERRORF( + "Failed to link %s => %s (%s)\n", newpath, oldpath, strerror(errno)); + } + + return st; } static void @@ -1030,26 +1033,31 @@ write_property_array(const LilvState* state, LV2_URID_Unmap* unmap, const char* dir) { - for (uint32_t i = 0; i < array->n; ++i) { - Property* prop = &array->props[i]; - const char* key = unmap->unmap(unmap->handle, prop->key); - - const SerdNode p = serd_node_from_string(SERD_URI, USTR(key)); - if (prop->type == state->atom_Path && !dir) { - const char* path = (const char*)prop->value; - const char* abs_path = lilv_state_rel2abs(state, path); - LILV_WARNF("Writing absolute path %s\n", abs_path); - sratom_write(sratom, unmap, flags, - subject, &p, prop->type, - strlen(abs_path) + 1, abs_path); - } else if (prop->flags & LV2_STATE_IS_POD || - prop->type == state->atom_Path) { - sratom_write(sratom, unmap, flags, - subject, &p, prop->type, prop->size, prop->value); - } else { - LILV_WARNF("Lost non-POD property <%s> on save\n", key); - } - } + for (uint32_t i = 0; i < array->n; ++i) { + Property* prop = &array->props[i]; + const char* key = unmap->unmap(unmap->handle, prop->key); + + const SerdNode p = serd_node_from_string(SERD_URI, USTR(key)); + if (prop->type == state->atom_Path && !dir) { + const char* path = (const char*)prop->value; + const char* abs_path = lilv_state_rel2abs(state, path); + LILV_WARNF("Writing absolute path %s\n", abs_path); + sratom_write(sratom, + unmap, + flags, + subject, + &p, + prop->type, + strlen(abs_path) + 1, + abs_path); + } else if (prop->flags & LV2_STATE_IS_POD || + prop->type == state->atom_Path) { + sratom_write( + sratom, unmap, flags, subject, &p, prop->type, prop->size, prop->value); + } else { + LILV_WARNF("Lost non-POD property <%s> on save\n", key); + } + } } static int @@ -1061,137 +1069,139 @@ lilv_state_write(LilvWorld* world, const char* uri, const char* dir) { - SerdNode lv2_appliesTo = serd_node_from_string( - SERD_CURIE, USTR("lv2:appliesTo")); - - const SerdNode* plugin_uri = sord_node_to_serd_node( - state->plugin_uri->node); - - SerdNode subject = serd_node_from_string(SERD_URI, USTR(uri ? uri : "")); - - // <subject> a pset:Preset - SerdNode p = serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type")); - SerdNode o = serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset)); - serd_writer_write_statement(writer, 0, NULL, - &subject, &p, &o, NULL, NULL); - - // <subject> lv2:appliesTo <http://example.org/plugin> - serd_writer_write_statement(writer, 0, NULL, - &subject, - &lv2_appliesTo, - plugin_uri, NULL, NULL); - - // <subject> rdfs:label label - if (state->label) { - p = serd_node_from_string(SERD_URI, USTR(LILV_NS_RDFS "label")); - o = serd_node_from_string(SERD_LITERAL, USTR(state->label)); - serd_writer_write_statement(writer, 0, - NULL, &subject, &p, &o, NULL, NULL); - } - - SerdEnv* env = serd_writer_get_env(writer); - const SerdNode* base = serd_env_get_base_uri(env, NULL); - - Sratom* sratom = sratom_new(map); - sratom_set_sink(sratom, (const char*)base->buf, - (SerdStatementSink)serd_writer_write_statement, - (SerdEndSink)serd_writer_end_anon, - writer); - - // Write metadata - sratom_set_pretty_numbers(sratom, false); // Use precise types - write_property_array(state, &state->metadata, sratom, 0, - &subject, unmap, dir); - - // Write port values - sratom_set_pretty_numbers(sratom, true); // Use pretty numbers - for (uint32_t i = 0; i < state->n_values; ++i) { - PortValue* const value = &state->values[i]; - - const SerdNode port = serd_node_from_string( - SERD_BLANK, USTR(value->symbol)); - - // <> lv2:port _:symbol - p = serd_node_from_string(SERD_URI, USTR(LV2_CORE__port)); - serd_writer_write_statement(writer, SERD_ANON_O_BEGIN, - NULL, &subject, &p, &port, NULL, NULL); - - // _:symbol lv2:symbol "symbol" - p = serd_node_from_string(SERD_URI, USTR(LV2_CORE__symbol)); - o = serd_node_from_string(SERD_LITERAL, USTR(value->symbol)); - serd_writer_write_statement(writer, SERD_ANON_CONT, - NULL, &port, &p, &o, NULL, NULL); - - // _:symbol pset:value value - p = serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__value)); - sratom_write(sratom, unmap, SERD_ANON_CONT, &port, &p, - value->atom->type, value->atom->size, value->atom + 1); - - serd_writer_end_anon(writer, &port); - } - - // Write properties - const SerdNode body = serd_node_from_string(SERD_BLANK, USTR("body")); - if (state->props.n > 0) { - p = serd_node_from_string(SERD_URI, USTR(LV2_STATE__state)); - serd_writer_write_statement(writer, SERD_ANON_O_BEGIN, NULL, - &subject, &p, &body, NULL, NULL); - } - sratom_set_pretty_numbers(sratom, false); // Use precise types - write_property_array(state, &state->props, sratom, SERD_ANON_CONT, - &body, unmap, dir); - - if (state->props.n > 0) { - serd_writer_end_anon(writer, &body); - } - - sratom_free(sratom); - return 0; + SerdNode lv2_appliesTo = + serd_node_from_string(SERD_CURIE, USTR("lv2:appliesTo")); + + const SerdNode* plugin_uri = sord_node_to_serd_node(state->plugin_uri->node); + + SerdNode subject = serd_node_from_string(SERD_URI, USTR(uri ? uri : "")); + + // <subject> a pset:Preset + SerdNode p = serd_node_from_string(SERD_URI, USTR(LILV_NS_RDF "type")); + SerdNode o = serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__Preset)); + serd_writer_write_statement(writer, 0, NULL, &subject, &p, &o, NULL, NULL); + + // <subject> lv2:appliesTo <http://example.org/plugin> + serd_writer_write_statement( + writer, 0, NULL, &subject, &lv2_appliesTo, plugin_uri, NULL, NULL); + + // <subject> rdfs:label label + if (state->label) { + p = serd_node_from_string(SERD_URI, USTR(LILV_NS_RDFS "label")); + o = serd_node_from_string(SERD_LITERAL, USTR(state->label)); + serd_writer_write_statement(writer, 0, NULL, &subject, &p, &o, NULL, NULL); + } + + SerdEnv* env = serd_writer_get_env(writer); + const SerdNode* base = serd_env_get_base_uri(env, NULL); + + Sratom* sratom = sratom_new(map); + sratom_set_sink(sratom, + (const char*)base->buf, + (SerdStatementSink)serd_writer_write_statement, + (SerdEndSink)serd_writer_end_anon, + writer); + + // Write metadata + sratom_set_pretty_numbers(sratom, false); // Use precise types + write_property_array( + state, &state->metadata, sratom, 0, &subject, unmap, dir); + + // Write port values + sratom_set_pretty_numbers(sratom, true); // Use pretty numbers + for (uint32_t i = 0; i < state->n_values; ++i) { + PortValue* const value = &state->values[i]; + + const SerdNode port = + serd_node_from_string(SERD_BLANK, USTR(value->symbol)); + + // <> lv2:port _:symbol + p = serd_node_from_string(SERD_URI, USTR(LV2_CORE__port)); + serd_writer_write_statement( + writer, SERD_ANON_O_BEGIN, NULL, &subject, &p, &port, NULL, NULL); + + // _:symbol lv2:symbol "symbol" + p = serd_node_from_string(SERD_URI, USTR(LV2_CORE__symbol)); + o = serd_node_from_string(SERD_LITERAL, USTR(value->symbol)); + serd_writer_write_statement( + writer, SERD_ANON_CONT, NULL, &port, &p, &o, NULL, NULL); + + // _:symbol pset:value value + p = serd_node_from_string(SERD_URI, USTR(LV2_PRESETS__value)); + sratom_write(sratom, + unmap, + SERD_ANON_CONT, + &port, + &p, + value->atom->type, + value->atom->size, + value->atom + 1); + + serd_writer_end_anon(writer, &port); + } + + // Write properties + const SerdNode body = serd_node_from_string(SERD_BLANK, USTR("body")); + if (state->props.n > 0) { + p = serd_node_from_string(SERD_URI, USTR(LV2_STATE__state)); + serd_writer_write_statement( + writer, SERD_ANON_O_BEGIN, NULL, &subject, &p, &body, NULL, NULL); + } + sratom_set_pretty_numbers(sratom, false); // Use precise types + write_property_array( + state, &state->props, sratom, SERD_ANON_CONT, &body, unmap, dir); + + if (state->props.n > 0) { + serd_writer_end_anon(writer, &body); + } + + sratom_free(sratom); + return 0; } static void lilv_state_make_links(const LilvState* state, const char* dir) { - // Create symlinks to files - 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_absolute_child(pm->rel, dir); - if (lilv_path_is_child(pm->abs, state->copy_dir) - && strcmp(state->copy_dir, dir)) { - // Link directly to snapshot in the copy directory - maybe_symlink(pm->abs, path); - } else if (!lilv_path_is_child(pm->abs, dir)) { - const char* link_dir = state->link_dir ? state->link_dir : dir; - char* pat = lilv_path_absolute_child(pm->rel, link_dir); - if (!strcmp(dir, link_dir)) { - // Link directory is save directory, make link at exact path - remove(pat); - maybe_symlink(pm->abs, pat); - } else { - // Make a link in the link directory to external file - char* lpath = lilv_find_free_path(pat, link_exists, pm->abs); - if (!lilv_path_exists(lpath)) { - if (lilv_symlink(pm->abs, lpath)) { - LILV_ERRORF("Failed to link %s => %s (%s)\n", - pm->abs, - lpath, - strerror(errno)); - } - } - - // Make a link in the save directory to the external link - char* target = lilv_path_relative_to(lpath, dir); - maybe_symlink(lpath, path); - free(target); - free(lpath); - } - free(pat); - } - free(path); - } + // Create symlinks to files + 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_absolute_child(pm->rel, dir); + if (lilv_path_is_child(pm->abs, state->copy_dir) && + strcmp(state->copy_dir, dir)) { + // Link directly to snapshot in the copy directory + maybe_symlink(pm->abs, path); + } else if (!lilv_path_is_child(pm->abs, dir)) { + const char* link_dir = state->link_dir ? state->link_dir : dir; + char* pat = lilv_path_absolute_child(pm->rel, link_dir); + if (!strcmp(dir, link_dir)) { + // Link directory is save directory, make link at exact path + remove(pat); + maybe_symlink(pm->abs, pat); + } else { + // Make a link in the link directory to external file + char* lpath = lilv_find_free_path(pat, link_exists, pm->abs); + if (!lilv_path_exists(lpath)) { + if (lilv_symlink(pm->abs, lpath)) { + LILV_ERRORF("Failed to link %s => %s (%s)\n", + pm->abs, + lpath, + strerror(errno)); + } + } + + // Make a link in the save directory to the external link + char* target = lilv_path_relative_to(lpath, dir); + maybe_symlink(lpath, path); + free(target); + free(lpath); + } + free(pat); + } + free(path); + } } int @@ -1203,55 +1213,54 @@ lilv_state_save(LilvWorld* world, const char* dir, const char* filename) { - if (!filename || !dir || lilv_create_directories(dir)) { - return 1; - } - - char* abs_dir = real_dir(dir); - char* const path = lilv_path_join(abs_dir, filename); - FILE* fd = fopen(path, "w"); - if (!fd) { - LILV_ERRORF("Failed to open %s (%s)\n", path, strerror(errno)); - free(abs_dir); - free(path); - return 4; - } - - // Create symlinks to files if necessary - lilv_state_make_links(state, abs_dir); - - // Write state to Turtle file - SerdNode file = serd_node_new_file_uri(USTR(path), NULL, NULL, true); - SerdNode node = uri ? serd_node_from_string(SERD_URI, USTR(uri)) : file; - SerdEnv* env = NULL; - SerdWriter* ttl = ttl_file_writer(fd, &file, &env); - int ret = lilv_state_write( - world, map, unmap, state, ttl, (const char*)node.buf, dir); - - // Set saved dir and uri (FIXME: const violation) - free(state->dir); - lilv_node_free(state->uri); - ((LilvState*)state)->dir = lilv_strdup(abs_dir); - ((LilvState*)state)->uri = lilv_new_uri(world, (const char*)node.buf); - - serd_node_free(&file); - serd_writer_free(ttl); - serd_env_free(env); - fclose(fd); - - // Add entry to manifest - if (!ret) { - char* const manifest = lilv_path_join(abs_dir, "manifest.ttl"); - - ret = add_state_to_manifest( - world, state->plugin_uri, manifest, uri, path); - - free(manifest); - } - - free(abs_dir); - free(path); - return ret; + if (!filename || !dir || lilv_create_directories(dir)) { + return 1; + } + + char* abs_dir = real_dir(dir); + char* const path = lilv_path_join(abs_dir, filename); + FILE* fd = fopen(path, "w"); + if (!fd) { + LILV_ERRORF("Failed to open %s (%s)\n", path, strerror(errno)); + free(abs_dir); + free(path); + return 4; + } + + // Create symlinks to files if necessary + lilv_state_make_links(state, abs_dir); + + // Write state to Turtle file + SerdNode file = serd_node_new_file_uri(USTR(path), NULL, NULL, true); + SerdNode node = uri ? serd_node_from_string(SERD_URI, USTR(uri)) : file; + SerdEnv* env = NULL; + SerdWriter* ttl = ttl_file_writer(fd, &file, &env); + int ret = + lilv_state_write(world, map, unmap, state, ttl, (const char*)node.buf, dir); + + // Set saved dir and uri (FIXME: const violation) + free(state->dir); + lilv_node_free(state->uri); + ((LilvState*)state)->dir = lilv_strdup(abs_dir); + ((LilvState*)state)->uri = lilv_new_uri(world, (const char*)node.buf); + + serd_node_free(&file); + serd_writer_free(ttl); + serd_env_free(env); + fclose(fd); + + // Add entry to manifest + if (!ret) { + char* const manifest = lilv_path_join(abs_dir, "manifest.ttl"); + + ret = add_state_to_manifest(world, state->plugin_uri, manifest, uri, path); + + free(manifest); + } + + free(abs_dir); + free(path); + return ret; } char* @@ -1262,256 +1271,248 @@ lilv_state_to_string(LilvWorld* world, const char* uri, const char* base_uri) { - if (!uri) { - LILV_ERROR("Attempt to serialise state with no URI\n"); - return NULL; - } - - SerdChunk chunk = { NULL, 0 }; - SerdEnv* env = NULL; - SerdNode base = serd_node_from_string(SERD_URI, USTR(base_uri)); - SerdWriter* writer = ttl_writer(serd_chunk_sink, &chunk, &base, &env); - - lilv_state_write(world, map, unmap, state, writer, uri, NULL); - - serd_writer_free(writer); - serd_env_free(env); - char* str = (char*)serd_chunk_sink_finish(&chunk); - char* result = lilv_strdup(str); - serd_free(str); - return result; + if (!uri) { + LILV_ERROR("Attempt to serialise state with no URI\n"); + return NULL; + } + + SerdChunk chunk = {NULL, 0}; + SerdEnv* env = NULL; + SerdNode base = serd_node_from_string(SERD_URI, USTR(base_uri)); + SerdWriter* writer = ttl_writer(serd_chunk_sink, &chunk, &base, &env); + + lilv_state_write(world, map, unmap, state, writer, uri, NULL); + + serd_writer_free(writer); + serd_env_free(env); + char* str = (char*)serd_chunk_sink_finish(&chunk); + char* result = lilv_strdup(str); + serd_free(str); + return result; } static void try_unlink(const char* state_dir, const char* path) { - if (!strncmp(state_dir, path, strlen(state_dir))) { - if (lilv_path_exists(path) && lilv_remove(path)) { - LILV_ERRORF("Failed to remove %s (%s)\n", path, strerror(errno)); - } - } + if (!strncmp(state_dir, path, strlen(state_dir))) { + if (lilv_path_exists(path) && lilv_remove(path)) { + LILV_ERRORF("Failed to remove %s (%s)\n", path, strerror(errno)); + } + } } 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 path = lilv_node_get_path(node, NULL); + char* const real_path = lilv_path_canonical(path); - free(path); - return real_path; + free(path); + return real_path; } int -lilv_state_delete(LilvWorld* world, - const LilvState* state) +lilv_state_delete(LilvWorld* world, const LilvState* state) { - if (!state->dir) { - LILV_ERROR("Attempt to delete unsaved state\n"); - return -1; - } - - 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 = lilv_path_exists(manifest_path); - SordModel* model = sord_new(world->world, SORD_SPO, false); - - if (has_manifest) { - // Read manifest into temporary local model - SerdEnv* env = serd_env_new(sord_node_to_serd_node(manifest->node)); - SerdReader* ttl = sord_new_reader(model, env, SERD_TURTLE, NULL); - serd_reader_read_file(ttl, USTR(manifest_path)); - serd_reader_free(ttl); - serd_env_free(env); - } - - if (state->uri) { - SordNode* file = sord_get( - model, state->uri->node, world->uris.rdfs_seeAlso, NULL, NULL); - if (file) { - // 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) { - try_unlink(state->dir, real_path); - } - serd_free(real_path); - serd_free(path); - } - - // Remove any existing manifest entries for this state - const char* state_uri_str = lilv_node_as_string(state->uri); - remove_manifest_entry(world->world, model, state_uri_str); - remove_manifest_entry(world->world, world->model, state_uri_str); - } - - // Drop bundle from model - lilv_world_unload_bundle(world, bundle); - - if (sord_num_quads(model) == 0) { - // Manifest is empty, attempt to remove bundle entirely - if (has_manifest) { - try_unlink(state->dir, manifest_path); - } - - // Remove all known files from state bundle - 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 (lilv_remove(state->dir)) { - LILV_ERRORF("Failed to remove directory %s (%s)\n", - state->dir, strerror(errno)); - } - } else { - // Still something in the manifest, update and reload bundle - const SerdNode* manifest_node = sord_node_to_serd_node(manifest->node); - SerdEnv* env = serd_env_new(manifest_node); - - write_manifest(world, env, model, manifest_node); - lilv_world_load_bundle(world, bundle); - serd_env_free(env); - } - - sord_free(model); - lilv_free(manifest_path); - lilv_node_free(manifest); - lilv_node_free(bundle); - - return 0; + if (!state->dir) { + LILV_ERROR("Attempt to delete unsaved state\n"); + return -1; + } + + 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 = lilv_path_exists(manifest_path); + SordModel* model = sord_new(world->world, SORD_SPO, false); + + if (has_manifest) { + // Read manifest into temporary local model + SerdEnv* env = serd_env_new(sord_node_to_serd_node(manifest->node)); + SerdReader* ttl = sord_new_reader(model, env, SERD_TURTLE, NULL); + serd_reader_read_file(ttl, USTR(manifest_path)); + serd_reader_free(ttl); + serd_env_free(env); + } + + if (state->uri) { + SordNode* file = + sord_get(model, state->uri->node, world->uris.rdfs_seeAlso, NULL, NULL); + if (file) { + // 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) { + try_unlink(state->dir, real_path); + } + serd_free(real_path); + serd_free(path); + } + + // Remove any existing manifest entries for this state + const char* state_uri_str = lilv_node_as_string(state->uri); + remove_manifest_entry(world->world, model, state_uri_str); + remove_manifest_entry(world->world, world->model, state_uri_str); + } + + // Drop bundle from model + lilv_world_unload_bundle(world, bundle); + + if (sord_num_quads(model) == 0) { + // Manifest is empty, attempt to remove bundle entirely + if (has_manifest) { + try_unlink(state->dir, manifest_path); + } + + // Remove all known files from state bundle + 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 (lilv_remove(state->dir)) { + LILV_ERRORF( + "Failed to remove directory %s (%s)\n", state->dir, strerror(errno)); + } + } else { + // Still something in the manifest, update and reload bundle + const SerdNode* manifest_node = sord_node_to_serd_node(manifest->node); + SerdEnv* env = serd_env_new(manifest_node); + + write_manifest(world, env, model, manifest_node); + lilv_world_load_bundle(world, bundle); + serd_env_free(env); + } + + sord_free(model); + lilv_free(manifest_path); + lilv_node_free(manifest); + lilv_node_free(bundle); + + return 0; } static void free_property_array(LilvState* state, PropertyArray* array) { - for (uint32_t i = 0; i < array->n; ++i) { - Property* prop = &array->props[i]; - if ((prop->flags & LV2_STATE_IS_POD) || - prop->type == state->atom_Path) { - free(prop->value); - } - } - free(array->props); + for (uint32_t i = 0; i < array->n; ++i) { + Property* prop = &array->props[i]; + if ((prop->flags & LV2_STATE_IS_POD) || prop->type == state->atom_Path) { + free(prop->value); + } + } + free(array->props); } void lilv_state_free(LilvState* state) { - if (state) { - free_property_array(state, &state->props); - free_property_array(state, &state->metadata); - for (uint32_t i = 0; i < state->n_values; ++i) { - free(state->values[i].atom); - free(state->values[i].symbol); - } - lilv_node_free(state->plugin_uri); - lilv_node_free(state->uri); - zix_tree_free(state->abs2rel); - zix_tree_free(state->rel2abs); - free(state->values); - free(state->label); - free(state->dir); - free(state->scratch_dir); - free(state->copy_dir); - free(state->link_dir); - free(state); - } + if (state) { + free_property_array(state, &state->props); + free_property_array(state, &state->metadata); + for (uint32_t i = 0; i < state->n_values; ++i) { + free(state->values[i].atom); + free(state->values[i].symbol); + } + lilv_node_free(state->plugin_uri); + lilv_node_free(state->uri); + zix_tree_free(state->abs2rel); + zix_tree_free(state->rel2abs); + free(state->values); + free(state->label); + free(state->dir); + free(state->scratch_dir); + free(state->copy_dir); + free(state->link_dir); + free(state); + } } bool lilv_state_equals(const LilvState* a, const LilvState* b) { - if (!lilv_node_equals(a->plugin_uri, b->plugin_uri) - || (a->label && !b->label) - || (b->label && !a->label) - || (a->label && b->label && strcmp(a->label, b->label)) - || a->props.n != b->props.n - || a->n_values != b->n_values) { - return false; - } - - for (uint32_t i = 0; i < a->n_values; ++i) { - PortValue* const av = &a->values[i]; - PortValue* const bv = &b->values[i]; - if (av->atom->size != bv->atom->size || - av->atom->type != bv->atom->type || - strcmp(av->symbol, bv->symbol) || - memcmp(av->atom + 1, bv->atom + 1, av->atom->size)) { - return false; - } - } - - for (uint32_t i = 0; i < a->props.n; ++i) { - Property* const ap = &a->props.props[i]; - Property* const bp = &b->props.props[i]; - if (ap->key != bp->key - || ap->type != bp->type - || ap->flags != bp->flags) { - return false; - } - - if (ap->type == a->atom_Path) { - if (!lilv_file_equals(lilv_state_rel2abs(a, (char*)ap->value), - lilv_state_rel2abs(b, (char*)bp->value))) { - return false; - } - } else if (ap->size != bp->size - || memcmp(ap->value, bp->value, ap->size)) { - return false; - } - } - - return true; + if (!lilv_node_equals(a->plugin_uri, b->plugin_uri) || + (a->label && !b->label) || (b->label && !a->label) || + (a->label && b->label && strcmp(a->label, b->label)) || + a->props.n != b->props.n || a->n_values != b->n_values) { + return false; + } + + for (uint32_t i = 0; i < a->n_values; ++i) { + PortValue* const av = &a->values[i]; + PortValue* const bv = &b->values[i]; + if (av->atom->size != bv->atom->size || av->atom->type != bv->atom->type || + strcmp(av->symbol, bv->symbol) || + memcmp(av->atom + 1, bv->atom + 1, av->atom->size)) { + return false; + } + } + + for (uint32_t i = 0; i < a->props.n; ++i) { + Property* const ap = &a->props.props[i]; + Property* const bp = &b->props.props[i]; + if (ap->key != bp->key || ap->type != bp->type || ap->flags != bp->flags) { + return false; + } + + if (ap->type == a->atom_Path) { + if (!lilv_file_equals(lilv_state_rel2abs(a, (char*)ap->value), + lilv_state_rel2abs(b, (char*)bp->value))) { + return false; + } + } else if (ap->size != bp->size || memcmp(ap->value, bp->value, ap->size)) { + return false; + } + } + + return true; } unsigned lilv_state_get_num_properties(const LilvState* state) { - return state->props.n; + return state->props.n; } const LilvNode* lilv_state_get_plugin_uri(const LilvState* state) { - return state->plugin_uri; + return state->plugin_uri; } const LilvNode* lilv_state_get_uri(const LilvState* state) { - return state->uri; + return state->uri; } const char* lilv_state_get_label(const LilvState* state) { - return state->label; + return state->label; } void lilv_state_set_label(LilvState* state, const char* label) { - const size_t len = strlen(label); - state->label = (char*)realloc(state->label, len + 1); - memcpy(state->label, label, len + 1); + const size_t len = strlen(label); + state->label = (char*)realloc(state->label, len + 1); + memcpy(state->label, label, len + 1); } int @@ -1522,6 +1523,6 @@ lilv_state_set_metadata(LilvState* state, uint32_t type, uint32_t flags) { - append_property(state, &state->metadata, key, value, size, type, flags); - return LV2_STATE_SUCCESS; + append_property(state, &state->metadata, key, value, size, type, flags); + return LV2_STATE_SUCCESS; } @@ -26,46 +26,46 @@ LilvUI* lilv_ui_new(LilvWorld* world, - LilvNode* uri, - LilvNode* type_uri, - LilvNode* binary_uri) + LilvNode* uri, + LilvNode* type_uri, + LilvNode* binary_uri) { - assert(uri); - assert(type_uri); - assert(binary_uri); - - LilvUI* ui = (LilvUI*)malloc(sizeof(LilvUI)); - ui->world = world; - ui->uri = uri; - ui->binary_uri = binary_uri; - - // FIXME: kludge - char* bundle = lilv_strdup(lilv_node_as_string(ui->binary_uri)); - char* last_slash = strrchr(bundle, '/') + 1; - *last_slash = '\0'; - ui->bundle_uri = lilv_new_uri(world, bundle); - free(bundle); - - ui->classes = lilv_nodes_new(); - zix_tree_insert((ZixTree*)ui->classes, type_uri, NULL); - - return ui; + assert(uri); + assert(type_uri); + assert(binary_uri); + + LilvUI* ui = (LilvUI*)malloc(sizeof(LilvUI)); + ui->world = world; + ui->uri = uri; + ui->binary_uri = binary_uri; + + // FIXME: kludge + char* bundle = lilv_strdup(lilv_node_as_string(ui->binary_uri)); + char* last_slash = strrchr(bundle, '/') + 1; + *last_slash = '\0'; + ui->bundle_uri = lilv_new_uri(world, bundle); + free(bundle); + + ui->classes = lilv_nodes_new(); + zix_tree_insert((ZixTree*)ui->classes, type_uri, NULL); + + return ui; } void lilv_ui_free(LilvUI* ui) { - lilv_node_free(ui->uri); - lilv_node_free(ui->bundle_uri); - lilv_node_free(ui->binary_uri); - lilv_nodes_free(ui->classes); - free(ui); + lilv_node_free(ui->uri); + lilv_node_free(ui->bundle_uri); + lilv_node_free(ui->binary_uri); + lilv_nodes_free(ui->classes); + free(ui); } const LilvNode* lilv_ui_get_uri(const LilvUI* ui) { - return ui->uri; + return ui->uri; } unsigned @@ -74,42 +74,42 @@ lilv_ui_is_supported(const LilvUI* ui, const LilvNode* container_type, const LilvNode** ui_type) { - const LilvNodes* classes = lilv_ui_get_classes(ui); - LILV_FOREACH(nodes, c, classes) { - const LilvNode* type = lilv_nodes_get(classes, c); - const unsigned q = supported_func(lilv_node_as_uri(container_type), - lilv_node_as_uri(type)); - if (q) { - if (ui_type) { - *ui_type = type; - } - return q; - } - } - - return 0; + const LilvNodes* classes = lilv_ui_get_classes(ui); + LILV_FOREACH (nodes, c, classes) { + const LilvNode* type = lilv_nodes_get(classes, c); + const unsigned q = + supported_func(lilv_node_as_uri(container_type), lilv_node_as_uri(type)); + if (q) { + if (ui_type) { + *ui_type = type; + } + return q; + } + } + + return 0; } const LilvNodes* lilv_ui_get_classes(const LilvUI* ui) { - return ui->classes; + return ui->classes; } bool lilv_ui_is_a(const LilvUI* ui, const LilvNode* class_uri) { - return lilv_nodes_contains(ui->classes, class_uri); + return lilv_nodes_contains(ui->classes, class_uri); } const LilvNode* lilv_ui_get_bundle_uri(const LilvUI* ui) { - return ui->bundle_uri; + return ui->bundle_uri; } const LilvNode* lilv_ui_get_binary_uri(const LilvUI* ui) { - return ui->binary_uri; + return ui->binary_uri; } @@ -36,76 +36,76 @@ void lilv_free(void* ptr) { - free(ptr); + free(ptr); } char* lilv_strjoin(const char* first, ...) { - size_t len = strlen(first); - char* result = (char*)malloc(len + 1); - - memcpy(result, first, len); - - va_list args; - va_start(args, first); - while (1) { - const char* const s = va_arg(args, const char *); - if (s == NULL) { - break; - } - - const size_t this_len = strlen(s); - char* new_result = (char*)realloc(result, len + this_len + 1); - if (!new_result) { - va_end(args); - free(result); - return NULL; - } - - result = new_result; - memcpy(result + len, s, this_len); - len += this_len; - } - va_end(args); - - result[len] = '\0'; - - return result; + size_t len = strlen(first); + char* result = (char*)malloc(len + 1); + + memcpy(result, first, len); + + va_list args; + va_start(args, first); + while (1) { + const char* const s = va_arg(args, const char*); + if (s == NULL) { + break; + } + + const size_t this_len = strlen(s); + char* new_result = (char*)realloc(result, len + this_len + 1); + if (!new_result) { + va_end(args); + free(result); + return NULL; + } + + result = new_result; + memcpy(result + len, s, this_len); + len += this_len; + } + va_end(args); + + result[len] = '\0'; + + return result; } char* lilv_strdup(const char* str) { - if (!str) { - return NULL; - } - - const size_t len = strlen(str); - char* copy = (char*)malloc(len + 1); - memcpy(copy, str, len + 1); - return copy; + if (!str) { + return NULL; + } + + const size_t len = strlen(str); + char* copy = (char*)malloc(len + 1); + memcpy(copy, str, len + 1); + return copy; } const char* lilv_uri_to_path(const char* uri) { #if defined(__GNUC__) && __GNUC__ > 4 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif - return (const char*)serd_uri_to_path((const uint8_t*)uri); + return (const char*)serd_uri_to_path((const uint8_t*)uri); #if defined(__GNUC__) && __GNUC__ > 4 -# pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif } char* lilv_file_uri_parse(const char* uri, char** hostname) { - return (char*)serd_file_uri_parse((const uint8_t*)uri, (uint8_t**)hostname); + return (char*)serd_file_uri_parse((const uint8_t*)uri, (uint8_t**)hostname); } /** Return the current LANG converted to Turtle (i.e. RFC3066) style. @@ -114,35 +114,35 @@ lilv_file_uri_parse(const char* uri, char** hostname) char* lilv_get_lang(void) { - const char* const env_lang = getenv("LANG"); - if (!env_lang || !strcmp(env_lang, "") - || !strcmp(env_lang, "C") || !strcmp(env_lang, "POSIX")) { - return NULL; - } - - const size_t env_lang_len = strlen(env_lang); - char* const lang = (char*)malloc(env_lang_len + 1); - for (size_t i = 0; i < env_lang_len + 1; ++i) { - if (env_lang[i] == '_') { - lang[i] = '-'; // Convert _ to - - } else if (env_lang[i] >= 'A' && env_lang[i] <= 'Z') { - lang[i] = env_lang[i] + ('a' - 'A'); // Convert to lowercase - } else if (env_lang[i] >= 'a' && env_lang[i] <= 'z') { - lang[i] = env_lang[i]; // Lowercase letter, copy verbatim - } else if (env_lang[i] >= '0' && env_lang[i] <= '9') { - lang[i] = env_lang[i]; // Digit, copy verbatim - } else if (env_lang[i] == '\0' || env_lang[i] == '.') { - // End, or start of suffix (e.g. en_CA.utf-8), finished - lang[i] = '\0'; - break; - } else { - LILV_ERRORF("Illegal LANG `%s' ignored\n", env_lang); - free(lang); - return NULL; - } - } - - return lang; + const char* const env_lang = getenv("LANG"); + if (!env_lang || !strcmp(env_lang, "") || !strcmp(env_lang, "C") || + !strcmp(env_lang, "POSIX")) { + return NULL; + } + + const size_t env_lang_len = strlen(env_lang); + char* const lang = (char*)malloc(env_lang_len + 1); + for (size_t i = 0; i < env_lang_len + 1; ++i) { + if (env_lang[i] == '_') { + lang[i] = '-'; // Convert _ to - + } else if (env_lang[i] >= 'A' && env_lang[i] <= 'Z') { + lang[i] = env_lang[i] + ('a' - 'A'); // Convert to lowercase + } else if (env_lang[i] >= 'a' && env_lang[i] <= 'z') { + lang[i] = env_lang[i]; // Lowercase letter, copy verbatim + } else if (env_lang[i] >= '0' && env_lang[i] <= '9') { + lang[i] = env_lang[i]; // Digit, copy verbatim + } else if (env_lang[i] == '\0' || env_lang[i] == '.') { + // End, or start of suffix (e.g. en_CA.utf-8), finished + lang[i] = '\0'; + break; + } else { + LILV_ERRORF("Illegal LANG `%s' ignored\n", env_lang); + free(lang); + return NULL; + } + } + + return lang; } #ifndef _WIN32 @@ -151,25 +151,24 @@ lilv_get_lang(void) static char* strappend(char* dst, size_t* dst_len, const char* suffix, size_t suffix_len) { - dst = (char*)realloc(dst, *dst_len + suffix_len + 1); - memcpy(dst + *dst_len, suffix, suffix_len); - dst[(*dst_len += suffix_len)] = '\0'; - return dst; + dst = (char*)realloc(dst, *dst_len + suffix_len + 1); + memcpy(dst + *dst_len, suffix, suffix_len); + dst[(*dst_len += suffix_len)] = '\0'; + return dst; } /** Append the value of the environment variable var to dst. */ static char* append_var(char* dst, size_t* dst_len, const char* var) { - // Get value from environment - const char* val = getenv(var); - if (val) { // Value found, append it - return strappend(dst, dst_len, val, strlen(val)); - } - - // No value found, append variable reference as-is - return strappend(strappend(dst, dst_len, "$", 1), - dst_len, var, strlen(var)); + // Get value from environment + const char* val = getenv(var); + if (val) { // Value found, append it + return strappend(dst, dst_len, val, strlen(val)); + } + + // No value found, append variable reference as-is + return strappend(strappend(dst, dst_len, "$", 1), dst_len, var, strlen(var)); } #endif @@ -179,48 +178,48 @@ char* lilv_expand(const char* path) { #ifdef _WIN32 - char* out = (char*)malloc(MAX_PATH); - ExpandEnvironmentStrings(path, out, MAX_PATH); + char* out = (char*)malloc(MAX_PATH); + ExpandEnvironmentStrings(path, out, MAX_PATH); #else - char* out = NULL; - size_t len = 0; - - const char* start = path; // Start of current chunk to copy - for (const char* s = path; *s;) { - if (*s == '$') { - // Hit $ (variable reference, e.g. $VAR_NAME) - for (const char* t = s + 1; ; ++t) { - if (!*t || (!isupper(*t) && !isdigit(*t) && *t != '_')) { - // Append preceding chunk - out = strappend(out, &len, start, s - start); - - // Append variable value (or $VAR_NAME if not found) - char* var = (char*)calloc(t - s, 1); - memcpy(var, s + 1, t - s - 1); - out = append_var(out, &len, var); - free(var); - - // Continue after variable reference - start = s = t; - break; - } - } - } else if (*s == '~' && (*(s + 1) == '/' || !*(s + 1))) { - // Hit ~ before slash or end of string (home directory reference) - out = strappend(out, &len, start, s - start); - out = append_var(out, &len, "HOME"); - start = ++s; - } else { - ++s; - } - } - - if (*start) { - out = strappend(out, &len, start, strlen(start)); - } + char* out = NULL; + size_t len = 0; + + const char* start = path; // Start of current chunk to copy + for (const char* s = path; *s;) { + if (*s == '$') { + // Hit $ (variable reference, e.g. $VAR_NAME) + for (const char* t = s + 1;; ++t) { + if (!*t || (!isupper(*t) && !isdigit(*t) && *t != '_')) { + // Append preceding chunk + out = strappend(out, &len, start, s - start); + + // Append variable value (or $VAR_NAME if not found) + char* var = (char*)calloc(t - s, 1); + memcpy(var, s + 1, t - s - 1); + out = append_var(out, &len, var); + free(var); + + // Continue after variable reference + start = s = t; + break; + } + } + } else if (*s == '~' && (*(s + 1) == '/' || !*(s + 1))) { + // Hit ~ before slash or end of string (home directory reference) + out = strappend(out, &len, start, s - start); + out = append_var(out, &len, "HOME"); + start = ++s; + } else { + ++s; + } + } + + if (*start) { + out = strappend(out, &len, start, strlen(start)); + } #endif - return out; + return out; } char* @@ -228,66 +227,65 @@ lilv_find_free_path(const char* in_path, bool (*exists)(const char*, const void*), const void* user_data) { - const size_t in_path_len = strlen(in_path); - char* path = (char*)malloc(in_path_len + 7); - memcpy(path, in_path, in_path_len + 1); - - for (unsigned i = 2; i < 1000000u; ++i) { - if (!exists(path, user_data)) { - return path; - } - snprintf(path, in_path_len + 7, "%s.%u", in_path, i); - } - - return NULL; + const size_t in_path_len = strlen(in_path); + char* path = (char*)malloc(in_path_len + 7); + memcpy(path, in_path, in_path_len + 1); + + for (unsigned i = 2; i < 1000000u; ++i) { + if (!exists(path, user_data)) { + return path; + } + snprintf(path, in_path_len + 7, "%s.%u", in_path, i); + } + + return NULL; } typedef struct { - char* pattern; - time_t time; - char* latest; + char* pattern; + time_t time; + char* latest; } Latest; static void update_latest(const char* path, const char* name, void* data) { - Latest* latest = (Latest*)data; - char* entry_path = lilv_path_join(path, name); - unsigned num = 0; - if (sscanf(entry_path, latest->pattern, &num) == 1) { - struct stat st; - if (!stat(entry_path, &st)) { - if (st.st_mtime >= latest->time) { - free(latest->latest); - latest->latest = entry_path; - } - } else { - LILV_ERRORF("stat(%s) (%s)\n", path, strerror(errno)); - } - } - if (entry_path != latest->latest) { - free(entry_path); - } + Latest* latest = (Latest*)data; + char* entry_path = lilv_path_join(path, name); + unsigned num = 0; + if (sscanf(entry_path, latest->pattern, &num) == 1) { + struct stat st; + if (!stat(entry_path, &st)) { + if (st.st_mtime >= latest->time) { + free(latest->latest); + latest->latest = entry_path; + } + } else { + LILV_ERRORF("stat(%s) (%s)\n", path, strerror(errno)); + } + } + if (entry_path != latest->latest) { + free(entry_path); + } } /** Return the latest copy of the file at `path` that is newer. */ char* lilv_get_latest_copy(const char* path, const char* copy_path) { - char* copy_dir = lilv_path_parent(copy_path); - Latest latest = { lilv_strjoin(copy_path, ".%u", NULL), 0, NULL }; + char* copy_dir = lilv_path_parent(copy_path); + Latest latest = {lilv_strjoin(copy_path, ".%u", NULL), 0, NULL}; - struct stat st; - if (!stat(path, &st)) { - latest.time = st.st_mtime; - } else { - LILV_ERRORF("stat(%s) (%s)\n", path, strerror(errno)); - } + struct stat st; + if (!stat(path, &st)) { + latest.time = st.st_mtime; + } else { + LILV_ERRORF("stat(%s) (%s)\n", path, strerror(errno)); + } - lilv_dir_for_each(copy_dir, &latest, update_latest); + lilv_dir_for_each(copy_dir, &latest, update_latest); - free(latest.pattern); - free(copy_dir); - return latest.latest; + free(latest.pattern); + free(copy_dir); + return latest.latest; } - diff --git a/src/world.c b/src/world.c index a04ba26..a6f103e 100644 --- a/src/world.c +++ b/src/world.c @@ -28,8 +28,8 @@ #include "lv2/presets/presets.h" #ifdef LILV_DYN_MANIFEST -# include "lv2/dynmanifest/dynmanifest.h" -# include <dlfcn.h> +# include "lv2/dynmanifest/dynmanifest.h" +# include <dlfcn.h> #endif #include <assert.h> @@ -45,166 +45,164 @@ lilv_world_drop_graph(LilvWorld* world, const SordNode* graph); LilvWorld* lilv_world_new(void) { - LilvWorld* world = (LilvWorld*)calloc(1, sizeof(LilvWorld)); + LilvWorld* world = (LilvWorld*)calloc(1, sizeof(LilvWorld)); - world->world = sord_world_new(); - if (!world->world) { - goto fail; - } + world->world = sord_world_new(); + if (!world->world) { + goto fail; + } - world->model = sord_new(world->world, SORD_SPO|SORD_OPS, true); - if (!world->model) { - goto fail; - } + world->model = sord_new(world->world, SORD_SPO | SORD_OPS, true); + if (!world->model) { + goto fail; + } - world->specs = NULL; - world->plugin_classes = lilv_plugin_classes_new(); - world->plugins = lilv_plugins_new(); - world->zombies = lilv_plugins_new(); - world->loaded_files = zix_tree_new( - false, lilv_resource_node_cmp, NULL, (ZixDestroyFunc)lilv_node_free); + world->specs = NULL; + world->plugin_classes = lilv_plugin_classes_new(); + world->plugins = lilv_plugins_new(); + world->zombies = lilv_plugins_new(); + world->loaded_files = zix_tree_new( + false, lilv_resource_node_cmp, NULL, (ZixDestroyFunc)lilv_node_free); - world->libs = zix_tree_new(false, lilv_lib_compare, NULL, NULL); + world->libs = zix_tree_new(false, lilv_lib_compare, NULL, NULL); #define NS_DCTERMS "http://purl.org/dc/terms/" -#define NS_DYNMAN "http://lv2plug.in/ns/ext/dynmanifest#" -#define NS_OWL "http://www.w3.org/2002/07/owl#" +#define NS_DYNMAN "http://lv2plug.in/ns/ext/dynmanifest#" +#define NS_OWL "http://www.w3.org/2002/07/owl#" #define NEW_URI(uri) sord_new_uri(world->world, (const uint8_t*)(uri)) - world->uris.dc_replaces = NEW_URI(NS_DCTERMS "replaces"); - world->uris.dman_DynManifest = NEW_URI(NS_DYNMAN "DynManifest"); - world->uris.doap_name = NEW_URI(LILV_NS_DOAP "name"); - world->uris.lv2_Plugin = NEW_URI(LV2_CORE__Plugin); - world->uris.lv2_Specification = NEW_URI(LV2_CORE__Specification); - world->uris.lv2_appliesTo = NEW_URI(LV2_CORE__appliesTo); - world->uris.lv2_binary = NEW_URI(LV2_CORE__binary); - world->uris.lv2_default = NEW_URI(LV2_CORE__default); - world->uris.lv2_designation = NEW_URI(LV2_CORE__designation); - world->uris.lv2_extensionData = NEW_URI(LV2_CORE__extensionData); - world->uris.lv2_index = NEW_URI(LV2_CORE__index); - world->uris.lv2_latency = NEW_URI(LV2_CORE__latency); - world->uris.lv2_maximum = NEW_URI(LV2_CORE__maximum); - world->uris.lv2_microVersion = NEW_URI(LV2_CORE__microVersion); - world->uris.lv2_minimum = NEW_URI(LV2_CORE__minimum); - world->uris.lv2_minorVersion = NEW_URI(LV2_CORE__minorVersion); - world->uris.lv2_name = NEW_URI(LV2_CORE__name); - world->uris.lv2_optionalFeature = NEW_URI(LV2_CORE__optionalFeature); - world->uris.lv2_port = NEW_URI(LV2_CORE__port); - world->uris.lv2_portProperty = NEW_URI(LV2_CORE__portProperty); - world->uris.lv2_reportsLatency = NEW_URI(LV2_CORE__reportsLatency); - world->uris.lv2_requiredFeature = NEW_URI(LV2_CORE__requiredFeature); - world->uris.lv2_symbol = NEW_URI(LV2_CORE__symbol); - world->uris.lv2_prototype = NEW_URI(LV2_CORE__prototype); - world->uris.owl_Ontology = NEW_URI(NS_OWL "Ontology"); - world->uris.pset_value = NEW_URI(LV2_PRESETS__value); - world->uris.rdf_a = NEW_URI(LILV_NS_RDF "type"); - world->uris.rdf_value = NEW_URI(LILV_NS_RDF "value"); - world->uris.rdfs_Class = NEW_URI(LILV_NS_RDFS "Class"); - world->uris.rdfs_label = NEW_URI(LILV_NS_RDFS "label"); - world->uris.rdfs_seeAlso = NEW_URI(LILV_NS_RDFS "seeAlso"); - world->uris.rdfs_subClassOf = NEW_URI(LILV_NS_RDFS "subClassOf"); - world->uris.xsd_base64Binary = NEW_URI(LILV_NS_XSD "base64Binary"); - world->uris.xsd_boolean = NEW_URI(LILV_NS_XSD "boolean"); - world->uris.xsd_decimal = NEW_URI(LILV_NS_XSD "decimal"); - world->uris.xsd_double = NEW_URI(LILV_NS_XSD "double"); - world->uris.xsd_integer = NEW_URI(LILV_NS_XSD "integer"); - world->uris.null_uri = NULL; - - world->lv2_plugin_class = lilv_plugin_class_new( - world, NULL, world->uris.lv2_Plugin, "Plugin"); - assert(world->lv2_plugin_class); - - world->n_read_files = 0; - world->opt.filter_language = true; - world->opt.dyn_manifest = true; - - return world; + world->uris.dc_replaces = NEW_URI(NS_DCTERMS "replaces"); + world->uris.dman_DynManifest = NEW_URI(NS_DYNMAN "DynManifest"); + world->uris.doap_name = NEW_URI(LILV_NS_DOAP "name"); + world->uris.lv2_Plugin = NEW_URI(LV2_CORE__Plugin); + world->uris.lv2_Specification = NEW_URI(LV2_CORE__Specification); + world->uris.lv2_appliesTo = NEW_URI(LV2_CORE__appliesTo); + world->uris.lv2_binary = NEW_URI(LV2_CORE__binary); + world->uris.lv2_default = NEW_URI(LV2_CORE__default); + world->uris.lv2_designation = NEW_URI(LV2_CORE__designation); + world->uris.lv2_extensionData = NEW_URI(LV2_CORE__extensionData); + world->uris.lv2_index = NEW_URI(LV2_CORE__index); + world->uris.lv2_latency = NEW_URI(LV2_CORE__latency); + world->uris.lv2_maximum = NEW_URI(LV2_CORE__maximum); + world->uris.lv2_microVersion = NEW_URI(LV2_CORE__microVersion); + world->uris.lv2_minimum = NEW_URI(LV2_CORE__minimum); + world->uris.lv2_minorVersion = NEW_URI(LV2_CORE__minorVersion); + world->uris.lv2_name = NEW_URI(LV2_CORE__name); + world->uris.lv2_optionalFeature = NEW_URI(LV2_CORE__optionalFeature); + world->uris.lv2_port = NEW_URI(LV2_CORE__port); + world->uris.lv2_portProperty = NEW_URI(LV2_CORE__portProperty); + world->uris.lv2_reportsLatency = NEW_URI(LV2_CORE__reportsLatency); + world->uris.lv2_requiredFeature = NEW_URI(LV2_CORE__requiredFeature); + world->uris.lv2_symbol = NEW_URI(LV2_CORE__symbol); + world->uris.lv2_prototype = NEW_URI(LV2_CORE__prototype); + world->uris.owl_Ontology = NEW_URI(NS_OWL "Ontology"); + world->uris.pset_value = NEW_URI(LV2_PRESETS__value); + world->uris.rdf_a = NEW_URI(LILV_NS_RDF "type"); + world->uris.rdf_value = NEW_URI(LILV_NS_RDF "value"); + world->uris.rdfs_Class = NEW_URI(LILV_NS_RDFS "Class"); + world->uris.rdfs_label = NEW_URI(LILV_NS_RDFS "label"); + world->uris.rdfs_seeAlso = NEW_URI(LILV_NS_RDFS "seeAlso"); + world->uris.rdfs_subClassOf = NEW_URI(LILV_NS_RDFS "subClassOf"); + world->uris.xsd_base64Binary = NEW_URI(LILV_NS_XSD "base64Binary"); + world->uris.xsd_boolean = NEW_URI(LILV_NS_XSD "boolean"); + world->uris.xsd_decimal = NEW_URI(LILV_NS_XSD "decimal"); + world->uris.xsd_double = NEW_URI(LILV_NS_XSD "double"); + world->uris.xsd_integer = NEW_URI(LILV_NS_XSD "integer"); + world->uris.null_uri = NULL; + + world->lv2_plugin_class = + lilv_plugin_class_new(world, NULL, world->uris.lv2_Plugin, "Plugin"); + assert(world->lv2_plugin_class); + + world->n_read_files = 0; + world->opt.filter_language = true; + world->opt.dyn_manifest = true; + + return world; fail: - /* keep on rockin' in the */ free(world); - return NULL; + /* keep on rockin' in the */ free(world); + return NULL; } void lilv_world_free(LilvWorld* world) { - if (!world) { - return; - } - - lilv_plugin_class_free(world->lv2_plugin_class); - world->lv2_plugin_class = NULL; - - for (SordNode** n = (SordNode**)&world->uris; *n; ++n) { - sord_node_free(world->world, *n); - } - - for (LilvSpec* spec = world->specs; spec;) { - LilvSpec* next = spec->next; - sord_node_free(world->world, spec->spec); - sord_node_free(world->world, spec->bundle); - lilv_nodes_free(spec->data_uris); - free(spec); - spec = next; - } - world->specs = NULL; - - LILV_FOREACH(plugins, i, world->plugins) { - const LilvPlugin* p = lilv_plugins_get(world->plugins, i); - lilv_plugin_free((LilvPlugin*)p); - } - zix_tree_free((ZixTree*)world->plugins); - world->plugins = NULL; - - LILV_FOREACH(plugins, i, world->zombies) { - const LilvPlugin* p = lilv_plugins_get(world->zombies, i); - lilv_plugin_free((LilvPlugin*)p); - } - zix_tree_free((ZixTree*)world->zombies); - world->zombies = NULL; - - zix_tree_free((ZixTree*)world->loaded_files); - world->loaded_files = NULL; - - zix_tree_free(world->libs); - world->libs = NULL; - - zix_tree_free((ZixTree*)world->plugin_classes); - world->plugin_classes = NULL; - - sord_free(world->model); - world->model = NULL; - - sord_world_free(world->world); - world->world = NULL; - - free(world->opt.lv2_path); - free(world); + if (!world) { + return; + } + + lilv_plugin_class_free(world->lv2_plugin_class); + world->lv2_plugin_class = NULL; + + for (SordNode** n = (SordNode**)&world->uris; *n; ++n) { + sord_node_free(world->world, *n); + } + + for (LilvSpec* spec = world->specs; spec;) { + LilvSpec* next = spec->next; + sord_node_free(world->world, spec->spec); + sord_node_free(world->world, spec->bundle); + lilv_nodes_free(spec->data_uris); + free(spec); + spec = next; + } + world->specs = NULL; + + LILV_FOREACH (plugins, i, world->plugins) { + const LilvPlugin* p = lilv_plugins_get(world->plugins, i); + lilv_plugin_free((LilvPlugin*)p); + } + zix_tree_free((ZixTree*)world->plugins); + world->plugins = NULL; + + LILV_FOREACH (plugins, i, world->zombies) { + const LilvPlugin* p = lilv_plugins_get(world->zombies, i); + lilv_plugin_free((LilvPlugin*)p); + } + zix_tree_free((ZixTree*)world->zombies); + world->zombies = NULL; + + zix_tree_free((ZixTree*)world->loaded_files); + world->loaded_files = NULL; + + zix_tree_free(world->libs); + world->libs = NULL; + + zix_tree_free((ZixTree*)world->plugin_classes); + world->plugin_classes = NULL; + + sord_free(world->model); + world->model = NULL; + + sord_world_free(world->world); + world->world = NULL; + + free(world->opt.lv2_path); + free(world); } void -lilv_world_set_option(LilvWorld* world, - const char* uri, - const LilvNode* value) +lilv_world_set_option(LilvWorld* world, const char* uri, const LilvNode* value) { - if (!strcmp(uri, LILV_OPTION_DYN_MANIFEST)) { - if (lilv_node_is_bool(value)) { - world->opt.dyn_manifest = lilv_node_as_bool(value); - return; - } - } else if (!strcmp(uri, LILV_OPTION_FILTER_LANG)) { - if (lilv_node_is_bool(value)) { - world->opt.filter_language = lilv_node_as_bool(value); - return; - } - } else if (!strcmp(uri, LILV_OPTION_LV2_PATH)) { - if (lilv_node_is_string(value)) { - world->opt.lv2_path = lilv_strdup(lilv_node_as_string(value)); - return; - } - } - LILV_WARNF("Unrecognized or invalid option `%s'\n", uri); + if (!strcmp(uri, LILV_OPTION_DYN_MANIFEST)) { + if (lilv_node_is_bool(value)) { + world->opt.dyn_manifest = lilv_node_as_bool(value); + return; + } + } else if (!strcmp(uri, LILV_OPTION_FILTER_LANG)) { + if (lilv_node_is_bool(value)) { + world->opt.filter_language = lilv_node_as_bool(value); + return; + } + } else if (!strcmp(uri, LILV_OPTION_LV2_PATH)) { + if (lilv_node_is_string(value)) { + world->opt.lv2_path = lilv_strdup(lilv_node_as_string(value)); + return; + } + } + LILV_WARNF("Unrecognized or invalid option `%s'\n", uri); } LilvNodes* @@ -213,32 +211,32 @@ lilv_world_find_nodes(LilvWorld* world, const LilvNode* predicate, const LilvNode* object) { - if (subject && !lilv_node_is_uri(subject) && !lilv_node_is_blank(subject)) { - LILV_ERRORF("Subject `%s' is not a resource\n", - sord_node_get_string(subject->node)); - return NULL; - } - - if (!predicate) { - LILV_ERROR("Missing required predicate\n"); - return NULL; - } - - if (!lilv_node_is_uri(predicate)) { - LILV_ERRORF("Predicate `%s' is not a URI\n", - sord_node_get_string(predicate->node)); - return NULL; - } - - if (!subject && !object) { - LILV_ERROR("Both subject and object are NULL\n"); - return NULL; - } - - return lilv_world_find_nodes_internal(world, - subject ? subject->node : NULL, - predicate->node, - object ? object->node : NULL); + if (subject && !lilv_node_is_uri(subject) && !lilv_node_is_blank(subject)) { + LILV_ERRORF("Subject `%s' is not a resource\n", + sord_node_get_string(subject->node)); + return NULL; + } + + if (!predicate) { + LILV_ERROR("Missing required predicate\n"); + return NULL; + } + + if (!lilv_node_is_uri(predicate)) { + LILV_ERRORF("Predicate `%s' is not a URI\n", + sord_node_get_string(predicate->node)); + return NULL; + } + + if (!subject && !object) { + LILV_ERROR("Both subject and object are NULL\n"); + return NULL; + } + + return lilv_world_find_nodes_internal(world, + subject ? subject->node : NULL, + predicate->node, + object ? object->node : NULL); } LilvNode* @@ -247,34 +245,34 @@ lilv_world_get(LilvWorld* world, const LilvNode* predicate, const LilvNode* object) { - if (!object) { - // TODO: Improve performance (see lilv_plugin_get_one) - SordIter* stream = sord_search(world->model, - subject ? subject->node : NULL, - predicate ? predicate->node : NULL, - NULL, - NULL); - - LilvNodes* nodes = - lilv_nodes_from_stream_objects(world, stream, SORD_OBJECT); - - if (nodes) { - LilvNode* value = lilv_node_duplicate(lilv_nodes_get_first(nodes)); - lilv_nodes_free(nodes); - return value; - } - - return NULL; - } - - SordNode* snode = sord_get(world->model, - subject ? subject->node : NULL, - predicate ? predicate->node : NULL, - object ? object->node : NULL, - NULL); - LilvNode* lnode = lilv_node_new_from_node(world, snode); - sord_node_free(world->world, snode); - return lnode; + if (!object) { + // TODO: Improve performance (see lilv_plugin_get_one) + SordIter* stream = sord_search(world->model, + subject ? subject->node : NULL, + predicate ? predicate->node : NULL, + NULL, + NULL); + + LilvNodes* nodes = + lilv_nodes_from_stream_objects(world, stream, SORD_OBJECT); + + if (nodes) { + LilvNode* value = lilv_node_duplicate(lilv_nodes_get_first(nodes)); + lilv_nodes_free(nodes); + return value; + } + + return NULL; + } + + SordNode* snode = sord_get(world->model, + subject ? subject->node : NULL, + predicate ? predicate->node : NULL, + object ? object->node : NULL, + NULL); + LilvNode* lnode = lilv_node_new_from_node(world, snode); + sord_node_free(world->world, snode); + return lnode; } SordIter* @@ -283,7 +281,7 @@ lilv_world_query_internal(LilvWorld* world, const SordNode* predicate, const SordNode* object) { - return sord_search(world->model, subject, predicate, object, NULL); + return sord_search(world->model, subject, predicate, object, NULL); } bool @@ -292,7 +290,7 @@ lilv_world_ask_internal(LilvWorld* world, const SordNode* predicate, const SordNode* object) { - return sord_ask(world->model, subject, predicate, object, NULL); + return sord_ask(world->model, subject, predicate, object, NULL); } bool @@ -301,11 +299,11 @@ lilv_world_ask(LilvWorld* world, const LilvNode* predicate, const LilvNode* object) { - return sord_ask(world->model, - subject ? subject->node : NULL, - predicate ? predicate->node : NULL, - object ? object->node : NULL, - NULL); + return sord_ask(world->model, + subject ? subject->node : NULL, + predicate ? predicate->node : NULL, + object ? object->node : NULL, + NULL); } SordModel* @@ -316,15 +314,15 @@ lilv_world_filter_model(LilvWorld* world, const SordNode* object, const SordNode* graph) { - SordModel* results = sord_new(world->world, SORD_SPO, false); - SordIter* i = sord_search(model, subject, predicate, object, graph); - for (; !sord_iter_end(i); sord_iter_next(i)) { - SordQuad quad; - sord_iter_get(i, quad); - sord_add(results, quad); - } - sord_iter_free(i); - return results; + SordModel* results = sord_new(world->world, SORD_SPO, false); + SordIter* i = sord_search(model, subject, predicate, object, graph); + for (; !sord_iter_end(i); sord_iter_next(i)) { + SordQuad quad; + sord_iter_get(i, quad); + sord_add(results, quad); + } + sord_iter_free(i); + return results; } LilvNodes* @@ -333,37 +331,37 @@ lilv_world_find_nodes_internal(LilvWorld* world, const SordNode* predicate, const SordNode* object) { - return lilv_nodes_from_stream_objects( - world, - lilv_world_query_internal(world, subject, predicate, object), - (object == NULL) ? SORD_OBJECT : SORD_SUBJECT); + return lilv_nodes_from_stream_objects( + world, + lilv_world_query_internal(world, subject, predicate, object), + (object == NULL) ? SORD_OBJECT : SORD_SUBJECT); } static SerdNode lilv_new_uri_relative_to_base(const uint8_t* uri_str, const uint8_t* base_uri_str) { - SerdURI base_uri; - serd_uri_parse(base_uri_str, &base_uri); - return serd_node_new_uri_from_string(uri_str, &base_uri, NULL); + SerdURI base_uri; + serd_uri_parse(base_uri_str, &base_uri); + return serd_node_new_uri_from_string(uri_str, &base_uri, NULL); } const uint8_t* lilv_world_blank_node_prefix(LilvWorld* world) { - static char str[32]; - snprintf(str, sizeof(str), "%u", world->n_read_files++); - return (const uint8_t*)str; + static char str[32]; + snprintf(str, sizeof(str), "%u", world->n_read_files++); + return (const uint8_t*)str; } /** Comparator for sequences (e.g. world->plugins). */ int lilv_header_compare_by_uri(const void* a, const void* b, void* user_data) { - const struct LilvHeader* const header_a = (const struct LilvHeader*)a; - const struct LilvHeader* const header_b = (const struct LilvHeader*)b; - return strcmp(lilv_node_as_uri(header_a->uri), - lilv_node_as_uri(header_b->uri)); + const struct LilvHeader* const header_a = (const struct LilvHeader*)a; + const struct LilvHeader* const header_b = (const struct LilvHeader*)b; + return strcmp(lilv_node_as_uri(header_a->uri), + lilv_node_as_uri(header_b->uri)); } /** @@ -376,32 +374,31 @@ lilv_header_compare_by_uri(const void* a, const void* b, void* user_data) int lilv_lib_compare(const void* a, const void* b, void* user_data) { - const LilvLib* const lib_a = (const LilvLib*)a; - const LilvLib* const lib_b = (const LilvLib*)b; - int cmp = strcmp(lilv_node_as_uri(lib_a->uri), - lilv_node_as_uri(lib_b->uri)); - return cmp ? cmp : strcmp(lib_a->bundle_path, lib_b->bundle_path); + const LilvLib* const lib_a = (const LilvLib*)a; + const LilvLib* const lib_b = (const LilvLib*)b; + int cmp = strcmp(lilv_node_as_uri(lib_a->uri), lilv_node_as_uri(lib_b->uri)); + return cmp ? cmp : strcmp(lib_a->bundle_path, lib_b->bundle_path); } /** Get an element of a collection of any object with an LilvHeader by URI. */ static ZixTreeIter* lilv_collection_find_by_uri(const ZixTree* seq, const LilvNode* uri) { - ZixTreeIter* i = NULL; - if (lilv_node_is_uri(uri)) { - struct LilvHeader key = { NULL, (LilvNode*)uri }; - zix_tree_find(seq, &key, &i); - } - return i; + ZixTreeIter* i = NULL; + if (lilv_node_is_uri(uri)) { + struct LilvHeader key = {NULL, (LilvNode*)uri}; + zix_tree_find(seq, &key, &i); + } + return i; } /** Get an element of a collection of any object with an LilvHeader by URI. */ struct LilvHeader* lilv_collection_get_by_uri(const ZixTree* seq, const LilvNode* uri) { - ZixTreeIter* const i = lilv_collection_find_by_uri(seq, uri); + ZixTreeIter* const i = lilv_collection_find_by_uri(seq, uri); - return i ? (struct LilvHeader*)zix_tree_get(i) : NULL; + return i ? (struct LilvHeader*)zix_tree_get(i) : NULL; } static void @@ -409,28 +406,25 @@ lilv_world_add_spec(LilvWorld* world, const SordNode* specification_node, const SordNode* bundle_node) { - LilvSpec* spec = (LilvSpec*)malloc(sizeof(LilvSpec)); - spec->spec = sord_node_copy(specification_node); - spec->bundle = sord_node_copy(bundle_node); - spec->data_uris = lilv_nodes_new(); - - // Add all data files (rdfs:seeAlso) - SordIter* files = sord_search(world->model, - specification_node, - world->uris.rdfs_seeAlso, - NULL, - NULL); - FOREACH_MATCH(files) { - const SordNode* file_node = sord_iter_get_node(files, SORD_OBJECT); - zix_tree_insert((ZixTree*)spec->data_uris, - lilv_node_new_from_node(world, file_node), - NULL); - } - sord_iter_free(files); - - // Add specification to world specification list - spec->next = world->specs; - world->specs = spec; + LilvSpec* spec = (LilvSpec*)malloc(sizeof(LilvSpec)); + spec->spec = sord_node_copy(specification_node); + spec->bundle = sord_node_copy(bundle_node); + spec->data_uris = lilv_nodes_new(); + + // Add all data files (rdfs:seeAlso) + SordIter* files = sord_search( + world->model, specification_node, world->uris.rdfs_seeAlso, NULL, NULL); + FOREACH_MATCH (files) { + const SordNode* file_node = sord_iter_get_node(files, SORD_OBJECT); + zix_tree_insert((ZixTree*)spec->data_uris, + lilv_node_new_from_node(world, file_node), + NULL); + } + sord_iter_free(files); + + // Add specification to world specification list + spec->next = world->specs; + world->specs = spec; } static void @@ -440,86 +434,80 @@ lilv_world_add_plugin(LilvWorld* world, void* dynmanifest, const SordNode* bundle) { - LilvNode* plugin_uri = lilv_node_new_from_node(world, plugin_node); - ZixTreeIter* z = NULL; - LilvPlugin* plugin = (LilvPlugin*)lilv_plugins_get_by_uri( - world->plugins, plugin_uri); - - if (plugin) { - // Existing plugin, if this is different bundle, ignore it - // (use the first plugin found in LV2_PATH) - const LilvNode* last_bundle = lilv_plugin_get_bundle_uri(plugin); - const char* plugin_uri_str = lilv_node_as_uri(plugin_uri); - if (sord_node_equals(bundle, last_bundle->node)) { - LILV_WARNF("Reloading plugin <%s>\n", plugin_uri_str); - plugin->loaded = false; - lilv_node_free(plugin_uri); - } else { - LILV_WARNF("Duplicate plugin <%s>\n", plugin_uri_str); - LILV_WARNF("... found in %s\n", lilv_node_as_string(last_bundle)); - LILV_WARNF("... and %s (ignored)\n", sord_node_get_string(bundle)); - lilv_node_free(plugin_uri); - return; - } - } else if ((z = lilv_collection_find_by_uri((const ZixTree*)world->zombies, - plugin_uri))) { - // Plugin bundle has been re-loaded, move from zombies to plugins - plugin = (LilvPlugin*)zix_tree_get(z); - zix_tree_remove((ZixTree*)world->zombies, z); - zix_tree_insert((ZixTree*)world->plugins, plugin, NULL); - lilv_node_free(plugin_uri); - lilv_plugin_clear(plugin, lilv_node_new_from_node(world, bundle)); - } else { - // Add new plugin to the world - plugin = lilv_plugin_new( - world, plugin_uri, lilv_node_new_from_node(world, bundle)); - - // Add manifest as plugin data file (as if it were rdfs:seeAlso) - zix_tree_insert((ZixTree*)plugin->data_uris, - lilv_node_duplicate(manifest_uri), - NULL); - - // Add plugin to world plugin sequence - zix_tree_insert((ZixTree*)world->plugins, plugin, NULL); - } - + LilvNode* plugin_uri = lilv_node_new_from_node(world, plugin_node); + ZixTreeIter* z = NULL; + LilvPlugin* plugin = + (LilvPlugin*)lilv_plugins_get_by_uri(world->plugins, plugin_uri); + + if (plugin) { + // Existing plugin, if this is different bundle, ignore it + // (use the first plugin found in LV2_PATH) + const LilvNode* last_bundle = lilv_plugin_get_bundle_uri(plugin); + const char* plugin_uri_str = lilv_node_as_uri(plugin_uri); + if (sord_node_equals(bundle, last_bundle->node)) { + LILV_WARNF("Reloading plugin <%s>\n", plugin_uri_str); + plugin->loaded = false; + lilv_node_free(plugin_uri); + } else { + LILV_WARNF("Duplicate plugin <%s>\n", plugin_uri_str); + LILV_WARNF("... found in %s\n", lilv_node_as_string(last_bundle)); + LILV_WARNF("... and %s (ignored)\n", sord_node_get_string(bundle)); + lilv_node_free(plugin_uri); + return; + } + } else if ((z = lilv_collection_find_by_uri((const ZixTree*)world->zombies, + plugin_uri))) { + // Plugin bundle has been re-loaded, move from zombies to plugins + plugin = (LilvPlugin*)zix_tree_get(z); + zix_tree_remove((ZixTree*)world->zombies, z); + zix_tree_insert((ZixTree*)world->plugins, plugin, NULL); + lilv_node_free(plugin_uri); + lilv_plugin_clear(plugin, lilv_node_new_from_node(world, bundle)); + } else { + // Add new plugin to the world + plugin = lilv_plugin_new( + world, plugin_uri, lilv_node_new_from_node(world, bundle)); + + // Add manifest as plugin data file (as if it were rdfs:seeAlso) + zix_tree_insert( + (ZixTree*)plugin->data_uris, lilv_node_duplicate(manifest_uri), NULL); + + // Add plugin to world plugin sequence + zix_tree_insert((ZixTree*)world->plugins, plugin, NULL); + } #ifdef LILV_DYN_MANIFEST - // Set dynamic manifest library URI, if applicable - if (dynmanifest) { - plugin->dynmanifest = (LilvDynManifest*)dynmanifest; - ++((LilvDynManifest*)dynmanifest)->refs; - } + // Set dynamic manifest library URI, if applicable + if (dynmanifest) { + plugin->dynmanifest = (LilvDynManifest*)dynmanifest; + ++((LilvDynManifest*)dynmanifest)->refs; + } #endif - // Add all plugin data files (rdfs:seeAlso) - SordIter* files = sord_search(world->model, - plugin_node, - world->uris.rdfs_seeAlso, - NULL, - NULL); - FOREACH_MATCH(files) { - const SordNode* file_node = sord_iter_get_node(files, SORD_OBJECT); - zix_tree_insert((ZixTree*)plugin->data_uris, - lilv_node_new_from_node(world, file_node), - NULL); - } - sord_iter_free(files); + // Add all plugin data files (rdfs:seeAlso) + SordIter* files = sord_search( + world->model, plugin_node, world->uris.rdfs_seeAlso, NULL, NULL); + FOREACH_MATCH (files) { + const SordNode* file_node = sord_iter_get_node(files, SORD_OBJECT); + zix_tree_insert((ZixTree*)plugin->data_uris, + lilv_node_new_from_node(world, file_node), + NULL); + } + sord_iter_free(files); } SerdStatus lilv_world_load_graph(LilvWorld* world, SordNode* graph, const LilvNode* uri) { - const SerdNode* base = sord_node_to_serd_node(uri->node); - SerdEnv* env = serd_env_new(base); - SerdReader* reader = sord_new_reader( - world->model, env, SERD_TURTLE, graph); + const SerdNode* base = sord_node_to_serd_node(uri->node); + SerdEnv* env = serd_env_new(base); + SerdReader* reader = sord_new_reader(world->model, env, SERD_TURTLE, graph); - const SerdStatus st = lilv_world_load_file(world, reader, uri); + const SerdStatus st = lilv_world_load_file(world, reader, uri); - serd_env_free(env); - serd_reader_free(reader); - return st; + serd_env_free(env); + serd_reader_free(reader); + return st; } static void @@ -528,161 +516,154 @@ lilv_world_load_dyn_manifest(LilvWorld* world, const LilvNode* manifest) { #ifdef LILV_DYN_MANIFEST - if (!world->opt.dyn_manifest) { - return; - } - - LV2_Dyn_Manifest_Handle handle = NULL; - - // ?dman a dynman:DynManifest bundle_node - SordModel* model = lilv_world_filter_model(world, - world->model, - NULL, - world->uris.rdf_a, - world->uris.dman_DynManifest, - bundle_node); - SordIter* iter = sord_begin(model); - for (; !sord_iter_end(iter); sord_iter_next(iter)) { - const SordNode* dmanifest = sord_iter_get_node(iter, SORD_SUBJECT); - - // ?dman lv2:binary ?binary - SordIter* binaries = sord_search(world->model, - dmanifest, - world->uris.lv2_binary, - NULL, - bundle_node); - if (sord_iter_end(binaries)) { - sord_iter_free(binaries); - LILV_ERRORF("Dynamic manifest in <%s> has no binaries, ignored\n", - sord_node_get_string(bundle_node)); - continue; - } - - // Get binary path - const SordNode* binary = sord_iter_get_node(binaries, SORD_OBJECT); - const uint8_t* lib_uri = sord_node_get_string(binary); - char* lib_path = lilv_file_uri_parse((const char*)lib_uri, 0); - if (!lib_path) { - LILV_ERROR("No dynamic manifest library path\n"); - sord_iter_free(binaries); - continue; - } - - // Open library - dlerror(); - void* lib = dlopen(lib_path, RTLD_LAZY); - if (!lib) { - LILV_ERRORF("Failed to open dynmanifest library `%s' (%s)\n", - lib_path, dlerror()); - sord_iter_free(binaries); - lilv_free(lib_path); - continue; - } - - // Open dynamic manifest - typedef int (*OpenFunc)(LV2_Dyn_Manifest_Handle*, - const LV2_Feature *const *); - OpenFunc dmopen = (OpenFunc)lilv_dlfunc(lib, "lv2_dyn_manifest_open"); - if (!dmopen || dmopen(&handle, &dman_features)) { - LILV_ERRORF("No `lv2_dyn_manifest_open' in `%s'\n", lib_path); - sord_iter_free(binaries); - dlclose(lib); - lilv_free(lib_path); - continue; - } - - // Get subjects (the data that would be in manifest.ttl) - typedef int (*GetSubjectsFunc)(LV2_Dyn_Manifest_Handle, FILE*); - GetSubjectsFunc get_subjects_func = (GetSubjectsFunc)lilv_dlfunc( - lib, "lv2_dyn_manifest_get_subjects"); - if (!get_subjects_func) { - LILV_ERRORF("No `lv2_dyn_manifest_get_subjects' in `%s'\n", - lib_path); - sord_iter_free(binaries); - dlclose(lib); - lilv_free(lib_path); - continue; - } - - LilvDynManifest* desc = (LilvDynManifest*)malloc(sizeof(LilvDynManifest)); - desc->bundle = lilv_node_new_from_node(world, bundle_node); - desc->lib = lib; - desc->handle = handle; - desc->refs = 0; - - sord_iter_free(binaries); - - // Generate data file - FILE* fd = tmpfile(); - get_subjects_func(handle, fd); - rewind(fd); - - // Parse generated data file into temporary model - // FIXME - const SerdNode* base = sord_node_to_serd_node(dmanifest); - SerdEnv* env = serd_env_new(base); - SerdReader* reader = sord_new_reader( - world->model, env, SERD_TURTLE, sord_node_copy(dmanifest)); - serd_reader_add_blank_prefix(reader, - lilv_world_blank_node_prefix(world)); - serd_reader_read_file_handle(reader, fd, - (const uint8_t*)"(dyn-manifest)"); - serd_reader_free(reader); - serd_env_free(env); - - // Close (and automatically delete) temporary data file - fclose(fd); - - // ?plugin a lv2:Plugin - SordModel* plugins = lilv_world_filter_model(world, - world->model, - NULL, - world->uris.rdf_a, - world->uris.lv2_Plugin, - dmanifest); - SordIter* p = sord_begin(plugins); - FOREACH_MATCH(p) { - const SordNode* plug = sord_iter_get_node(p, SORD_SUBJECT); - lilv_world_add_plugin(world, plug, manifest, desc, bundle_node); - } - if (desc->refs == 0) { - lilv_dynmanifest_free(desc); - } - sord_iter_free(p); - sord_free(plugins); - lilv_free(lib_path); - } - sord_iter_free(iter); - sord_free(model); -#endif // LILV_DYN_MANIFEST + if (!world->opt.dyn_manifest) { + return; + } + + LV2_Dyn_Manifest_Handle handle = NULL; + + // ?dman a dynman:DynManifest bundle_node + SordModel* model = lilv_world_filter_model(world, + world->model, + NULL, + world->uris.rdf_a, + world->uris.dman_DynManifest, + bundle_node); + SordIter* iter = sord_begin(model); + for (; !sord_iter_end(iter); sord_iter_next(iter)) { + const SordNode* dmanifest = sord_iter_get_node(iter, SORD_SUBJECT); + + // ?dman lv2:binary ?binary + SordIter* binaries = sord_search( + world->model, dmanifest, world->uris.lv2_binary, NULL, bundle_node); + if (sord_iter_end(binaries)) { + sord_iter_free(binaries); + LILV_ERRORF("Dynamic manifest in <%s> has no binaries, ignored\n", + sord_node_get_string(bundle_node)); + continue; + } + + // Get binary path + const SordNode* binary = sord_iter_get_node(binaries, SORD_OBJECT); + const uint8_t* lib_uri = sord_node_get_string(binary); + char* lib_path = lilv_file_uri_parse((const char*)lib_uri, 0); + if (!lib_path) { + LILV_ERROR("No dynamic manifest library path\n"); + sord_iter_free(binaries); + continue; + } + + // Open library + dlerror(); + void* lib = dlopen(lib_path, RTLD_LAZY); + if (!lib) { + LILV_ERRORF( + "Failed to open dynmanifest library `%s' (%s)\n", lib_path, dlerror()); + sord_iter_free(binaries); + lilv_free(lib_path); + continue; + } + + // Open dynamic manifest + typedef int (*OpenFunc)(LV2_Dyn_Manifest_Handle*, + const LV2_Feature* const*); + OpenFunc dmopen = (OpenFunc)lilv_dlfunc(lib, "lv2_dyn_manifest_open"); + if (!dmopen || dmopen(&handle, &dman_features)) { + LILV_ERRORF("No `lv2_dyn_manifest_open' in `%s'\n", lib_path); + sord_iter_free(binaries); + dlclose(lib); + lilv_free(lib_path); + continue; + } + + // Get subjects (the data that would be in manifest.ttl) + typedef int (*GetSubjectsFunc)(LV2_Dyn_Manifest_Handle, FILE*); + GetSubjectsFunc get_subjects_func = + (GetSubjectsFunc)lilv_dlfunc(lib, "lv2_dyn_manifest_get_subjects"); + if (!get_subjects_func) { + LILV_ERRORF("No `lv2_dyn_manifest_get_subjects' in `%s'\n", lib_path); + sord_iter_free(binaries); + dlclose(lib); + lilv_free(lib_path); + continue; + } + + LilvDynManifest* desc = (LilvDynManifest*)malloc(sizeof(LilvDynManifest)); + desc->bundle = lilv_node_new_from_node(world, bundle_node); + desc->lib = lib; + desc->handle = handle; + desc->refs = 0; + + sord_iter_free(binaries); + + // Generate data file + FILE* fd = tmpfile(); + get_subjects_func(handle, fd); + rewind(fd); + + // Parse generated data file into temporary model + // FIXME + const SerdNode* base = sord_node_to_serd_node(dmanifest); + SerdEnv* env = serd_env_new(base); + SerdReader* reader = sord_new_reader( + world->model, env, SERD_TURTLE, sord_node_copy(dmanifest)); + serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world)); + serd_reader_read_file_handle(reader, fd, (const uint8_t*)"(dyn-manifest)"); + serd_reader_free(reader); + serd_env_free(env); + + // Close (and automatically delete) temporary data file + fclose(fd); + + // ?plugin a lv2:Plugin + SordModel* plugins = lilv_world_filter_model(world, + world->model, + NULL, + world->uris.rdf_a, + world->uris.lv2_Plugin, + dmanifest); + SordIter* p = sord_begin(plugins); + FOREACH_MATCH (p) { + const SordNode* plug = sord_iter_get_node(p, SORD_SUBJECT); + lilv_world_add_plugin(world, plug, manifest, desc, bundle_node); + } + if (desc->refs == 0) { + lilv_dynmanifest_free(desc); + } + sord_iter_free(p); + sord_free(plugins); + lilv_free(lib_path); + } + sord_iter_free(iter); + sord_free(model); +#endif // LILV_DYN_MANIFEST } #ifdef LILV_DYN_MANIFEST void lilv_dynmanifest_free(LilvDynManifest* dynmanifest) { - typedef int (*CloseFunc)(LV2_Dyn_Manifest_Handle); - CloseFunc close_func = (CloseFunc)lilv_dlfunc(dynmanifest->lib, - "lv2_dyn_manifest_close"); - if (close_func) { - close_func(dynmanifest->handle); - } - - dlclose(dynmanifest->lib); - lilv_node_free(dynmanifest->bundle); - free(dynmanifest); + typedef int (*CloseFunc)(LV2_Dyn_Manifest_Handle); + CloseFunc close_func = + (CloseFunc)lilv_dlfunc(dynmanifest->lib, "lv2_dyn_manifest_close"); + if (close_func) { + close_func(dynmanifest->handle); + } + + dlclose(dynmanifest->lib); + lilv_node_free(dynmanifest->bundle); + free(dynmanifest); } -#endif // LILV_DYN_MANIFEST +#endif // LILV_DYN_MANIFEST LilvNode* lilv_world_get_manifest_uri(LilvWorld* world, const LilvNode* bundle_uri) { - SerdNode manifest_uri = lilv_new_uri_relative_to_base( - (const uint8_t*)"manifest.ttl", - sord_node_get_string(bundle_uri->node)); - LilvNode* manifest = lilv_new_uri(world, (const char*)manifest_uri.buf); - serd_node_free(&manifest_uri); - return manifest; + SerdNode manifest_uri = lilv_new_uri_relative_to_base( + (const uint8_t*)"manifest.ttl", sord_node_get_string(bundle_uri->node)); + LilvNode* manifest = lilv_new_uri(world, (const char*)manifest_uri.buf); + serd_node_free(&manifest_uri); + return manifest; } static SordModel* @@ -690,308 +671,298 @@ load_plugin_model(LilvWorld* world, const LilvNode* bundle_uri, const LilvNode* plugin_uri) { - // Create model and reader for loading into it - SordNode* bundle_node = bundle_uri->node; - SordModel* model = sord_new(world->world, SORD_SPO|SORD_OPS, false); - SerdEnv* env = serd_env_new(sord_node_to_serd_node(bundle_node)); - SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); - - // Load manifest - LilvNode* manifest_uri = lilv_world_get_manifest_uri(world, bundle_uri); - serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world)); - serd_reader_read_file( - reader, (const uint8_t*)lilv_node_as_string(manifest_uri)); - - // Load any seeAlso files - SordModel* files = lilv_world_filter_model( - world, model, plugin_uri->node, world->uris.rdfs_seeAlso, NULL, NULL); - - SordIter* f = sord_begin(files); - FOREACH_MATCH(f) { - const SordNode* file = sord_iter_get_node(f, SORD_OBJECT); - const uint8_t* file_str = sord_node_get_string(file); - if (sord_node_get_type(file) == SORD_URI) { - serd_reader_add_blank_prefix( - reader, lilv_world_blank_node_prefix(world)); - serd_reader_read_file(reader, file_str); - } - } - - sord_iter_free(f); - sord_free(files); - serd_reader_free(reader); - serd_env_free(env); - lilv_node_free(manifest_uri); - - return model; + // Create model and reader for loading into it + SordNode* bundle_node = bundle_uri->node; + SordModel* model = sord_new(world->world, SORD_SPO | SORD_OPS, false); + SerdEnv* env = serd_env_new(sord_node_to_serd_node(bundle_node)); + SerdReader* reader = sord_new_reader(model, env, SERD_TURTLE, NULL); + + // Load manifest + LilvNode* manifest_uri = lilv_world_get_manifest_uri(world, bundle_uri); + serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world)); + serd_reader_read_file(reader, + (const uint8_t*)lilv_node_as_string(manifest_uri)); + + // Load any seeAlso files + SordModel* files = lilv_world_filter_model( + world, model, plugin_uri->node, world->uris.rdfs_seeAlso, NULL, NULL); + + SordIter* f = sord_begin(files); + FOREACH_MATCH (f) { + const SordNode* file = sord_iter_get_node(f, SORD_OBJECT); + const uint8_t* file_str = sord_node_get_string(file); + if (sord_node_get_type(file) == SORD_URI) { + serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world)); + serd_reader_read_file(reader, file_str); + } + } + + sord_iter_free(f); + sord_free(files); + serd_reader_free(reader); + serd_env_free(env); + lilv_node_free(manifest_uri); + + return model; } static LilvVersion get_version(LilvWorld* world, SordModel* model, const LilvNode* subject) { - const SordNode* minor_node = sord_get( - model, subject->node, world->uris.lv2_minorVersion, NULL, NULL); - const SordNode* micro_node = sord_get( - model, subject->node, world->uris.lv2_microVersion, NULL, NULL); - - - LilvVersion version = { 0, 0 }; - if (minor_node && micro_node) { - version.minor = atoi((const char*)sord_node_get_string(minor_node)); - version.micro = atoi((const char*)sord_node_get_string(micro_node)); - } - - return version; + const SordNode* minor_node = + sord_get(model, subject->node, world->uris.lv2_minorVersion, NULL, NULL); + const SordNode* micro_node = + sord_get(model, subject->node, world->uris.lv2_microVersion, NULL, NULL); + + LilvVersion version = {0, 0}; + if (minor_node && micro_node) { + version.minor = atoi((const char*)sord_node_get_string(minor_node)); + version.micro = atoi((const char*)sord_node_get_string(micro_node)); + } + + return version; } void lilv_world_load_bundle(LilvWorld* world, const LilvNode* bundle_uri) { - if (!lilv_node_is_uri(bundle_uri)) { - LILV_ERRORF("Bundle URI `%s' is not a URI\n", - sord_node_get_string(bundle_uri->node)); - return; - } - - SordNode* bundle_node = bundle_uri->node; - LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle_uri); - - // Read manifest into model with graph = bundle_node - SerdStatus st = lilv_world_load_graph(world, bundle_node, manifest); - if (st > SERD_FAILURE) { - LILV_ERRORF("Error reading %s\n", lilv_node_as_string(manifest)); - lilv_node_free(manifest); - return; - } - - // ?plugin a lv2:Plugin - SordIter* plug_results = sord_search(world->model, - NULL, - world->uris.rdf_a, - world->uris.lv2_Plugin, - bundle_node); - - // Find any loaded plugins that will be replaced with a newer version - LilvNodes* unload_uris = lilv_nodes_new(); - FOREACH_MATCH(plug_results) { - const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT); - - LilvNode* plugin_uri = lilv_node_new_from_node(world, plug); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(world->plugins, plugin_uri); - const LilvNode* last_bundle = plugin ? lilv_plugin_get_bundle_uri(plugin) : NULL; - if (!plugin || sord_node_equals(bundle_node, last_bundle->node)) { - // No previously loaded version, or it's from the same bundle - lilv_node_free(plugin_uri); - continue; - } - - // Compare versions - SordModel* this_model = load_plugin_model(world, bundle_uri, plugin_uri); - LilvVersion this_version = get_version(world, this_model, plugin_uri); - SordModel* last_model = load_plugin_model(world, last_bundle, plugin_uri); - LilvVersion last_version = get_version(world, last_model, plugin_uri); - sord_free(this_model); - sord_free(last_model); - const int cmp = lilv_version_cmp(&this_version, &last_version); - if (cmp > 0) { - zix_tree_insert((ZixTree*)unload_uris, - lilv_node_duplicate(plugin_uri), - NULL); - LILV_WARNF("Replacing version %d.%d of <%s> from <%s>\n", - last_version.minor, last_version.micro, - sord_node_get_string(plug), - sord_node_get_string(last_bundle->node)); - LILV_NOTEF("New version %d.%d found in <%s>\n", - this_version.minor, this_version.micro, - sord_node_get_string(bundle_node)); - } else if (cmp < 0) { - LILV_WARNF("Ignoring bundle <%s>\n", - sord_node_get_string(bundle_node)); - LILV_NOTEF("Newer version of <%s> loaded from <%s>\n", - sord_node_get_string(plug), - sord_node_get_string(last_bundle->node)); - lilv_node_free(plugin_uri); - sord_iter_free(plug_results); - lilv_world_drop_graph(world, bundle_node); - lilv_node_free(manifest); - lilv_nodes_free(unload_uris); - return; - } - lilv_node_free(plugin_uri); - } - - sord_iter_free(plug_results); - - // Unload any old conflicting plugins - LilvNodes* unload_bundles = lilv_nodes_new(); - LILV_FOREACH(nodes, i, unload_uris) { - const LilvNode* uri = lilv_nodes_get(unload_uris, i); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(world->plugins, uri); - const LilvNode* bundle = lilv_plugin_get_bundle_uri(plugin); - - // Unload plugin and record bundle for later unloading - lilv_world_unload_resource(world, uri); - zix_tree_insert((ZixTree*)unload_bundles, - lilv_node_duplicate(bundle), - NULL); - - } - lilv_nodes_free(unload_uris); - - // Now unload the associated bundles - // This must be done last since several plugins could be in the same bundle - LILV_FOREACH(nodes, i, unload_bundles) { - lilv_world_unload_bundle(world, lilv_nodes_get(unload_bundles, i)); - } - lilv_nodes_free(unload_bundles); - - // Re-search for plugin results now that old plugins are gone - plug_results = sord_search(world->model, - NULL, - world->uris.rdf_a, - world->uris.lv2_Plugin, - bundle_node); - - FOREACH_MATCH(plug_results) { - const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT); - lilv_world_add_plugin(world, plug, manifest, NULL, bundle_node); - } - sord_iter_free(plug_results); - - lilv_world_load_dyn_manifest(world, bundle_node, manifest); - - // ?spec a lv2:Specification - // ?spec a owl:Ontology - const SordNode* spec_preds[] = { world->uris.lv2_Specification, - world->uris.owl_Ontology, - NULL }; - for (const SordNode** p = spec_preds; *p; ++p) { - SordIter* i = sord_search( - world->model, NULL, world->uris.rdf_a, *p, bundle_node); - FOREACH_MATCH(i) { - const SordNode* spec = sord_iter_get_node(i, SORD_SUBJECT); - lilv_world_add_spec(world, spec, bundle_node); - } - sord_iter_free(i); - } - - lilv_node_free(manifest); + if (!lilv_node_is_uri(bundle_uri)) { + LILV_ERRORF("Bundle URI `%s' is not a URI\n", + sord_node_get_string(bundle_uri->node)); + return; + } + + SordNode* bundle_node = bundle_uri->node; + LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle_uri); + + // Read manifest into model with graph = bundle_node + SerdStatus st = lilv_world_load_graph(world, bundle_node, manifest); + if (st > SERD_FAILURE) { + LILV_ERRORF("Error reading %s\n", lilv_node_as_string(manifest)); + lilv_node_free(manifest); + return; + } + + // ?plugin a lv2:Plugin + SordIter* plug_results = sord_search( + world->model, NULL, world->uris.rdf_a, world->uris.lv2_Plugin, bundle_node); + + // Find any loaded plugins that will be replaced with a newer version + LilvNodes* unload_uris = lilv_nodes_new(); + FOREACH_MATCH (plug_results) { + const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT); + + LilvNode* plugin_uri = lilv_node_new_from_node(world, plug); + const LilvPlugin* plugin = + lilv_plugins_get_by_uri(world->plugins, plugin_uri); + const LilvNode* last_bundle = + plugin ? lilv_plugin_get_bundle_uri(plugin) : NULL; + if (!plugin || sord_node_equals(bundle_node, last_bundle->node)) { + // No previously loaded version, or it's from the same bundle + lilv_node_free(plugin_uri); + continue; + } + + // Compare versions + SordModel* this_model = load_plugin_model(world, bundle_uri, plugin_uri); + LilvVersion this_version = get_version(world, this_model, plugin_uri); + SordModel* last_model = load_plugin_model(world, last_bundle, plugin_uri); + LilvVersion last_version = get_version(world, last_model, plugin_uri); + sord_free(this_model); + sord_free(last_model); + const int cmp = lilv_version_cmp(&this_version, &last_version); + if (cmp > 0) { + zix_tree_insert( + (ZixTree*)unload_uris, lilv_node_duplicate(plugin_uri), NULL); + LILV_WARNF("Replacing version %d.%d of <%s> from <%s>\n", + last_version.minor, + last_version.micro, + sord_node_get_string(plug), + sord_node_get_string(last_bundle->node)); + LILV_NOTEF("New version %d.%d found in <%s>\n", + this_version.minor, + this_version.micro, + sord_node_get_string(bundle_node)); + } else if (cmp < 0) { + LILV_WARNF("Ignoring bundle <%s>\n", sord_node_get_string(bundle_node)); + LILV_NOTEF("Newer version of <%s> loaded from <%s>\n", + sord_node_get_string(plug), + sord_node_get_string(last_bundle->node)); + lilv_node_free(plugin_uri); + sord_iter_free(plug_results); + lilv_world_drop_graph(world, bundle_node); + lilv_node_free(manifest); + lilv_nodes_free(unload_uris); + return; + } + lilv_node_free(plugin_uri); + } + + sord_iter_free(plug_results); + + // Unload any old conflicting plugins + LilvNodes* unload_bundles = lilv_nodes_new(); + LILV_FOREACH (nodes, i, unload_uris) { + const LilvNode* uri = lilv_nodes_get(unload_uris, i); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(world->plugins, uri); + const LilvNode* bundle = lilv_plugin_get_bundle_uri(plugin); + + // Unload plugin and record bundle for later unloading + lilv_world_unload_resource(world, uri); + zix_tree_insert( + (ZixTree*)unload_bundles, lilv_node_duplicate(bundle), NULL); + } + lilv_nodes_free(unload_uris); + + // Now unload the associated bundles + // This must be done last since several plugins could be in the same bundle + LILV_FOREACH (nodes, i, unload_bundles) { + lilv_world_unload_bundle(world, lilv_nodes_get(unload_bundles, i)); + } + lilv_nodes_free(unload_bundles); + + // Re-search for plugin results now that old plugins are gone + plug_results = sord_search( + world->model, NULL, world->uris.rdf_a, world->uris.lv2_Plugin, bundle_node); + + FOREACH_MATCH (plug_results) { + const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT); + lilv_world_add_plugin(world, plug, manifest, NULL, bundle_node); + } + sord_iter_free(plug_results); + + lilv_world_load_dyn_manifest(world, bundle_node, manifest); + + // ?spec a lv2:Specification + // ?spec a owl:Ontology + const SordNode* spec_preds[] = { + world->uris.lv2_Specification, world->uris.owl_Ontology, NULL}; + for (const SordNode** p = spec_preds; *p; ++p) { + SordIter* i = + sord_search(world->model, NULL, world->uris.rdf_a, *p, bundle_node); + FOREACH_MATCH (i) { + const SordNode* spec = sord_iter_get_node(i, SORD_SUBJECT); + lilv_world_add_spec(world, spec, bundle_node); + } + sord_iter_free(i); + } + + lilv_node_free(manifest); } static int lilv_world_drop_graph(LilvWorld* world, const SordNode* graph) { - SordIter* i = sord_search(world->model, NULL, NULL, NULL, graph); - while (!sord_iter_end(i)) { - const SerdStatus st = sord_erase(world->model, i); - if (st) { - LILV_ERRORF("Error removing statement from <%s> (%s)\n", - sord_node_get_string(graph), serd_strerror(st)); - return st; - } - } - sord_iter_free(i); - - return 0; + SordIter* i = sord_search(world->model, NULL, NULL, NULL, graph); + while (!sord_iter_end(i)) { + const SerdStatus st = sord_erase(world->model, i); + if (st) { + LILV_ERRORF("Error removing statement from <%s> (%s)\n", + sord_node_get_string(graph), + serd_strerror(st)); + return st; + } + } + sord_iter_free(i); + + return 0; } /** Remove loaded_files entry so file will be reloaded if requested. */ static int lilv_world_unload_file(LilvWorld* world, const LilvNode* file) { - ZixTreeIter* iter = NULL; - if (!zix_tree_find((ZixTree*)world->loaded_files, file, &iter)) { - zix_tree_remove((ZixTree*)world->loaded_files, iter); - return 0; - } - return 1; + ZixTreeIter* iter = NULL; + if (!zix_tree_find((ZixTree*)world->loaded_files, file, &iter)) { + zix_tree_remove((ZixTree*)world->loaded_files, iter); + return 0; + } + return 1; } int lilv_world_unload_bundle(LilvWorld* world, const LilvNode* bundle_uri) { - if (!bundle_uri) { - return 0; - } - - // Find all loaded files that are inside the bundle - LilvNodes* files = lilv_nodes_new(); - LILV_FOREACH(nodes, i, world->loaded_files) { - const LilvNode* file = lilv_nodes_get(world->loaded_files, i); - if (!strncmp(lilv_node_as_string(file), - lilv_node_as_string(bundle_uri), - strlen(lilv_node_as_string(bundle_uri)))) { - zix_tree_insert((ZixTree*)files, - lilv_node_duplicate(file), - NULL); - } - } - - // Unload all loaded files in the bundle - LILV_FOREACH(nodes, i, files) { - const LilvNode* file = lilv_nodes_get(world->plugins, i); - lilv_world_unload_file(world, file); - } - - lilv_nodes_free(files); - - /* Remove any plugins in the bundle from the plugin list. Since the - application may still have a pointer to the LilvPlugin, it can not be - destroyed here. Instead, we move it to the zombie plugin list, so it - will not be in the list returned by lilv_world_get_all_plugins() but can - still be used. - */ - ZixTreeIter* i = zix_tree_begin((ZixTree*)world->plugins); - while (i != zix_tree_end((ZixTree*)world->plugins)) { - LilvPlugin* p = (LilvPlugin*)zix_tree_get(i); - ZixTreeIter* next = zix_tree_iter_next(i); - - if (lilv_node_equals(lilv_plugin_get_bundle_uri(p), bundle_uri)) { - zix_tree_remove((ZixTree*)world->plugins, i); - zix_tree_insert((ZixTree*)world->zombies, p, NULL); - } - - i = next; - } - - // Drop everything in bundle graph - return lilv_world_drop_graph(world, bundle_uri->node); + if (!bundle_uri) { + return 0; + } + + // Find all loaded files that are inside the bundle + LilvNodes* files = lilv_nodes_new(); + LILV_FOREACH (nodes, i, world->loaded_files) { + const LilvNode* file = lilv_nodes_get(world->loaded_files, i); + if (!strncmp(lilv_node_as_string(file), + lilv_node_as_string(bundle_uri), + strlen(lilv_node_as_string(bundle_uri)))) { + zix_tree_insert((ZixTree*)files, lilv_node_duplicate(file), NULL); + } + } + + // Unload all loaded files in the bundle + LILV_FOREACH (nodes, i, files) { + const LilvNode* file = lilv_nodes_get(world->plugins, i); + lilv_world_unload_file(world, file); + } + + lilv_nodes_free(files); + + /* Remove any plugins in the bundle from the plugin list. Since the + application may still have a pointer to the LilvPlugin, it can not be + destroyed here. Instead, we move it to the zombie plugin list, so it + will not be in the list returned by lilv_world_get_all_plugins() but can + still be used. + */ + ZixTreeIter* i = zix_tree_begin((ZixTree*)world->plugins); + while (i != zix_tree_end((ZixTree*)world->plugins)) { + LilvPlugin* p = (LilvPlugin*)zix_tree_get(i); + ZixTreeIter* next = zix_tree_iter_next(i); + + if (lilv_node_equals(lilv_plugin_get_bundle_uri(p), bundle_uri)) { + zix_tree_remove((ZixTree*)world->plugins, i); + zix_tree_insert((ZixTree*)world->zombies, p, NULL); + } + + i = next; + } + + // Drop everything in bundle graph + return lilv_world_drop_graph(world, bundle_uri->node); } static void load_dir_entry(const char* dir, const char* name, void* data) { - LilvWorld* world = (LilvWorld*)data; - char* path = lilv_strjoin(dir, "/", name, "/", NULL); - SerdNode suri = serd_node_new_file_uri((const uint8_t*)path, 0, 0, true); - LilvNode* node = lilv_new_uri(world, (const char*)suri.buf); - - lilv_world_load_bundle(world, node); - lilv_node_free(node); - serd_node_free(&suri); - free(path); + LilvWorld* world = (LilvWorld*)data; + char* path = lilv_strjoin(dir, "/", name, "/", NULL); + SerdNode suri = serd_node_new_file_uri((const uint8_t*)path, 0, 0, true); + LilvNode* node = lilv_new_uri(world, (const char*)suri.buf); + + lilv_world_load_bundle(world, node); + lilv_node_free(node); + serd_node_free(&suri); + free(path); } /** Load all bundles in the directory at `dir_path`. */ static void lilv_world_load_directory(LilvWorld* world, const char* dir_path) { - char* path = lilv_expand(dir_path); - if (path) { - lilv_dir_for_each(path, world, load_dir_entry); - free(path); - } + char* path = lilv_expand(dir_path); + if (path) { + lilv_dir_for_each(path, world, load_dir_entry); + free(path); + } } static const char* first_path_sep(const char* path) { - for (const char* p = path; *p != '\0'; ++p) { - if (*p == LILV_PATH_SEP[0]) { - return p; - } - } - return NULL; + for (const char* p = path; *p != '\0'; ++p) { + if (*p == LILV_PATH_SEP[0]) { + return p; + } + } + return NULL; } /** Load all bundles found in `lv2_path`. @@ -1000,279 +971,265 @@ first_path_sep(const char* path) * parent directories of bundles, not a list of bundle directories). */ static void -lilv_world_load_path(LilvWorld* world, - const char* lv2_path) +lilv_world_load_path(LilvWorld* world, const char* lv2_path) { - while (lv2_path[0] != '\0') { - const char* const sep = first_path_sep(lv2_path); - if (sep) { - const size_t dir_len = sep - lv2_path; - char* const dir = (char*)malloc(dir_len + 1); - memcpy(dir, lv2_path, dir_len); - dir[dir_len] = '\0'; - lilv_world_load_directory(world, dir); - free(dir); - lv2_path += dir_len + 1; - } else { - lilv_world_load_directory(world, lv2_path); - lv2_path = "\0"; - } - } + while (lv2_path[0] != '\0') { + const char* const sep = first_path_sep(lv2_path); + if (sep) { + const size_t dir_len = sep - lv2_path; + char* const dir = (char*)malloc(dir_len + 1); + memcpy(dir, lv2_path, dir_len); + dir[dir_len] = '\0'; + lilv_world_load_directory(world, dir); + free(dir); + lv2_path += dir_len + 1; + } else { + lilv_world_load_directory(world, lv2_path); + lv2_path = "\0"; + } + } } void lilv_world_load_specifications(LilvWorld* world) { - for (LilvSpec* spec = world->specs; spec; spec = spec->next) { - LILV_FOREACH(nodes, f, spec->data_uris) { - LilvNode* file = (LilvNode*)lilv_collection_get(spec->data_uris, f); - lilv_world_load_graph(world, NULL, file); - } - } + for (LilvSpec* spec = world->specs; spec; spec = spec->next) { + LILV_FOREACH (nodes, f, spec->data_uris) { + LilvNode* file = (LilvNode*)lilv_collection_get(spec->data_uris, f); + lilv_world_load_graph(world, NULL, file); + } + } } void lilv_world_load_plugin_classes(LilvWorld* world) { - /* FIXME: This loads all classes, not just lv2:Plugin subclasses. - However, if the host gets all the classes via lilv_plugin_class_get_children - starting with lv2:Plugin as the root (which is e.g. how a host would build - a menu), they won't be seen anyway... - */ - - SordIter* classes = sord_search(world->model, - NULL, - world->uris.rdf_a, - world->uris.rdfs_Class, - NULL); - FOREACH_MATCH(classes) { - const SordNode* class_node = sord_iter_get_node(classes, SORD_SUBJECT); - - SordNode* parent = sord_get( - world->model, class_node, world->uris.rdfs_subClassOf, NULL, NULL); - if (!parent || sord_node_get_type(parent) != SORD_URI) { - continue; - } - - SordNode* label = sord_get( - world->model, class_node, world->uris.rdfs_label, NULL, NULL); - if (!label) { - sord_node_free(world->world, parent); - continue; - } - - LilvPluginClass* pclass = lilv_plugin_class_new( - world, parent, class_node, - (const char*)sord_node_get_string(label)); - if (pclass) { - zix_tree_insert((ZixTree*)world->plugin_classes, pclass, NULL); - } - - sord_node_free(world->world, label); - sord_node_free(world->world, parent); - } - sord_iter_free(classes); + /* FIXME: This loads all classes, not just lv2:Plugin subclasses. + However, if the host gets all the classes via + lilv_plugin_class_get_children starting with lv2:Plugin as the root (which + is e.g. how a host would build a menu), they won't be seen anyway... + */ + + SordIter* classes = sord_search( + world->model, NULL, world->uris.rdf_a, world->uris.rdfs_Class, NULL); + FOREACH_MATCH (classes) { + const SordNode* class_node = sord_iter_get_node(classes, SORD_SUBJECT); + + SordNode* parent = sord_get( + world->model, class_node, world->uris.rdfs_subClassOf, NULL, NULL); + if (!parent || sord_node_get_type(parent) != SORD_URI) { + continue; + } + + SordNode* label = + sord_get(world->model, class_node, world->uris.rdfs_label, NULL, NULL); + if (!label) { + sord_node_free(world->world, parent); + continue; + } + + LilvPluginClass* pclass = lilv_plugin_class_new( + world, parent, class_node, (const char*)sord_node_get_string(label)); + if (pclass) { + zix_tree_insert((ZixTree*)world->plugin_classes, pclass, NULL); + } + + sord_node_free(world->world, label); + sord_node_free(world->world, parent); + } + sord_iter_free(classes); } void lilv_world_load_all(LilvWorld* world) { - const char* lv2_path = world->opt.lv2_path; - if (!lv2_path) { - lv2_path = getenv("LV2_PATH"); - } - if (!lv2_path) { - lv2_path = LILV_DEFAULT_LV2_PATH; - } - - // Discover bundles and read all manifest files into model - lilv_world_load_path(world, lv2_path); - - LILV_FOREACH(plugins, p, world->plugins) { - const LilvPlugin* plugin = (const LilvPlugin*)lilv_collection_get( - (ZixTree*)world->plugins, p); - - // ?new dc:replaces plugin - if (sord_ask(world->model, - NULL, - world->uris.dc_replaces, - lilv_plugin_get_uri(plugin)->node, - NULL)) { - // TODO: Check if replacement is a known plugin? (expensive) - ((LilvPlugin*)plugin)->replaced = true; - } - } - - // Query out things to cache - lilv_world_load_specifications(world); - lilv_world_load_plugin_classes(world); + const char* lv2_path = world->opt.lv2_path; + if (!lv2_path) { + lv2_path = getenv("LV2_PATH"); + } + if (!lv2_path) { + lv2_path = LILV_DEFAULT_LV2_PATH; + } + + // Discover bundles and read all manifest files into model + lilv_world_load_path(world, lv2_path); + + LILV_FOREACH (plugins, p, world->plugins) { + const LilvPlugin* plugin = + (const LilvPlugin*)lilv_collection_get((ZixTree*)world->plugins, p); + + // ?new dc:replaces plugin + if (sord_ask(world->model, + NULL, + world->uris.dc_replaces, + lilv_plugin_get_uri(plugin)->node, + NULL)) { + // TODO: Check if replacement is a known plugin? (expensive) + ((LilvPlugin*)plugin)->replaced = true; + } + } + + // Query out things to cache + lilv_world_load_specifications(world); + lilv_world_load_plugin_classes(world); } SerdStatus lilv_world_load_file(LilvWorld* world, SerdReader* reader, const LilvNode* uri) { - ZixTreeIter* iter = NULL; - if (!zix_tree_find((ZixTree*)world->loaded_files, uri, &iter)) { - return SERD_FAILURE; // File has already been loaded - } - - size_t uri_len = 0; - const uint8_t* const uri_str = sord_node_get_string_counted( - uri->node, &uri_len); - if (strncmp((const char*)uri_str, "file:", 5)) { - return SERD_FAILURE; // Not a local file - } - - if (strcmp((const char*)uri_str + uri_len - 4, ".ttl")) { - return SERD_FAILURE; // Not a Turtle file - } - - serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world)); - const SerdStatus st = serd_reader_read_file(reader, uri_str); - if (st) { - LILV_ERRORF("Error loading file `%s'\n", lilv_node_as_string(uri)); - return st; - } - - zix_tree_insert((ZixTree*)world->loaded_files, - lilv_node_duplicate(uri), - NULL); - return SERD_SUCCESS; + ZixTreeIter* iter = NULL; + if (!zix_tree_find((ZixTree*)world->loaded_files, uri, &iter)) { + return SERD_FAILURE; // File has already been loaded + } + + size_t uri_len = 0; + const uint8_t* const uri_str = + sord_node_get_string_counted(uri->node, &uri_len); + if (strncmp((const char*)uri_str, "file:", 5)) { + return SERD_FAILURE; // Not a local file + } + + if (strcmp((const char*)uri_str + uri_len - 4, ".ttl")) { + return SERD_FAILURE; // Not a Turtle file + } + + serd_reader_add_blank_prefix(reader, lilv_world_blank_node_prefix(world)); + const SerdStatus st = serd_reader_read_file(reader, uri_str); + if (st) { + LILV_ERRORF("Error loading file `%s'\n", lilv_node_as_string(uri)); + return st; + } + + zix_tree_insert( + (ZixTree*)world->loaded_files, lilv_node_duplicate(uri), NULL); + return SERD_SUCCESS; } int -lilv_world_load_resource(LilvWorld* world, - const LilvNode* resource) +lilv_world_load_resource(LilvWorld* world, const LilvNode* resource) { - if (!lilv_node_is_uri(resource) && !lilv_node_is_blank(resource)) { - LILV_ERRORF("Node `%s' is not a resource\n", - sord_node_get_string(resource->node)); - return -1; - } - - SordModel* files = lilv_world_filter_model(world, - world->model, - resource->node, - world->uris.rdfs_seeAlso, - NULL, NULL); - - SordIter* f = sord_begin(files); - int n_read = 0; - FOREACH_MATCH(f) { - const SordNode* file = sord_iter_get_node(f, SORD_OBJECT); - const uint8_t* file_str = sord_node_get_string(file); - LilvNode* file_node = lilv_node_new_from_node(world, file); - if (sord_node_get_type(file) != SORD_URI) { - LILV_ERRORF("rdfs:seeAlso node `%s' is not a URI\n", file_str); - } else if (!lilv_world_load_graph(world, (SordNode*)file, file_node)) { - ++n_read; - } - lilv_node_free(file_node); - } - sord_iter_free(f); - - sord_free(files); - return n_read; + if (!lilv_node_is_uri(resource) && !lilv_node_is_blank(resource)) { + LILV_ERRORF("Node `%s' is not a resource\n", + sord_node_get_string(resource->node)); + return -1; + } + + SordModel* files = lilv_world_filter_model( + world, world->model, resource->node, world->uris.rdfs_seeAlso, NULL, NULL); + + SordIter* f = sord_begin(files); + int n_read = 0; + FOREACH_MATCH (f) { + const SordNode* file = sord_iter_get_node(f, SORD_OBJECT); + const uint8_t* file_str = sord_node_get_string(file); + LilvNode* file_node = lilv_node_new_from_node(world, file); + if (sord_node_get_type(file) != SORD_URI) { + LILV_ERRORF("rdfs:seeAlso node `%s' is not a URI\n", file_str); + } else if (!lilv_world_load_graph(world, (SordNode*)file, file_node)) { + ++n_read; + } + lilv_node_free(file_node); + } + sord_iter_free(f); + + sord_free(files); + return n_read; } int -lilv_world_unload_resource(LilvWorld* world, - const LilvNode* resource) +lilv_world_unload_resource(LilvWorld* world, const LilvNode* resource) { - if (!lilv_node_is_uri(resource) && !lilv_node_is_blank(resource)) { - LILV_ERRORF("Node `%s' is not a resource\n", - sord_node_get_string(resource->node)); - return -1; - } - - SordModel* files = lilv_world_filter_model(world, - world->model, - resource->node, - world->uris.rdfs_seeAlso, - NULL, NULL); - - SordIter* f = sord_begin(files); - int n_dropped = 0; - FOREACH_MATCH(f) { - const SordNode* file = sord_iter_get_node(f, SORD_OBJECT); - LilvNode* file_node = lilv_node_new_from_node(world, file); - if (sord_node_get_type(file) != SORD_URI) { - LILV_ERRORF("rdfs:seeAlso node `%s' is not a URI\n", - sord_node_get_string(file)); - } else if (!lilv_world_drop_graph(world, file_node->node)) { - lilv_world_unload_file(world, file_node); - ++n_dropped; - } - lilv_node_free(file_node); - } - sord_iter_free(f); - - sord_free(files); - return n_dropped; + if (!lilv_node_is_uri(resource) && !lilv_node_is_blank(resource)) { + LILV_ERRORF("Node `%s' is not a resource\n", + sord_node_get_string(resource->node)); + return -1; + } + + SordModel* files = lilv_world_filter_model( + world, world->model, resource->node, world->uris.rdfs_seeAlso, NULL, NULL); + + SordIter* f = sord_begin(files); + int n_dropped = 0; + FOREACH_MATCH (f) { + const SordNode* file = sord_iter_get_node(f, SORD_OBJECT); + LilvNode* file_node = lilv_node_new_from_node(world, file); + if (sord_node_get_type(file) != SORD_URI) { + LILV_ERRORF("rdfs:seeAlso node `%s' is not a URI\n", + sord_node_get_string(file)); + } else if (!lilv_world_drop_graph(world, file_node->node)) { + lilv_world_unload_file(world, file_node); + ++n_dropped; + } + lilv_node_free(file_node); + } + sord_iter_free(f); + + sord_free(files); + return n_dropped; } const LilvPluginClass* lilv_world_get_plugin_class(const LilvWorld* world) { - return world->lv2_plugin_class; + return world->lv2_plugin_class; } const LilvPluginClasses* lilv_world_get_plugin_classes(const LilvWorld* world) { - return world->plugin_classes; + return world->plugin_classes; } const LilvPlugins* lilv_world_get_all_plugins(const LilvWorld* world) { - return world->plugins; + return world->plugins; } LilvNode* lilv_world_get_symbol(LilvWorld* world, const LilvNode* subject) { - // Check for explicitly given symbol - SordNode* snode = sord_get( - world->model, subject->node, world->uris.lv2_symbol, NULL, NULL); - - if (snode) { - LilvNode* ret = lilv_node_new_from_node(world, snode); - sord_node_free(world->world, snode); - return ret; - } - - if (!lilv_node_is_uri(subject)) { - return NULL; - } - - // Find rightmost segment of URI - SerdURI uri; - serd_uri_parse((const uint8_t*)lilv_node_as_uri(subject), &uri); - const char* str = "_"; - if (uri.fragment.buf) { - str = (const char*)uri.fragment.buf + 1; - } else if (uri.query.buf) { - str = (const char*)uri.query.buf; - } else if (uri.path.buf) { - const char* last_slash = strrchr((const char*)uri.path.buf, '/'); - str = last_slash ? (last_slash + 1) : (const char*)uri.path.buf; - } - - // Replace invalid characters - const size_t len = strlen(str); - char* const sym = (char*)calloc(1, len + 1); - for (size_t i = 0; i < len; ++i) { - const char c = str[i]; - if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || - (c == '_') || (i > 0 && c >= '0' && c <= '9'))) { - sym[i] = '_'; - } else { - sym[i] = str[i]; - } - } - - LilvNode* ret = lilv_new_string(world, sym); - free(sym); - return ret; + // Check for explicitly given symbol + SordNode* snode = + sord_get(world->model, subject->node, world->uris.lv2_symbol, NULL, NULL); + + if (snode) { + LilvNode* ret = lilv_node_new_from_node(world, snode); + sord_node_free(world->world, snode); + return ret; + } + + if (!lilv_node_is_uri(subject)) { + return NULL; + } + + // Find rightmost segment of URI + SerdURI uri; + serd_uri_parse((const uint8_t*)lilv_node_as_uri(subject), &uri); + const char* str = "_"; + if (uri.fragment.buf) { + str = (const char*)uri.fragment.buf + 1; + } else if (uri.query.buf) { + str = (const char*)uri.query.buf; + } else if (uri.path.buf) { + const char* last_slash = strrchr((const char*)uri.path.buf, '/'); + str = last_slash ? (last_slash + 1) : (const char*)uri.path.buf; + } + + // Replace invalid characters + const size_t len = strlen(str); + char* const sym = (char*)calloc(1, len + 1); + for (size_t i = 0; i < len; ++i) { + const char c = str[i]; + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || + (i > 0 && c >= '0' && c <= '9'))) { + sym[i] = '_'; + } else { + sym[i] = str[i]; + } + } + + LilvNode* ret = lilv_new_string(world, sym); + free(sym); + return ret; } diff --git a/src/zix/common.h b/src/zix/common.h index 32019e9..730a450 100644 --- a/src/zix/common.h +++ b/src/zix/common.h @@ -24,42 +24,42 @@ /** @cond */ #ifdef ZIX_SHARED -# ifdef _WIN32 -# define ZIX_LIB_IMPORT __declspec(dllimport) -# define ZIX_LIB_EXPORT __declspec(dllexport) -# else -# define ZIX_LIB_IMPORT __attribute__((visibility("default"))) -# define ZIX_LIB_EXPORT __attribute__((visibility("default"))) -# endif -# ifdef ZIX_INTERNAL -# define ZIX_API ZIX_LIB_EXPORT -# else -# define ZIX_API ZIX_LIB_IMPORT -# endif -# define ZIX_PRIVATE static +# ifdef _WIN32 +# define ZIX_LIB_IMPORT __declspec(dllimport) +# define ZIX_LIB_EXPORT __declspec(dllexport) +# else +# define ZIX_LIB_IMPORT __attribute__((visibility("default"))) +# define ZIX_LIB_EXPORT __attribute__((visibility("default"))) +# endif +# ifdef ZIX_INTERNAL +# define ZIX_API ZIX_LIB_EXPORT +# else +# define ZIX_API ZIX_LIB_IMPORT +# endif +# define ZIX_PRIVATE static #elif defined(ZIX_INLINE) -# define ZIX_API static inline -# define ZIX_PRIVATE static inline +# define ZIX_API static inline +# define ZIX_PRIVATE static inline #else -# define ZIX_API -# define ZIX_PRIVATE static +# define ZIX_API +# define ZIX_PRIVATE static #endif /** @endcond */ #ifdef __cplusplus extern "C" { #else -# include <stdbool.h> +# include <stdbool.h> #endif typedef enum { - ZIX_STATUS_SUCCESS, - ZIX_STATUS_ERROR, - ZIX_STATUS_NO_MEM, - ZIX_STATUS_NOT_FOUND, - ZIX_STATUS_EXISTS, - ZIX_STATUS_BAD_ARG, - ZIX_STATUS_BAD_PERMS + ZIX_STATUS_SUCCESS, + ZIX_STATUS_ERROR, + ZIX_STATUS_NO_MEM, + ZIX_STATUS_NOT_FOUND, + ZIX_STATUS_EXISTS, + ZIX_STATUS_BAD_ARG, + ZIX_STATUS_BAD_PERMS } ZixStatus; /** @@ -82,7 +82,7 @@ typedef void (*ZixDestroyFunc)(void* ptr); */ #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif -#endif /* ZIX_COMMON_H */ +#endif /* ZIX_COMMON_H */ diff --git a/src/zix/tree.c b/src/zix/tree.c index 15cea9a..a12d411 100644 --- a/src/zix/tree.c +++ b/src/zix/tree.c @@ -14,8 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "zix/common.h" #include "zix/tree.h" +#include "zix/common.h" #include <assert.h> #include <stdint.h> @@ -25,20 +25,20 @@ typedef struct ZixTreeNodeImpl ZixTreeNode; struct ZixTreeImpl { - ZixTreeNode* root; - ZixDestroyFunc destroy; - ZixComparator cmp; - void* cmp_data; - size_t size; - bool allow_duplicates; + ZixTreeNode* root; + ZixDestroyFunc destroy; + ZixComparator cmp; + void* cmp_data; + size_t size; + bool allow_duplicates; }; struct ZixTreeNodeImpl { - void* data; - struct ZixTreeNodeImpl* left; - struct ZixTreeNodeImpl* right; - struct ZixTreeNodeImpl* parent; - int_fast8_t balance; + void* data; + struct ZixTreeNodeImpl* left; + struct ZixTreeNodeImpl* right; + struct ZixTreeNodeImpl* parent; + int_fast8_t balance; }; #define MIN(a, b) (((a) < (b)) ? (a) : (b)) @@ -50,98 +50,98 @@ struct ZixTreeNodeImpl { // #define ZIX_TREE_HYPER_VERIFY 1 #if defined(ZIX_TREE_VERIFY) || defined(ZIX_TREE_HYPER_VERIFY) -# include "tree_debug.h" -# define ASSERT_BALANCE(n) assert(verify_balance(n)) +# include "tree_debug.h" +# define ASSERT_BALANCE(n) assert(verify_balance(n)) #else -# define ASSERT_BALANCE(n) +# define ASSERT_BALANCE(n) #endif #ifdef ZIX_TREE_DUMP -# include "tree_debug.h" -# define DUMP(t) zix_tree_print(t->root, 0) -# define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__) +# include "tree_debug.h" +# define DUMP(t) zix_tree_print(t->root, 0) +# define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__) #else -# define DUMP(t) -# define DEBUG_PRINTF(fmt, ...) +# define DUMP(t) +# define DEBUG_PRINTF(fmt, ...) #endif ZIX_API ZixTree* -zix_tree_new(bool allow_duplicates, - ZixComparator cmp, - void* cmp_data, - ZixDestroyFunc destroy) + zix_tree_new(bool allow_duplicates, + ZixComparator cmp, + void* cmp_data, + ZixDestroyFunc destroy) { - ZixTree* t = (ZixTree*)malloc(sizeof(ZixTree)); - t->root = NULL; - t->destroy = destroy; - t->cmp = cmp; - t->cmp_data = cmp_data; - t->size = 0; - t->allow_duplicates = allow_duplicates; - return t; + ZixTree* t = (ZixTree*)malloc(sizeof(ZixTree)); + t->root = NULL; + t->destroy = destroy; + t->cmp = cmp; + t->cmp_data = cmp_data; + t->size = 0; + t->allow_duplicates = allow_duplicates; + return t; } ZIX_PRIVATE void zix_tree_free_rec(ZixTree* t, ZixTreeNode* n) { - if (n) { - zix_tree_free_rec(t, n->left); - zix_tree_free_rec(t, n->right); - if (t->destroy) { - t->destroy(n->data); - } - free(n); - } + if (n) { + zix_tree_free_rec(t, n->left); + zix_tree_free_rec(t, n->right); + if (t->destroy) { + t->destroy(n->data); + } + free(n); + } } ZIX_API void zix_tree_free(ZixTree* t) { - if (t) { - zix_tree_free_rec(t, t->root); - free(t); - } + if (t) { + zix_tree_free_rec(t, t->root); + free(t); + } } ZIX_API size_t zix_tree_size(const ZixTree* t) { - return t->size; + return t->size; } ZIX_PRIVATE void rotate(ZixTreeNode* p, ZixTreeNode* q) { - assert(q->parent == p); - assert(p->left == q || p->right == q); - - q->parent = p->parent; - if (q->parent) { - if (q->parent->left == p) { - q->parent->left = q; - } else { - q->parent->right = q; - } - } - - if (p->right == q) { - // Rotate left - p->right = q->left; - q->left = p; - if (p->right) { - p->right->parent = p; - } - } else { - // Rotate right - assert(p->left == q); - p->left = q->right; - q->right = p; - if (p->left) { - p->left->parent = p; - } - } - - p->parent = q; + assert(q->parent == p); + assert(p->left == q || p->right == q); + + q->parent = p->parent; + if (q->parent) { + if (q->parent->left == p) { + q->parent->left = q; + } else { + q->parent->right = q; + } + } + + if (p->right == q) { + // Rotate left + p->right = q->left; + q->left = p; + if (p->right) { + p->right->parent = p; + } + } else { + // Rotate right + assert(p->left == q); + p->left = q->right; + q->right = p; + if (p->left) { + p->left->parent = p; + } + } + + p->parent = q; } /** @@ -154,26 +154,26 @@ rotate(ZixTreeNode* p, ZixTreeNode* q) * B C A B */ ZIX_PRIVATE ZixTreeNode* -rotate_left(ZixTreeNode* p, int* height_change) + rotate_left(ZixTreeNode* p, int* height_change) { - ZixTreeNode* const q = p->right; - *height_change = (q->balance == 0) ? 0 : -1; + ZixTreeNode* const q = p->right; + *height_change = (q->balance == 0) ? 0 : -1; - DEBUG_PRINTF("LL %ld\n", (intptr_t)p->data); + DEBUG_PRINTF("LL %ld\n", (intptr_t)p->data); - assert(p->balance == 2); - assert(q->balance == 0 || q->balance == 1); + assert(p->balance == 2); + assert(q->balance == 0 || q->balance == 1); - rotate(p, q); + rotate(p, q); - // p->balance -= 1 + MAX(0, q->balance); - // q->balance -= 1 - MIN(0, p->balance); - --q->balance; - p->balance = -(q->balance); + // p->balance -= 1 + MAX(0, q->balance); + // q->balance -= 1 - MIN(0, p->balance); + --q->balance; + p->balance = -(q->balance); - ASSERT_BALANCE(p); - ASSERT_BALANCE(q); - return q; + ASSERT_BALANCE(p); + ASSERT_BALANCE(q); + return q; } /** @@ -187,26 +187,26 @@ rotate_left(ZixTreeNode* p, int* height_change) * */ ZIX_PRIVATE ZixTreeNode* -rotate_right(ZixTreeNode* p, int* height_change) + rotate_right(ZixTreeNode* p, int* height_change) { - ZixTreeNode* const q = p->left; - *height_change = (q->balance == 0) ? 0 : -1; + ZixTreeNode* const q = p->left; + *height_change = (q->balance == 0) ? 0 : -1; - DEBUG_PRINTF("RR %ld\n", (intptr_t)p->data); + DEBUG_PRINTF("RR %ld\n", (intptr_t)p->data); - assert(p->balance == -2); - assert(q->balance == 0 || q->balance == -1); + assert(p->balance == -2); + assert(q->balance == 0 || q->balance == -1); - rotate(p, q); + rotate(p, q); - // p->balance += 1 - MIN(0, q->balance); - // q->balance += 1 + MAX(0, p->balance); - ++q->balance; - p->balance = -(q->balance); + // p->balance += 1 - MIN(0, q->balance); + // q->balance += 1 + MAX(0, p->balance); + ++q->balance; + p->balance = -(q->balance); - ASSERT_BALANCE(p); - ASSERT_BALANCE(q); - return q; + ASSERT_BALANCE(p); + ASSERT_BALANCE(q); + return q; } /** @@ -222,35 +222,38 @@ rotate_right(ZixTreeNode* p, int* height_change) * */ ZIX_PRIVATE ZixTreeNode* -rotate_left_right(ZixTreeNode* p, int* height_change) + rotate_left_right(ZixTreeNode* p, int* height_change) { - ZixTreeNode* const q = p->left; - ZixTreeNode* const r = q->right; + ZixTreeNode* const q = p->left; + ZixTreeNode* const r = q->right; - assert(p->balance == -2); - assert(q->balance == 1); - assert(r->balance == -1 || r->balance == 0 || r->balance == 1); + assert(p->balance == -2); + assert(q->balance == 1); + assert(r->balance == -1 || r->balance == 0 || r->balance == 1); - DEBUG_PRINTF("LR %ld P: %2d Q: %2d R: %2d\n", - (intptr_t)p->data, p->balance, q->balance, r->balance); + DEBUG_PRINTF("LR %ld P: %2d Q: %2d R: %2d\n", + (intptr_t)p->data, + p->balance, + q->balance, + r->balance); - rotate(q, r); - rotate(p, r); + rotate(q, r); + rotate(p, r); - q->balance -= 1 + MAX(0, r->balance); - p->balance += 1 - MIN(MIN(0, r->balance) - 1, r->balance + q->balance); - // r->balance += MAX(0, p->balance) + MIN(0, q->balance); + q->balance -= 1 + MAX(0, r->balance); + p->balance += 1 - MIN(MIN(0, r->balance) - 1, r->balance + q->balance); + // r->balance += MAX(0, p->balance) + MIN(0, q->balance); - // p->balance = (p->left && p->right) ? -MIN(r->balance, 0) : 0; - // q->balance = - MAX(r->balance, 0); - r->balance = 0; + // p->balance = (p->left && p->right) ? -MIN(r->balance, 0) : 0; + // q->balance = - MAX(r->balance, 0); + r->balance = 0; - *height_change = -1; + *height_change = -1; - ASSERT_BALANCE(p); - ASSERT_BALANCE(q); - ASSERT_BALANCE(r); - return r; + ASSERT_BALANCE(p); + ASSERT_BALANCE(q); + ASSERT_BALANCE(r); + return r; } /** @@ -266,452 +269,454 @@ rotate_left_right(ZixTreeNode* p, int* height_change) * */ ZIX_PRIVATE ZixTreeNode* -rotate_right_left(ZixTreeNode* p, int* height_change) + rotate_right_left(ZixTreeNode* p, int* height_change) { - ZixTreeNode* const q = p->right; - ZixTreeNode* const r = q->left; + ZixTreeNode* const q = p->right; + ZixTreeNode* const r = q->left; - assert(p->balance == 2); - assert(q->balance == -1); - assert(r->balance == -1 || r->balance == 0 || r->balance == 1); + assert(p->balance == 2); + assert(q->balance == -1); + assert(r->balance == -1 || r->balance == 0 || r->balance == 1); - DEBUG_PRINTF("RL %ld P: %2d Q: %2d R: %2d\n", - (intptr_t)p->data, p->balance, q->balance, r->balance); + DEBUG_PRINTF("RL %ld P: %2d Q: %2d R: %2d\n", + (intptr_t)p->data, + p->balance, + q->balance, + r->balance); - rotate(q, r); - rotate(p, r); + rotate(q, r); + rotate(p, r); - q->balance += 1 - MIN(0, r->balance); - p->balance -= 1 + MAX(MAX(0, r->balance) + 1, r->balance + q->balance); - // r->balance += MAX(0, q->balance) + MIN(0, p->balance); + q->balance += 1 - MIN(0, r->balance); + p->balance -= 1 + MAX(MAX(0, r->balance) + 1, r->balance + q->balance); + // r->balance += MAX(0, q->balance) + MIN(0, p->balance); - // p->balance = (p->left && p->right) ? -MAX(r->balance, 0) : 0; - // q->balance = - MIN(r->balance, 0); - r->balance = 0; - // assert(r->balance == 0); + // p->balance = (p->left && p->right) ? -MAX(r->balance, 0) : 0; + // q->balance = - MIN(r->balance, 0); + r->balance = 0; + // assert(r->balance == 0); - *height_change = -1; + *height_change = -1; - ASSERT_BALANCE(p); - ASSERT_BALANCE(q); - ASSERT_BALANCE(r); - return r; + ASSERT_BALANCE(p); + ASSERT_BALANCE(q); + ASSERT_BALANCE(r); + return r; } ZIX_PRIVATE ZixTreeNode* zix_tree_rebalance(ZixTree* t, ZixTreeNode* node, int* height_change) { #ifdef ZIX_TREE_HYPER_VERIFY - const size_t old_height = height(node); + const size_t old_height = height(node); #endif - DEBUG_PRINTF("REBALANCE %ld (%d)\n", (intptr_t)node->data, node->balance); - *height_change = 0; - const bool is_root = !node->parent; - assert((is_root && t->root == node) || (!is_root && t->root != node)); - ZixTreeNode* replacement = node; - if (node->balance == -2) { - assert(node->left); - if (node->left->balance == 1) { - replacement = rotate_left_right(node, height_change); - } else { - replacement = rotate_right(node, height_change); - } - } else if (node->balance == 2) { - assert(node->right); - if (node->right->balance == -1) { - replacement = rotate_right_left(node, height_change); - } else { - replacement = rotate_left(node, height_change); - } - } - if (is_root) { - assert(!replacement->parent); - t->root = replacement; - } - DUMP(t); + DEBUG_PRINTF("REBALANCE %ld (%d)\n", (intptr_t)node->data, node->balance); + *height_change = 0; + const bool is_root = !node->parent; + assert((is_root && t->root == node) || (!is_root && t->root != node)); + ZixTreeNode* replacement = node; + if (node->balance == -2) { + assert(node->left); + if (node->left->balance == 1) { + replacement = rotate_left_right(node, height_change); + } else { + replacement = rotate_right(node, height_change); + } + } else if (node->balance == 2) { + assert(node->right); + if (node->right->balance == -1) { + replacement = rotate_right_left(node, height_change); + } else { + replacement = rotate_left(node, height_change); + } + } + if (is_root) { + assert(!replacement->parent); + t->root = replacement; + } + DUMP(t); #ifdef ZIX_TREE_HYPER_VERIFY - assert(old_height + *height_change == height(replacement)); + assert(old_height + *height_change == height(replacement)); #endif - return replacement; + return replacement; } ZIX_API ZixStatus zix_tree_insert(ZixTree* t, void* e, ZixTreeIter** ti) { - DEBUG_PRINTF("**** INSERT %ld\n", (intptr_t)e); - int cmp = 0; - ZixTreeNode* n = t->root; - ZixTreeNode* p = NULL; - - // Find the parent p of e - while (n) { - p = n; - cmp = t->cmp(e, n->data, t->cmp_data); - if (cmp < 0) { - n = n->left; - } else if (cmp > 0) { - n = n->right; - } else if (t->allow_duplicates) { - n = n->right; - } else { - if (ti) { - *ti = n; - } - DEBUG_PRINTF("%ld EXISTS!\n", (intptr_t)e); - return ZIX_STATUS_EXISTS; - } - } - - // Allocate a new node n - if (!(n = (ZixTreeNode*)malloc(sizeof(ZixTreeNode)))) { - return ZIX_STATUS_NO_MEM; - } - memset(n, '\0', sizeof(ZixTreeNode)); - n->data = e; - n->balance = 0; - if (ti) { - *ti = n; - } - - bool p_height_increased = false; - - // Make p the parent of n - n->parent = p; - if (!p) { - t->root = n; - } else { - if (cmp < 0) { - assert(!p->left); - assert(p->balance == 0 || p->balance == 1); - p->left = n; - --p->balance; - p_height_increased = !p->right; - } else { - assert(!p->right); - assert(p->balance == 0 || p->balance == -1); - p->right = n; - ++p->balance; - p_height_increased = !p->left; - } - } - - DUMP(t); - - // Rebalance if necessary (at most 1 rotation) - assert(!p || p->balance == -1 || p->balance == 0 || p->balance == 1); - if (p && p_height_increased) { - int height_change = 0; - for (ZixTreeNode* i = p; i && i->parent; i = i->parent) { - if (i == i->parent->left) { - if (--i->parent->balance == -2) { - zix_tree_rebalance(t, i->parent, &height_change); - break; - } - } else { - assert(i == i->parent->right); - if (++i->parent->balance == 2) { - zix_tree_rebalance(t, i->parent, &height_change); - break; - } - } - - if (i->parent->balance == 0) { - break; - } - } - } - - DUMP(t); - - ++t->size; + DEBUG_PRINTF("**** INSERT %ld\n", (intptr_t)e); + int cmp = 0; + ZixTreeNode* n = t->root; + ZixTreeNode* p = NULL; + + // Find the parent p of e + while (n) { + p = n; + cmp = t->cmp(e, n->data, t->cmp_data); + if (cmp < 0) { + n = n->left; + } else if (cmp > 0) { + n = n->right; + } else if (t->allow_duplicates) { + n = n->right; + } else { + if (ti) { + *ti = n; + } + DEBUG_PRINTF("%ld EXISTS!\n", (intptr_t)e); + return ZIX_STATUS_EXISTS; + } + } + + // Allocate a new node n + if (!(n = (ZixTreeNode*)malloc(sizeof(ZixTreeNode)))) { + return ZIX_STATUS_NO_MEM; + } + memset(n, '\0', sizeof(ZixTreeNode)); + n->data = e; + n->balance = 0; + if (ti) { + *ti = n; + } + + bool p_height_increased = false; + + // Make p the parent of n + n->parent = p; + if (!p) { + t->root = n; + } else { + if (cmp < 0) { + assert(!p->left); + assert(p->balance == 0 || p->balance == 1); + p->left = n; + --p->balance; + p_height_increased = !p->right; + } else { + assert(!p->right); + assert(p->balance == 0 || p->balance == -1); + p->right = n; + ++p->balance; + p_height_increased = !p->left; + } + } + + DUMP(t); + + // Rebalance if necessary (at most 1 rotation) + assert(!p || p->balance == -1 || p->balance == 0 || p->balance == 1); + if (p && p_height_increased) { + int height_change = 0; + for (ZixTreeNode* i = p; i && i->parent; i = i->parent) { + if (i == i->parent->left) { + if (--i->parent->balance == -2) { + zix_tree_rebalance(t, i->parent, &height_change); + break; + } + } else { + assert(i == i->parent->right); + if (++i->parent->balance == 2) { + zix_tree_rebalance(t, i->parent, &height_change); + break; + } + } + + if (i->parent->balance == 0) { + break; + } + } + } + + DUMP(t); + + ++t->size; #ifdef ZIX_TREE_VERIFY - if (!verify(t, t->root)) { - return ZIX_STATUS_ERROR; - } + if (!verify(t, t->root)) { + return ZIX_STATUS_ERROR; + } #endif - return ZIX_STATUS_SUCCESS; + return ZIX_STATUS_SUCCESS; } ZIX_API ZixStatus zix_tree_remove(ZixTree* t, ZixTreeIter* ti) { - ZixTreeNode* const n = ti; - ZixTreeNode** pp = NULL; // parent pointer - ZixTreeNode* to_balance = n->parent; // lowest node to balance - int8_t d_balance = 0; // delta(balance) for n->parent - - DEBUG_PRINTF("*** REMOVE %ld\n", (intptr_t)n->data); - - if ((n == t->root) && !n->left && !n->right) { - t->root = NULL; - if (t->destroy) { - t->destroy(n->data); - } - free(n); - --t->size; - assert(t->size == 0); - return ZIX_STATUS_SUCCESS; - } - - // Set pp to the parent pointer to n, if applicable - if (n->parent) { - assert(n->parent->left == n || n->parent->right == n); - if (n->parent->left == n) { // n is left child - pp = &n->parent->left; - d_balance = 1; - } else { // n is right child - assert(n->parent->right == n); - pp = &n->parent->right; - d_balance = -1; - } - } - - assert(!pp || *pp == n); - - int height_change = 0; - if (!n->left && !n->right) { - // n is a leaf, just remove it - if (pp) { - *pp = NULL; - to_balance = n->parent; - height_change = (!n->parent->left && !n->parent->right) ? -1 : 0; - } - } else if (!n->left) { - // Replace n with right (only) child - if (pp) { - *pp = n->right; - to_balance = n->parent; - } else { - t->root = n->right; - } - n->right->parent = n->parent; - height_change = -1; - } else if (!n->right) { - // Replace n with left (only) child - if (pp) { - *pp = n->left; - to_balance = n->parent; - } else { - t->root = n->left; - } - n->left->parent = n->parent; - height_change = -1; - } else { - // Replace n with in-order successor (leftmost child of right subtree) - ZixTreeNode* replace = n->right; - while (replace->left) { - assert(replace->left->parent == replace); - replace = replace->left; - } - - // Remove replace from parent (replace_p) - if (replace->parent->left == replace) { - height_change = replace->parent->right ? 0 : -1; - d_balance = 1; - to_balance = replace->parent; - replace->parent->left = replace->right; - } else { - assert(replace->parent == n); - height_change = replace->parent->left ? 0 : -1; - d_balance = -1; - to_balance = replace->parent; - replace->parent->right = replace->right; - } - - if (to_balance == n) { - to_balance = replace; - } - - if (replace->right) { - replace->right->parent = replace->parent; - } - - replace->balance = n->balance; - - // Swap node to delete with replace - if (pp) { - *pp = replace; - } else { - assert(t->root == n); - t->root = replace; - } - replace->parent = n->parent; - replace->left = n->left; - n->left->parent = replace; - replace->right = n->right; - if (n->right) { - n->right->parent = replace; - } - - assert(!replace->parent - || replace->parent->left == replace - || replace->parent->right == replace); - } - - // Rebalance starting at to_balance upwards. - for (ZixTreeNode* i = to_balance; i; i = i->parent) { - i->balance += d_balance; - if (d_balance == 0 || i->balance == -1 || i->balance == 1) { - break; - } - - assert(i != n); - i = zix_tree_rebalance(t, i, &height_change); - if (i->balance == 0) { - height_change = -1; - } - - if (i->parent) { - if (i == i->parent->left) { - d_balance = height_change * -1; - } else { - assert(i == i->parent->right); - d_balance = height_change; - } - } - } - - DUMP(t); - - if (t->destroy) { - t->destroy(n->data); - } - free(n); - - --t->size; + ZixTreeNode* const n = ti; + ZixTreeNode** pp = NULL; // parent pointer + ZixTreeNode* to_balance = n->parent; // lowest node to balance + int8_t d_balance = 0; // delta(balance) for n->parent + + DEBUG_PRINTF("*** REMOVE %ld\n", (intptr_t)n->data); + + if ((n == t->root) && !n->left && !n->right) { + t->root = NULL; + if (t->destroy) { + t->destroy(n->data); + } + free(n); + --t->size; + assert(t->size == 0); + return ZIX_STATUS_SUCCESS; + } + + // Set pp to the parent pointer to n, if applicable + if (n->parent) { + assert(n->parent->left == n || n->parent->right == n); + if (n->parent->left == n) { // n is left child + pp = &n->parent->left; + d_balance = 1; + } else { // n is right child + assert(n->parent->right == n); + pp = &n->parent->right; + d_balance = -1; + } + } + + assert(!pp || *pp == n); + + int height_change = 0; + if (!n->left && !n->right) { + // n is a leaf, just remove it + if (pp) { + *pp = NULL; + to_balance = n->parent; + height_change = (!n->parent->left && !n->parent->right) ? -1 : 0; + } + } else if (!n->left) { + // Replace n with right (only) child + if (pp) { + *pp = n->right; + to_balance = n->parent; + } else { + t->root = n->right; + } + n->right->parent = n->parent; + height_change = -1; + } else if (!n->right) { + // Replace n with left (only) child + if (pp) { + *pp = n->left; + to_balance = n->parent; + } else { + t->root = n->left; + } + n->left->parent = n->parent; + height_change = -1; + } else { + // Replace n with in-order successor (leftmost child of right subtree) + ZixTreeNode* replace = n->right; + while (replace->left) { + assert(replace->left->parent == replace); + replace = replace->left; + } + + // Remove replace from parent (replace_p) + if (replace->parent->left == replace) { + height_change = replace->parent->right ? 0 : -1; + d_balance = 1; + to_balance = replace->parent; + replace->parent->left = replace->right; + } else { + assert(replace->parent == n); + height_change = replace->parent->left ? 0 : -1; + d_balance = -1; + to_balance = replace->parent; + replace->parent->right = replace->right; + } + + if (to_balance == n) { + to_balance = replace; + } + + if (replace->right) { + replace->right->parent = replace->parent; + } + + replace->balance = n->balance; + + // Swap node to delete with replace + if (pp) { + *pp = replace; + } else { + assert(t->root == n); + t->root = replace; + } + replace->parent = n->parent; + replace->left = n->left; + n->left->parent = replace; + replace->right = n->right; + if (n->right) { + n->right->parent = replace; + } + + assert(!replace->parent || replace->parent->left == replace || + replace->parent->right == replace); + } + + // Rebalance starting at to_balance upwards. + for (ZixTreeNode* i = to_balance; i; i = i->parent) { + i->balance += d_balance; + if (d_balance == 0 || i->balance == -1 || i->balance == 1) { + break; + } + + assert(i != n); + i = zix_tree_rebalance(t, i, &height_change); + if (i->balance == 0) { + height_change = -1; + } + + if (i->parent) { + if (i == i->parent->left) { + d_balance = height_change * -1; + } else { + assert(i == i->parent->right); + d_balance = height_change; + } + } + } + + DUMP(t); + + if (t->destroy) { + t->destroy(n->data); + } + free(n); + + --t->size; #ifdef ZIX_TREE_VERIFY - if (!verify(t, t->root)) { - return ZIX_STATUS_ERROR; - } + if (!verify(t, t->root)) { + return ZIX_STATUS_ERROR; + } #endif - return ZIX_STATUS_SUCCESS; + return ZIX_STATUS_SUCCESS; } ZIX_API ZixStatus zix_tree_find(const ZixTree* t, const void* e, ZixTreeIter** ti) { - ZixTreeNode* n = t->root; - while (n) { - const int cmp = t->cmp(e, n->data, t->cmp_data); - if (cmp == 0) { - break; - } - - if (cmp < 0) { - n = n->left; - } else { - n = n->right; - } - } - - *ti = n; - return (n) ? ZIX_STATUS_SUCCESS : ZIX_STATUS_NOT_FOUND; + ZixTreeNode* n = t->root; + while (n) { + const int cmp = t->cmp(e, n->data, t->cmp_data); + if (cmp == 0) { + break; + } + + if (cmp < 0) { + n = n->left; + } else { + n = n->right; + } + } + + *ti = n; + return (n) ? ZIX_STATUS_SUCCESS : ZIX_STATUS_NOT_FOUND; } ZIX_API void* zix_tree_get(const ZixTreeIter* ti) { - return ti ? ti->data : NULL; + return ti ? ti->data : NULL; } ZIX_API ZixTreeIter* -zix_tree_begin(ZixTree* t) + zix_tree_begin(ZixTree* t) { - if (!t->root) { - return NULL; - } - - ZixTreeNode* n = t->root; - while (n->left) { - n = n->left; - } - return n; + if (!t->root) { + return NULL; + } + + ZixTreeNode* n = t->root; + while (n->left) { + n = n->left; + } + return n; } ZIX_API ZixTreeIter* -zix_tree_end(ZixTree* t) + zix_tree_end(ZixTree* t) { - return NULL; + return NULL; } ZIX_API ZixTreeIter* -zix_tree_rbegin(ZixTree* t) + zix_tree_rbegin(ZixTree* t) { - if (!t->root) { - return NULL; - } - - ZixTreeNode* n = t->root; - while (n->right) { - n = n->right; - } - return n; + if (!t->root) { + return NULL; + } + + ZixTreeNode* n = t->root; + while (n->right) { + n = n->right; + } + return n; } ZIX_API ZixTreeIter* -zix_tree_rend(ZixTree* t) + zix_tree_rend(ZixTree* t) { - return NULL; + return NULL; } ZIX_API bool zix_tree_iter_is_end(const ZixTreeIter* i) { - return !i; + return !i; } ZIX_API bool zix_tree_iter_is_rend(const ZixTreeIter* i) { - return !i; + return !i; } ZIX_API ZixTreeIter* -zix_tree_iter_next(ZixTreeIter* i) + zix_tree_iter_next(ZixTreeIter* i) { - if (!i) { - return NULL; - } - - if (i->right) { - i = i->right; - while (i->left) { - i = i->left; - } - } else { - while (i->parent && i->parent->right == i) { // i is a right child - i = i->parent; - } - - i = i->parent; - } - - return i; + if (!i) { + return NULL; + } + + if (i->right) { + i = i->right; + while (i->left) { + i = i->left; + } + } else { + while (i->parent && i->parent->right == i) { // i is a right child + i = i->parent; + } + + i = i->parent; + } + + return i; } ZIX_API ZixTreeIter* -zix_tree_iter_prev(ZixTreeIter* i) + zix_tree_iter_prev(ZixTreeIter* i) { - if (!i) { - return NULL; - } - - if (i->left) { - i = i->left; - while (i->right) { - i = i->right; - } - } else { - while (i->parent && i->parent->left == i) { // i is a left child - i = i->parent; - } - - i = i->parent; - } - - return i; + if (!i) { + return NULL; + } + + if (i->left) { + i = i->left; + while (i->right) { + i = i->right; + } + } else { + while (i->parent && i->parent->left == i) { // i is a left child + i = i->parent; + } + + i = i->parent; + } + + return i; } diff --git a/src/zix/tree.h b/src/zix/tree.h index 983c0ea..170e2ca 100644 --- a/src/zix/tree.h +++ b/src/zix/tree.h @@ -47,10 +47,10 @@ typedef struct ZixTreeNodeImpl ZixTreeIter; Create a new (empty) tree. */ ZIX_API ZixTree* -zix_tree_new(bool allow_duplicates, - ZixComparator cmp, - void* cmp_data, - ZixDestroyFunc destroy); + zix_tree_new(bool allow_duplicates, + ZixComparator cmp, + void* cmp_data, + ZixDestroyFunc destroy); /** Free `t`. @@ -93,13 +93,13 @@ zix_tree_get(const ZixTreeIter* ti); Return an iterator to the first (smallest) element in `t`. */ ZIX_API ZixTreeIter* -zix_tree_begin(ZixTree* t); + zix_tree_begin(ZixTree* t); /** Return an iterator the the element one past the last element in `t`. */ ZIX_API ZixTreeIter* -zix_tree_end(ZixTree* t); + zix_tree_end(ZixTree* t); /** Return true iff `i` is an iterator to the end of its tree. @@ -111,13 +111,13 @@ zix_tree_iter_is_end(const ZixTreeIter* i); Return an iterator to the last (largest) element in `t`. */ ZIX_API ZixTreeIter* -zix_tree_rbegin(ZixTree* t); + zix_tree_rbegin(ZixTree* t); /** Return an iterator the the element one before the first element in `t`. */ ZIX_API ZixTreeIter* -zix_tree_rend(ZixTree* t); + zix_tree_rend(ZixTree* t); /** Return true iff `i` is an iterator to the reverse end of its tree. @@ -129,13 +129,13 @@ zix_tree_iter_is_rend(const ZixTreeIter* i); Return an iterator that points to the element one past `i`. */ ZIX_API ZixTreeIter* -zix_tree_iter_next(ZixTreeIter* i); + zix_tree_iter_next(ZixTreeIter* i); /** Return an iterator that points to the element one before `i`. */ ZIX_API ZixTreeIter* -zix_tree_iter_prev(ZixTreeIter* i); + zix_tree_iter_prev(ZixTreeIter* i); /** @} @@ -143,7 +143,7 @@ zix_tree_iter_prev(ZixTreeIter* i); */ #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif -#endif /* ZIX_TREE_H */ +#endif /* ZIX_TREE_H */ diff --git a/test/bad_syntax.lv2/bad_syntax.c b/test/bad_syntax.lv2/bad_syntax.c index fc4a210..72166c0 100644 --- a/test/bad_syntax.lv2/bad_syntax.c +++ b/test/bad_syntax.lv2/bad_syntax.c @@ -22,36 +22,33 @@ #define PLUGIN_URI "http://example.org/bad-syntax" -enum { - TEST_INPUT = 0, - TEST_OUTPUT = 1 -}; +enum { TEST_INPUT = 0, TEST_OUTPUT = 1 }; typedef struct { - float* input; - float* output; + float* input; + float* output; } Test; static void cleanup(LV2_Handle instance) { - free((Test*)instance); + free((Test*)instance); } static void connect_port(LV2_Handle instance, uint32_t port, void* data) { - Test* test = (Test*)instance; - switch (port) { - case TEST_INPUT: - test->input = (float*)data; - break; - case TEST_OUTPUT: - test->output = (float*)data; - break; - default: - break; - } + Test* test = (Test*)instance; + switch (port) { + case TEST_INPUT: + test->input = (float*)data; + break; + case TEST_OUTPUT: + test->output = (float*)data; + break; + default: + break; + } } static LV2_Handle @@ -60,35 +57,36 @@ instantiate(const LV2_Descriptor* descriptor, const char* path, const LV2_Feature* const* features) { - Test* test = (Test*)calloc(1, sizeof(Test)); - if (!test) { - return NULL; - } + Test* test = (Test*)calloc(1, sizeof(Test)); + if (!test) { + return NULL; + } - return (LV2_Handle)test; + return (LV2_Handle)test; } static void run(LV2_Handle instance, uint32_t sample_count) { - Test* test = (Test*)instance; + Test* test = (Test*)instance; - *test->output = *test->input; + *test->output = *test->input; } static const LV2_Descriptor descriptor = { - PLUGIN_URI, - instantiate, - connect_port, - NULL, // activate, - run, - NULL, // deactivate, - cleanup, - NULL // extension_data + PLUGIN_URI, + instantiate, + connect_port, + NULL, // activate, + run, + NULL, // deactivate, + cleanup, + NULL // extension_data }; LV2_SYMBOL_EXPORT -const LV2_Descriptor* lv2_descriptor(uint32_t index) +const LV2_Descriptor* +lv2_descriptor(uint32_t index) { - return (index == 0) ? &descriptor : NULL; + return (index == 0) ? &descriptor : NULL; } diff --git a/test/bad_syntax.lv2/test_bad_syntax.c b/test/bad_syntax.lv2/test_bad_syntax.c index 10aa4da..5f10828 100644 --- a/test/bad_syntax.lv2/test_bad_syntax.c +++ b/test/bad_syntax.lv2/test_bad_syntax.c @@ -16,33 +16,32 @@ int main(int argc, char** argv) { - if (argc != 2) { - fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); - return 1; - } - - const char* bundle_path = argv[1]; - LilvWorld* world = lilv_world_new(); - - // Load test plugin bundle - uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); - SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); - LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); - lilv_world_load_bundle(world, bundle_uri); - free(abs_bundle); - serd_node_free(&bundle); - lilv_node_free(bundle_uri); - - LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); - - assert(!lilv_plugin_get_name(plugin)); - assert(!lilv_plugin_instantiate(plugin, 48000, NULL)); - - lilv_node_free(plugin_uri); - lilv_world_free(world); - - return 0; + if (argc != 2) { + fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); + return 1; + } + + const char* bundle_path = argv[1]; + LilvWorld* world = lilv_world_new(); + + // Load test plugin bundle + uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); + SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); + LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); + lilv_world_load_bundle(world, bundle_uri); + free(abs_bundle); + serd_node_free(&bundle); + lilv_node_free(bundle_uri); + + LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); + + assert(!lilv_plugin_get_name(plugin)); + assert(!lilv_plugin_instantiate(plugin, 48000, NULL)); + + lilv_node_free(plugin_uri); + lilv_world_free(world); + + return 0; } - diff --git a/test/failed_instantiation.lv2/failed_instantiation.c b/test/failed_instantiation.lv2/failed_instantiation.c index 30ae0ca..d805848 100644 --- a/test/failed_instantiation.lv2/failed_instantiation.c +++ b/test/failed_instantiation.lv2/failed_instantiation.c @@ -22,14 +22,11 @@ #define PLUGIN_URI "http://example.org/failed-instantiation" -enum { - TEST_INPUT = 0, - TEST_OUTPUT = 1 -}; +enum { TEST_INPUT = 0, TEST_OUTPUT = 1 }; typedef struct { - float* input; - float* output; + float* input; + float* output; } Test; static void @@ -46,7 +43,7 @@ instantiate(const LV2_Descriptor* descriptor, const char* path, const LV2_Feature* const* features) { - return NULL; + return NULL; } static void @@ -54,18 +51,19 @@ run(LV2_Handle instance, uint32_t sample_count) {} static const LV2_Descriptor descriptor = { - PLUGIN_URI, - instantiate, - connect_port, - NULL, // activate, - run, - NULL, // deactivate, - cleanup, - NULL // extension_data + PLUGIN_URI, + instantiate, + connect_port, + NULL, // activate, + run, + NULL, // deactivate, + cleanup, + NULL // extension_data }; LV2_SYMBOL_EXPORT -const LV2_Descriptor* lv2_descriptor(uint32_t index) +const LV2_Descriptor* +lv2_descriptor(uint32_t index) { - return (index == 0) ? &descriptor : NULL; + return (index == 0) ? &descriptor : NULL; } diff --git a/test/failed_instantiation.lv2/test_failed_instantiation.c b/test/failed_instantiation.lv2/test_failed_instantiation.c index 7fb2714..8dbefc3 100644 --- a/test/failed_instantiation.lv2/test_failed_instantiation.c +++ b/test/failed_instantiation.lv2/test_failed_instantiation.c @@ -16,33 +16,32 @@ int main(int argc, char** argv) { - if (argc != 2) { - fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); - return 1; - } - - const char* bundle_path = argv[1]; - LilvWorld* world = lilv_world_new(); - - // Load test plugin bundle - uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); - SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); - LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); - lilv_world_load_bundle(world, bundle_uri); - free(abs_bundle); - serd_node_free(&bundle); - lilv_node_free(bundle_uri); - - LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); - assert(plugin); - - assert(!lilv_plugin_instantiate(plugin, 48000, NULL)); - - lilv_node_free(plugin_uri); - lilv_world_free(world); - - return 0; + if (argc != 2) { + fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); + return 1; + } + + const char* bundle_path = argv[1]; + LilvWorld* world = lilv_world_new(); + + // Load test plugin bundle + uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); + SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); + LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); + lilv_world_load_bundle(world, bundle_uri); + free(abs_bundle); + serd_node_free(&bundle); + lilv_node_free(bundle_uri); + + LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); + assert(plugin); + + assert(!lilv_plugin_instantiate(plugin, 48000, NULL)); + + lilv_node_free(plugin_uri); + lilv_world_free(world); + + return 0; } - diff --git a/test/failed_lib_descriptor.lv2/failed_lib_descriptor.c b/test/failed_lib_descriptor.lv2/failed_lib_descriptor.c index e24c8d9..180c8ae 100644 --- a/test/failed_lib_descriptor.lv2/failed_lib_descriptor.c +++ b/test/failed_lib_descriptor.lv2/failed_lib_descriptor.c @@ -21,8 +21,7 @@ LV2_SYMBOL_EXPORT const LV2_Lib_Descriptor* -lv2_lib_descriptor(const char* bundle_path, - const LV2_Feature*const* features) +lv2_lib_descriptor(const char* bundle_path, const LV2_Feature* const* features) { - return NULL; + return NULL; } diff --git a/test/failed_lib_descriptor.lv2/test_failed_lib_descriptor.c b/test/failed_lib_descriptor.lv2/test_failed_lib_descriptor.c index 63e81f3..71a3b96 100644 --- a/test/failed_lib_descriptor.lv2/test_failed_lib_descriptor.c +++ b/test/failed_lib_descriptor.lv2/test_failed_lib_descriptor.c @@ -16,34 +16,33 @@ int main(int argc, char** argv) { - if (argc != 2) { - fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); - return 1; - } - - const char* bundle_path = argv[1]; - LilvWorld* world = lilv_world_new(); - - // Load test plugin bundle - uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); - SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); - LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); - lilv_world_load_bundle(world, bundle_uri); - free(abs_bundle); - serd_node_free(&bundle); - lilv_node_free(bundle_uri); - - LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); - assert(plugin); - - LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL); - assert(!instance); - - lilv_node_free(plugin_uri); - lilv_world_free(world); - - return 0; + if (argc != 2) { + fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); + return 1; + } + + const char* bundle_path = argv[1]; + LilvWorld* world = lilv_world_new(); + + // Load test plugin bundle + uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); + SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); + LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); + lilv_world_load_bundle(world, bundle_uri); + free(abs_bundle); + serd_node_free(&bundle); + lilv_node_free(bundle_uri); + + LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); + assert(plugin); + + LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL); + assert(!instance); + + lilv_node_free(plugin_uri); + lilv_world_free(world); + + return 0; } - diff --git a/test/lib_descriptor.lv2/lib_descriptor.c b/test/lib_descriptor.lv2/lib_descriptor.c index 29176dc..0a14a23 100644 --- a/test/lib_descriptor.lv2/lib_descriptor.c +++ b/test/lib_descriptor.lv2/lib_descriptor.c @@ -22,36 +22,33 @@ #define PLUGIN_URI "http://example.org/lib-descriptor" -enum { - TEST_INPUT = 0, - TEST_OUTPUT = 1 -}; +enum { TEST_INPUT = 0, TEST_OUTPUT = 1 }; typedef struct { - float* input; - float* output; + float* input; + float* output; } Test; static void cleanup(LV2_Handle instance) { - free((Test*)instance); + free((Test*)instance); } static void connect_port(LV2_Handle instance, uint32_t port, void* data) { - Test* test = (Test*)instance; - switch (port) { - case TEST_INPUT: - test->input = (float*)data; - break; - case TEST_OUTPUT: - test->output = (float*)data; - break; - default: - break; - } + Test* test = (Test*)instance; + switch (port) { + case TEST_INPUT: + test->input = (float*)data; + break; + case TEST_OUTPUT: + test->output = (float*)data; + break; + default: + break; + } } static LV2_Handle @@ -60,54 +57,52 @@ instantiate(const LV2_Descriptor* descriptor, const char* path, const LV2_Feature* const* features) { - Test* test = (Test*)calloc(1, sizeof(Test)); - if (!test) { - return NULL; - } + Test* test = (Test*)calloc(1, sizeof(Test)); + if (!test) { + return NULL; + } - return (LV2_Handle)test; + return (LV2_Handle)test; } static void run(LV2_Handle instance, uint32_t sample_count) { - Test* test = (Test*)instance; + Test* test = (Test*)instance; - *test->output = *test->input; + *test->output = *test->input; } static const LV2_Descriptor descriptor = { - PLUGIN_URI, - instantiate, - connect_port, - NULL, // activate, - run, - NULL, // deactivate, - cleanup, - NULL // extension_data + PLUGIN_URI, + instantiate, + connect_port, + NULL, // activate, + run, + NULL, // deactivate, + cleanup, + NULL // extension_data }; static const LV2_Descriptor* get_plugin(LV2_Lib_Handle handle, uint32_t index) { - switch (index) { - case 0: - return &descriptor; - default: - return NULL; - } + switch (index) { + case 0: + return &descriptor; + default: + return NULL; + } } -static const LV2_Lib_Descriptor lib = { - NULL, - sizeof(LV2_Lib_Descriptor), - NULL, - get_plugin }; +static const LV2_Lib_Descriptor lib = {NULL, + sizeof(LV2_Lib_Descriptor), + NULL, + get_plugin}; LV2_SYMBOL_EXPORT const LV2_Lib_Descriptor* -lv2_lib_descriptor(const char* bundle_path, - const LV2_Feature*const* features) +lv2_lib_descriptor(const char* bundle_path, const LV2_Feature* const* features) { - return &lib; + return &lib; } diff --git a/test/lib_descriptor.lv2/test_lib_descriptor.c b/test/lib_descriptor.lv2/test_lib_descriptor.c index e0ba585..bf79be8 100644 --- a/test/lib_descriptor.lv2/test_lib_descriptor.c +++ b/test/lib_descriptor.lv2/test_lib_descriptor.c @@ -16,47 +16,46 @@ int main(int argc, char** argv) { - if (argc != 2) { - fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); - return 1; - } - - const char* bundle_path = argv[1]; - LilvWorld* world = lilv_world_new(); - - // Load test plugin bundle - uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); - SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); - LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); - lilv_world_load_bundle(world, bundle_uri); - free(abs_bundle); - serd_node_free(&bundle); - lilv_node_free(bundle_uri); - - LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); - assert(plugin); - - LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL); - assert(instance); - lilv_instance_free(instance); - - LilvNode* eg_blob = lilv_new_uri(world, "http://example.org/blob"); - LilvNode* blob = lilv_world_get(world, plugin_uri, eg_blob, NULL); - assert(lilv_node_is_literal(blob)); - lilv_node_free(blob); - lilv_node_free(eg_blob); - - LilvNode* eg_junk = lilv_new_uri(world, "http://example.org/junk"); - LilvNode* junk = lilv_world_get(world, plugin_uri, eg_junk, NULL); - assert(lilv_node_is_literal(junk)); - lilv_node_free(junk); - lilv_node_free(eg_junk); - - lilv_node_free(plugin_uri); - lilv_world_free(world); - - return 0; + if (argc != 2) { + fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); + return 1; + } + + const char* bundle_path = argv[1]; + LilvWorld* world = lilv_world_new(); + + // Load test plugin bundle + uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); + SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); + LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); + lilv_world_load_bundle(world, bundle_uri); + free(abs_bundle); + serd_node_free(&bundle); + lilv_node_free(bundle_uri); + + LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); + assert(plugin); + + LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL); + assert(instance); + lilv_instance_free(instance); + + LilvNode* eg_blob = lilv_new_uri(world, "http://example.org/blob"); + LilvNode* blob = lilv_world_get(world, plugin_uri, eg_blob, NULL); + assert(lilv_node_is_literal(blob)); + lilv_node_free(blob); + lilv_node_free(eg_blob); + + LilvNode* eg_junk = lilv_new_uri(world, "http://example.org/junk"); + LilvNode* junk = lilv_world_get(world, plugin_uri, eg_junk, NULL); + assert(lilv_node_is_literal(junk)); + lilv_node_free(junk); + lilv_node_free(eg_junk); + + lilv_node_free(plugin_uri); + lilv_world_free(world); + + return 0; } - diff --git a/test/lilv_cxx_test.cpp b/test/lilv_cxx_test.cpp index 4ee21ae..392ead2 100644 --- a/test/lilv_cxx_test.cpp +++ b/test/lilv_cxx_test.cpp @@ -19,7 +19,7 @@ int main() { - Lilv::World world; + Lilv::World world; - return 0; + return 0; } diff --git a/test/lilv_test_uri_map.h b/test/lilv_test_uri_map.h index e56445a..b18d8f4 100644 --- a/test/lilv_test_uri_map.h +++ b/test/lilv_test_uri_map.h @@ -28,59 +28,58 @@ #include <stdlib.h> #include <string.h> -typedef struct -{ - char** uris; - size_t n_uris; +typedef struct { + char** uris; + size_t n_uris; } LilvTestUriMap; static inline void lilv_test_uri_map_init(LilvTestUriMap* const map) { - map->uris = NULL; - map->n_uris = 0; + map->uris = NULL; + map->n_uris = 0; } static inline void lilv_test_uri_map_clear(LilvTestUriMap* const map) { - for (size_t i = 0; i < map->n_uris; ++i) { - free(map->uris[i]); - } + for (size_t i = 0; i < map->n_uris; ++i) { + free(map->uris[i]); + } - free(map->uris); - map->uris = NULL; - map->n_uris = 0; + free(map->uris); + map->uris = NULL; + map->n_uris = 0; } static inline LV2_URID map_uri(LV2_URID_Map_Handle handle, const char* uri) { - LilvTestUriMap* map = (LilvTestUriMap*)handle; + LilvTestUriMap* map = (LilvTestUriMap*)handle; - for (size_t i = 0; i < map->n_uris; ++i) { - if (!strcmp(map->uris[i], uri)) { - return i + 1; - } - } + for (size_t i = 0; i < map->n_uris; ++i) { + if (!strcmp(map->uris[i], uri)) { + return i + 1; + } + } - assert(serd_uri_string_has_scheme((const uint8_t*)uri)); + assert(serd_uri_string_has_scheme((const uint8_t*)uri)); - map->uris = (char**)realloc(map->uris, ++map->n_uris * sizeof(char*)); - map->uris[map->n_uris - 1] = lilv_strdup(uri); - return map->n_uris; + map->uris = (char**)realloc(map->uris, ++map->n_uris * sizeof(char*)); + map->uris[map->n_uris - 1] = lilv_strdup(uri); + return map->n_uris; } static inline const char* unmap_uri(LV2_URID_Map_Handle handle, LV2_URID urid) { - LilvTestUriMap* map = (LilvTestUriMap*)handle; + LilvTestUriMap* map = (LilvTestUriMap*)handle; - if (urid > 0 && urid <= map->n_uris) { - return map->uris[urid - 1]; - } + if (urid > 0 && urid <= map->n_uris) { + return map->uris[urid - 1]; + } - return NULL; + return NULL; } #endif // LILV_TEST_URI_MAP_H diff --git a/test/lilv_test_utils.c b/test/lilv_test_utils.c index 38754b0..16eeb8e 100644 --- a/test/lilv_test_utils.c +++ b/test/lilv_test_utils.c @@ -34,151 +34,149 @@ LilvTestEnv* lilv_test_env_new(void) { - LilvWorld* world = lilv_world_new(); - if (!world) { - return NULL; - } - - LilvTestEnv* env = (LilvTestEnv*)calloc(1, sizeof(LilvTestEnv)); - - env->world = world; - env->plugin1_uri = lilv_new_uri(world, "http://example.org/plug"); - 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* lv2_path = lilv_strjoin(test_path, "/test_lv2_path", NULL); - LilvNode* path = lilv_new_string(world, lv2_path); - lilv_world_set_option(world, LILV_OPTION_LV2_PATH, path); - free(lv2_path); - free(test_path); - lilv_node_free(path); - - return env; + LilvWorld* world = lilv_world_new(); + if (!world) { + return NULL; + } + + LilvTestEnv* env = (LilvTestEnv*)calloc(1, sizeof(LilvTestEnv)); + + env->world = world; + env->plugin1_uri = lilv_new_uri(world, "http://example.org/plug"); + 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* lv2_path = lilv_strjoin(test_path, "/test_lv2_path", NULL); + LilvNode* path = lilv_new_string(world, lv2_path); + lilv_world_set_option(world, LILV_OPTION_LV2_PATH, path); + free(lv2_path); + free(test_path); + lilv_node_free(path); + + return env; } void lilv_test_env_free(LilvTestEnv* env) { - free(env->test_content_path); - free(env->test_manifest_path); - free(env->test_bundle_uri); - free(env->test_bundle_path); - lilv_node_free(env->plugin2_uri); - lilv_node_free(env->plugin1_uri); - lilv_world_free(env->world); - free(env); + free(env->test_content_path); + free(env->test_manifest_path); + free(env->test_bundle_uri); + free(env->test_bundle_path); + lilv_node_free(env->plugin2_uri); + lilv_node_free(env->plugin1_uri); + lilv_world_free(env->world); + free(env); } int create_bundle(LilvTestEnv* env, const char* manifest, const char* plugin) { - { - static const char* const bundle_path = "/test_lv2_path/lilv-test.lv2"; - - char* const test_path = lilv_path_canonical(LILV_TEST_DIR); - env->test_bundle_path = lilv_strjoin(test_path, bundle_path, NULL); - lilv_free(test_path); - } - - if (lilv_create_directories(env->test_bundle_path)) { - fprintf(stderr, - "Failed to create directory '%s' (%s)\n", - env->test_bundle_path, - strerror(errno)); - return 1; - } - - SerdNode s = serd_node_new_file_uri((const uint8_t*)env->test_bundle_path, - NULL, - NULL, - true); - - env->test_bundle_uri = lilv_strjoin((const char*)s.buf, "/", NULL); - env->test_manifest_path = - lilv_strjoin(env->test_bundle_path, "/manifest.ttl", NULL); - env->test_content_path = - lilv_strjoin(env->test_bundle_path, "/plugin.ttl", NULL); - - serd_node_free(&s); - - FILE* const manifest_file = fopen(env->test_manifest_path, "w"); - if (!manifest_file) { - return 2; - } - - FILE* const plugin_file = fopen(env->test_content_path, "w"); - if (!plugin_file) { - fclose(manifest_file); - return 3; - } - - const size_t manifest_head_len = strlen(MANIFEST_PREFIXES); - const size_t manifest_len = strlen(manifest); - const size_t plugin_head_len = strlen(PLUGIN_PREFIXES); - const size_t plugin_len = strlen(plugin); - const size_t n_total = - manifest_len + plugin_len + manifest_head_len + plugin_head_len; - - size_t n_written = 0; - n_written += fwrite(MANIFEST_PREFIXES, 1, manifest_head_len, manifest_file); - n_written += fwrite(manifest, 1, manifest_len, manifest_file); - n_written += fwrite(PLUGIN_PREFIXES, 1, plugin_head_len, plugin_file); - n_written += fwrite(plugin, 1, plugin_len, plugin_file); - - fclose(manifest_file); - fclose(plugin_file); - return n_written == n_total ? 0 : 4; + { + static const char* const bundle_path = "/test_lv2_path/lilv-test.lv2"; + + char* const test_path = lilv_path_canonical(LILV_TEST_DIR); + env->test_bundle_path = lilv_strjoin(test_path, bundle_path, NULL); + lilv_free(test_path); + } + + if (lilv_create_directories(env->test_bundle_path)) { + fprintf(stderr, + "Failed to create directory '%s' (%s)\n", + env->test_bundle_path, + strerror(errno)); + return 1; + } + + SerdNode s = serd_node_new_file_uri( + (const uint8_t*)env->test_bundle_path, NULL, NULL, true); + + env->test_bundle_uri = lilv_strjoin((const char*)s.buf, "/", NULL); + env->test_manifest_path = + lilv_strjoin(env->test_bundle_path, "/manifest.ttl", NULL); + env->test_content_path = + lilv_strjoin(env->test_bundle_path, "/plugin.ttl", NULL); + + serd_node_free(&s); + + FILE* const manifest_file = fopen(env->test_manifest_path, "w"); + if (!manifest_file) { + return 2; + } + + FILE* const plugin_file = fopen(env->test_content_path, "w"); + if (!plugin_file) { + fclose(manifest_file); + return 3; + } + + const size_t manifest_head_len = strlen(MANIFEST_PREFIXES); + const size_t manifest_len = strlen(manifest); + const size_t plugin_head_len = strlen(PLUGIN_PREFIXES); + const size_t plugin_len = strlen(plugin); + const size_t n_total = + manifest_len + plugin_len + manifest_head_len + plugin_head_len; + + size_t n_written = 0; + n_written += fwrite(MANIFEST_PREFIXES, 1, manifest_head_len, manifest_file); + n_written += fwrite(manifest, 1, manifest_len, manifest_file); + n_written += fwrite(PLUGIN_PREFIXES, 1, plugin_head_len, plugin_file); + n_written += fwrite(plugin, 1, plugin_len, plugin_file); + + fclose(manifest_file); + fclose(plugin_file); + return n_written == n_total ? 0 : 4; } int start_bundle(LilvTestEnv* env, const char* manifest, const char* plugin) { - if (create_bundle(env, manifest, plugin)) { - return 1; - } + if (create_bundle(env, manifest, plugin)) { + return 1; + } - lilv_world_load_all(env->world); - return 0; + lilv_world_load_all(env->world); + return 0; } void delete_bundle(LilvTestEnv* env) { - if (env->test_content_path) { - lilv_remove(env->test_content_path); - } - - if (env->test_manifest_path) { - lilv_remove(env->test_manifest_path); - } - - if (env->test_bundle_path) { - remove(env->test_bundle_path); - } - - free(env->test_content_path); - free(env->test_manifest_path); - free(env->test_bundle_uri); - free(env->test_bundle_path); - - env->test_content_path = NULL; - env->test_manifest_path = NULL; - env->test_bundle_uri = NULL; - env->test_bundle_path = NULL; + if (env->test_content_path) { + lilv_remove(env->test_content_path); + } + + if (env->test_manifest_path) { + lilv_remove(env->test_manifest_path); + } + + if (env->test_bundle_path) { + remove(env->test_bundle_path); + } + + free(env->test_content_path); + free(env->test_manifest_path); + free(env->test_bundle_uri); + free(env->test_bundle_path); + + env->test_content_path = NULL; + env->test_manifest_path = NULL; + env->test_bundle_uri = NULL; + env->test_bundle_path = NULL; } void set_env(const char* name, const char* value) { #ifdef _WIN32 - // setenv on Windows does not modify the current process' environment - const size_t len = strlen(name) + 1 + strlen(value) + 1; - char* str = (char*)calloc(1, len); - snprintf(str, len, "%s=%s", name, value); - putenv(str); - free(str); + // setenv on Windows does not modify the current process' environment + const size_t len = strlen(name) + 1 + strlen(value) + 1; + char* str = (char*)calloc(1, len); + snprintf(str, len, "%s=%s", name, value); + putenv(str); + free(str); #else - setenv(name, value, 1); + setenv(name, value, 1); #endif } diff --git a/test/lilv_test_utils.h b/test/lilv_test_utils.h index 13fd939..e20c7df 100644 --- a/test/lilv_test_utils.h +++ b/test/lilv_test_utils.h @@ -20,13 +20,13 @@ #include "lilv/lilv.h" #define MANIFEST_PREFIXES \ - "\ + "\ @prefix : <http://example.org/> .\n\ @prefix lv2: <http://lv2plug.in/ns/lv2core#> .\n\ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n" #define PLUGIN_PREFIXES \ - "\ + "\ @prefix : <http://example.org/> .\n\ @prefix atom: <http://lv2plug.in/ns/ext/atom#> . \n\ @prefix doap: <http://usefulinc.com/ns/doap#> .\n\ @@ -37,30 +37,29 @@ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n" #define SIMPLE_MANIFEST_TTL \ - "\ + "\ :plug a lv2:Plugin ;\n\ lv2:binary <foo" SHLIB_EXT "> ;\n\ rdfs:seeAlso <plugin.ttl> .\n" #if defined(__APPLE__) -# define SHLIB_EXT ".dylib" +# define SHLIB_EXT ".dylib" #elif defined(_WIN32) -# define SHLIB_EXT ".dll" +# define SHLIB_EXT ".dll" #else -# define SHLIB_EXT ".so" +# define SHLIB_EXT ".so" #endif -typedef struct -{ - LilvWorld* world; - LilvNode* plugin1_uri; - LilvNode* plugin2_uri; - char* test_bundle_path; - char* test_bundle_uri; - char* test_manifest_path; - char* test_content_path; - int test_count; - int error_count; +typedef struct { + LilvWorld* world; + LilvNode* plugin1_uri; + LilvNode* plugin2_uri; + char* test_bundle_path; + char* test_bundle_uri; + char* test_manifest_path; + char* test_content_path; + int test_count; + int error_count; } LilvTestEnv; // Create a new test environment with a world, common values, and test LV2_PATH diff --git a/test/missing_descriptor.lv2/test_missing_descriptor.c b/test/missing_descriptor.lv2/test_missing_descriptor.c index f7b5ceb..330e534 100644 --- a/test/missing_descriptor.lv2/test_missing_descriptor.c +++ b/test/missing_descriptor.lv2/test_missing_descriptor.c @@ -16,34 +16,33 @@ int main(int argc, char** argv) { - if (argc != 2) { - fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); - return 1; - } - - const char* bundle_path = argv[1]; - LilvWorld* world = lilv_world_new(); - - // Load test plugin bundle - uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); - SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); - LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); - lilv_world_load_bundle(world, bundle_uri); - free(abs_bundle); - serd_node_free(&bundle); - lilv_node_free(bundle_uri); - - LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); - assert(plugin); - - LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL); - assert(!instance); - - lilv_node_free(plugin_uri); - lilv_world_free(world); - - return 0; + if (argc != 2) { + fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); + return 1; + } + + const char* bundle_path = argv[1]; + LilvWorld* world = lilv_world_new(); + + // Load test plugin bundle + uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); + SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); + LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); + lilv_world_load_bundle(world, bundle_uri); + free(abs_bundle); + serd_node_free(&bundle); + lilv_node_free(bundle_uri); + + LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); + assert(plugin); + + LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL); + assert(!instance); + + lilv_node_free(plugin_uri); + lilv_world_free(world); + + return 0; } - diff --git a/test/missing_name.lv2/missing_name.c b/test/missing_name.lv2/missing_name.c index 8945c1f..2f53cf4 100644 --- a/test/missing_name.lv2/missing_name.c +++ b/test/missing_name.lv2/missing_name.c @@ -22,36 +22,33 @@ #define PLUGIN_URI "http://example.org/missing-name" -enum { - TEST_INPUT = 0, - TEST_OUTPUT = 1 -}; +enum { TEST_INPUT = 0, TEST_OUTPUT = 1 }; typedef struct { - float* input; - float* output; + float* input; + float* output; } Test; static void cleanup(LV2_Handle instance) { - free((Test*)instance); + free((Test*)instance); } static void connect_port(LV2_Handle instance, uint32_t port, void* data) { - Test* test = (Test*)instance; - switch (port) { - case TEST_INPUT: - test->input = (float*)data; - break; - case TEST_OUTPUT: - test->output = (float*)data; - break; - default: - break; - } + Test* test = (Test*)instance; + switch (port) { + case TEST_INPUT: + test->input = (float*)data; + break; + case TEST_OUTPUT: + test->output = (float*)data; + break; + default: + break; + } } static LV2_Handle @@ -60,35 +57,36 @@ instantiate(const LV2_Descriptor* descriptor, const char* path, const LV2_Feature* const* features) { - Test* test = (Test*)calloc(1, sizeof(Test)); - if (!test) { - return NULL; - } + Test* test = (Test*)calloc(1, sizeof(Test)); + if (!test) { + return NULL; + } - return (LV2_Handle)test; + return (LV2_Handle)test; } static void run(LV2_Handle instance, uint32_t sample_count) { - Test* test = (Test*)instance; + Test* test = (Test*)instance; - *test->output = *test->input; + *test->output = *test->input; } static const LV2_Descriptor descriptor = { - PLUGIN_URI, - instantiate, - connect_port, - NULL, // activate, - run, - NULL, // deactivate, - cleanup, - NULL // extension_data + PLUGIN_URI, + instantiate, + connect_port, + NULL, // activate, + run, + NULL, // deactivate, + cleanup, + NULL // extension_data }; LV2_SYMBOL_EXPORT -const LV2_Descriptor* lv2_descriptor(uint32_t index) +const LV2_Descriptor* +lv2_descriptor(uint32_t index) { - return (index == 0) ? &descriptor : NULL; + return (index == 0) ? &descriptor : NULL; } diff --git a/test/missing_name.lv2/test_missing_name.c b/test/missing_name.lv2/test_missing_name.c index bf8cf95..5cb069a 100644 --- a/test/missing_name.lv2/test_missing_name.c +++ b/test/missing_name.lv2/test_missing_name.c @@ -16,35 +16,34 @@ int main(int argc, char** argv) { - if (argc != 2) { - fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); - return 1; - } - - const char* bundle_path = argv[1]; - LilvWorld* world = lilv_world_new(); - - // Load test plugin bundle - uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); - SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); - LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); - lilv_world_load_bundle(world, bundle_uri); - free(abs_bundle); - serd_node_free(&bundle); - lilv_node_free(bundle_uri); - - LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); - assert(plugin); - - LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL); - assert(instance); - lilv_instance_free(instance); - - lilv_node_free(plugin_uri); - lilv_world_free(world); - - return 0; + if (argc != 2) { + fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); + return 1; + } + + const char* bundle_path = argv[1]; + LilvWorld* world = lilv_world_new(); + + // Load test plugin bundle + uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); + SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); + LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); + lilv_world_load_bundle(world, bundle_uri); + free(abs_bundle); + serd_node_free(&bundle); + lilv_node_free(bundle_uri); + + LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); + assert(plugin); + + LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL); + assert(instance); + lilv_instance_free(instance); + + lilv_node_free(plugin_uri); + lilv_world_free(world); + + return 0; } - diff --git a/test/missing_plugin.lv2/missing_plugin.c b/test/missing_plugin.lv2/missing_plugin.c index bf45cbe..8ca146c 100644 --- a/test/missing_plugin.lv2/missing_plugin.c +++ b/test/missing_plugin.lv2/missing_plugin.c @@ -21,22 +21,22 @@ #include <stdlib.h> static const LV2_Descriptor descriptor = { - "http://example.org/not-the-plugin-you-are-looking-for", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; + "http://example.org/not-the-plugin-you-are-looking-for", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL}; LV2_SYMBOL_EXPORT -const LV2_Descriptor* lv2_descriptor(uint32_t index) +const LV2_Descriptor* +lv2_descriptor(uint32_t index) { - if (index == 0) { - return &descriptor; - } + if (index == 0) { + return &descriptor; + } - return NULL; + return NULL; } diff --git a/test/missing_plugin.lv2/test_missing_plugin.c b/test/missing_plugin.lv2/test_missing_plugin.c index c2a8259..861fcba 100644 --- a/test/missing_plugin.lv2/test_missing_plugin.c +++ b/test/missing_plugin.lv2/test_missing_plugin.c @@ -16,34 +16,33 @@ int main(int argc, char** argv) { - if (argc != 2) { - fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); - return 1; - } - - const char* bundle_path = argv[1]; - LilvWorld* world = lilv_world_new(); - - // Load test plugin bundle - uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); - SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); - LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); - lilv_world_load_bundle(world, bundle_uri); - free(abs_bundle); - serd_node_free(&bundle); - lilv_node_free(bundle_uri); - - LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); - assert(plugin); - - LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL); - assert(!instance); - - lilv_node_free(plugin_uri); - lilv_world_free(world); - - return 0; + if (argc != 2) { + fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); + return 1; + } + + const char* bundle_path = argv[1]; + LilvWorld* world = lilv_world_new(); + + // Load test plugin bundle + uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); + SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); + LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); + lilv_world_load_bundle(world, bundle_uri); + free(abs_bundle); + serd_node_free(&bundle); + lilv_node_free(bundle_uri); + + LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); + assert(plugin); + + LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000.0, NULL); + assert(!instance); + + lilv_node_free(plugin_uri); + lilv_world_free(world); + + return 0; } - diff --git a/test/missing_port.lv2/missing_port.c b/test/missing_port.lv2/missing_port.c index 558eeb0..e2fa77a 100644 --- a/test/missing_port.lv2/missing_port.c +++ b/test/missing_port.lv2/missing_port.c @@ -22,36 +22,33 @@ #define PLUGIN_URI "http://example.org/missing-port" -enum { - TEST_INPUT = 0, - TEST_OUTPUT = 1 -}; +enum { TEST_INPUT = 0, TEST_OUTPUT = 1 }; typedef struct { - float* input; - float* output; + float* input; + float* output; } Test; static void cleanup(LV2_Handle instance) { - free((Test*)instance); + free((Test*)instance); } static void connect_port(LV2_Handle instance, uint32_t port, void* data) { - Test* test = (Test*)instance; - switch (port) { - case TEST_INPUT: - test->input = (float*)data; - break; - case TEST_OUTPUT: - test->output = (float*)data; - break; - default: - break; - } + Test* test = (Test*)instance; + switch (port) { + case TEST_INPUT: + test->input = (float*)data; + break; + case TEST_OUTPUT: + test->output = (float*)data; + break; + default: + break; + } } static LV2_Handle @@ -60,35 +57,36 @@ instantiate(const LV2_Descriptor* descriptor, const char* path, const LV2_Feature* const* features) { - Test* test = (Test*)calloc(1, sizeof(Test)); - if (!test) { - return NULL; - } + Test* test = (Test*)calloc(1, sizeof(Test)); + if (!test) { + return NULL; + } - return (LV2_Handle)test; + return (LV2_Handle)test; } static void run(LV2_Handle instance, uint32_t sample_count) { - Test* test = (Test*)instance; + Test* test = (Test*)instance; - *test->output = *test->input; + *test->output = *test->input; } static const LV2_Descriptor descriptor = { - PLUGIN_URI, - instantiate, - connect_port, - NULL, // activate, - run, - NULL, // deactivate, - cleanup, - NULL // extension_data + PLUGIN_URI, + instantiate, + connect_port, + NULL, // activate, + run, + NULL, // deactivate, + cleanup, + NULL // extension_data }; LV2_SYMBOL_EXPORT -const LV2_Descriptor* lv2_descriptor(uint32_t index) +const LV2_Descriptor* +lv2_descriptor(uint32_t index) { - return (index == 0) ? &descriptor : NULL; + return (index == 0) ? &descriptor : NULL; } diff --git a/test/missing_port.lv2/test_missing_port.c b/test/missing_port.lv2/test_missing_port.c index a966d93..ec6713c 100644 --- a/test/missing_port.lv2/test_missing_port.c +++ b/test/missing_port.lv2/test_missing_port.c @@ -16,33 +16,32 @@ int main(int argc, char** argv) { - if (argc != 2) { - fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); - return 1; - } - - const char* bundle_path = argv[1]; - LilvWorld* world = lilv_world_new(); - - // Load test plugin bundle - uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); - SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); - LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); - lilv_world_load_bundle(world, bundle_uri); - free(abs_bundle); - serd_node_free(&bundle); - lilv_node_free(bundle_uri); - - LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); - - // Check that all ports are ignored - assert(lilv_plugin_get_num_ports(plugin) == 0); - - lilv_node_free(plugin_uri); - lilv_world_free(world); - - return 0; + if (argc != 2) { + fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); + return 1; + } + + const char* bundle_path = argv[1]; + LilvWorld* world = lilv_world_new(); + + // Load test plugin bundle + uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); + SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); + LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); + lilv_world_load_bundle(world, bundle_uri); + free(abs_bundle); + serd_node_free(&bundle); + lilv_node_free(bundle_uri); + + LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); + + // Check that all ports are ignored + assert(lilv_plugin_get_num_ports(plugin) == 0); + + lilv_node_free(plugin_uri); + lilv_world_free(world); + + return 0; } - diff --git a/test/missing_port_name.lv2/missing_port_name.c b/test/missing_port_name.lv2/missing_port_name.c index f48203a..2b8efe0 100644 --- a/test/missing_port_name.lv2/missing_port_name.c +++ b/test/missing_port_name.lv2/missing_port_name.c @@ -22,36 +22,33 @@ #define PLUGIN_URI "http://example.org/missing-port-name" -enum { - TEST_INPUT = 0, - TEST_OUTPUT = 1 -}; +enum { TEST_INPUT = 0, TEST_OUTPUT = 1 }; typedef struct { - float* input; - float* output; + float* input; + float* output; } Test; static void cleanup(LV2_Handle instance) { - free((Test*)instance); + free((Test*)instance); } static void connect_port(LV2_Handle instance, uint32_t port, void* data) { - Test* test = (Test*)instance; - switch (port) { - case TEST_INPUT: - test->input = (float*)data; - break; - case TEST_OUTPUT: - test->output = (float*)data; - break; - default: - break; - } + Test* test = (Test*)instance; + switch (port) { + case TEST_INPUT: + test->input = (float*)data; + break; + case TEST_OUTPUT: + test->output = (float*)data; + break; + default: + break; + } } static LV2_Handle @@ -60,35 +57,36 @@ instantiate(const LV2_Descriptor* descriptor, const char* path, const LV2_Feature* const* features) { - Test* test = (Test*)calloc(1, sizeof(Test)); - if (!test) { - return NULL; - } + Test* test = (Test*)calloc(1, sizeof(Test)); + if (!test) { + return NULL; + } - return (LV2_Handle)test; + return (LV2_Handle)test; } static void run(LV2_Handle instance, uint32_t sample_count) { - Test* test = (Test*)instance; + Test* test = (Test*)instance; - *test->output = *test->input; + *test->output = *test->input; } static const LV2_Descriptor descriptor = { - PLUGIN_URI, - instantiate, - connect_port, - NULL, // activate, - run, - NULL, // deactivate, - cleanup, - NULL // extension_data + PLUGIN_URI, + instantiate, + connect_port, + NULL, // activate, + run, + NULL, // deactivate, + cleanup, + NULL // extension_data }; LV2_SYMBOL_EXPORT -const LV2_Descriptor* lv2_descriptor(uint32_t index) +const LV2_Descriptor* +lv2_descriptor(uint32_t index) { - return (index == 0) ? &descriptor : NULL; + return (index == 0) ? &descriptor : NULL; } diff --git a/test/missing_port_name.lv2/test_missing_port_name.c b/test/missing_port_name.lv2/test_missing_port_name.c index 9a68065..4d017d9 100644 --- a/test/missing_port_name.lv2/test_missing_port_name.c +++ b/test/missing_port_name.lv2/test_missing_port_name.c @@ -16,37 +16,36 @@ int main(int argc, char** argv) { - if (argc != 2) { - fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); - return 1; - } - - const char* bundle_path = argv[1]; - LilvWorld* world = lilv_world_new(); - - // Load test plugin bundle - uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); - SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); - LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); - lilv_world_load_bundle(world, bundle_uri); - free(abs_bundle); - serd_node_free(&bundle); - lilv_node_free(bundle_uri); - - LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); - assert(plugin); - - const LilvPort* port = lilv_plugin_get_port_by_index(plugin, 0); - assert(port); - LilvNode* name = lilv_port_get_name(plugin, port); - assert(!name); - lilv_node_free(name); - - lilv_node_free(plugin_uri); - lilv_world_free(world); - - return 0; + if (argc != 2) { + fprintf(stderr, "USAGE: %s BUNDLE\n", argv[0]); + return 1; + } + + const char* bundle_path = argv[1]; + LilvWorld* world = lilv_world_new(); + + // Load test plugin bundle + uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(bundle_path); + SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); + LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); + lilv_world_load_bundle(world, bundle_uri); + free(abs_bundle); + serd_node_free(&bundle); + lilv_node_free(bundle_uri); + + LilvNode* plugin_uri = lilv_new_uri(world, PLUGIN_URI); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); + assert(plugin); + + const LilvPort* port = lilv_plugin_get_port_by_index(plugin, 0); + assert(port); + LilvNode* name = lilv_port_get_name(plugin, port); + assert(!name); + lilv_node_free(name); + + lilv_node_free(plugin_uri); + lilv_world_free(world); + + return 0; } - diff --git a/test/new_version.lv2/new_version.c b/test/new_version.lv2/new_version.c index 2669a83..ac5c6ad 100644 --- a/test/new_version.lv2/new_version.c +++ b/test/new_version.lv2/new_version.c @@ -22,36 +22,33 @@ #define PLUGIN_URI "http://example.org/versioned" -enum { - TEST_INPUT = 0, - TEST_OUTPUT = 1 -}; +enum { TEST_INPUT = 0, TEST_OUTPUT = 1 }; typedef struct { - float* input; - float* output; + float* input; + float* output; } Test; static void cleanup(LV2_Handle instance) { - free((Test*)instance); + free((Test*)instance); } static void connect_port(LV2_Handle instance, uint32_t port, void* data) { - Test* test = (Test*)instance; - switch (port) { - case TEST_INPUT: - test->input = (float*)data; - break; - case TEST_OUTPUT: - test->output = (float*)data; - break; - default: - break; - } + Test* test = (Test*)instance; + switch (port) { + case TEST_INPUT: + test->input = (float*)data; + break; + case TEST_OUTPUT: + test->output = (float*)data; + break; + default: + break; + } } static LV2_Handle @@ -60,35 +57,36 @@ instantiate(const LV2_Descriptor* descriptor, const char* path, const LV2_Feature* const* features) { - Test* test = (Test*)calloc(1, sizeof(Test)); - if (!test) { - return NULL; - } + Test* test = (Test*)calloc(1, sizeof(Test)); + if (!test) { + return NULL; + } - return (LV2_Handle)test; + return (LV2_Handle)test; } static void run(LV2_Handle instance, uint32_t sample_count) { - Test* test = (Test*)instance; + Test* test = (Test*)instance; - *test->output = *test->input; + *test->output = *test->input; } static const LV2_Descriptor descriptor = { - PLUGIN_URI, - instantiate, - connect_port, - NULL, // activate, - run, - NULL, // deactivate, - cleanup, - NULL // extension_data + PLUGIN_URI, + instantiate, + connect_port, + NULL, // activate, + run, + NULL, // deactivate, + cleanup, + NULL // extension_data }; LV2_SYMBOL_EXPORT -const LV2_Descriptor* lv2_descriptor(uint32_t index) +const LV2_Descriptor* +lv2_descriptor(uint32_t index) { - return (index == 0) ? &descriptor : NULL; + return (index == 0) ? &descriptor : NULL; } diff --git a/test/old_version.lv2/old_version.c b/test/old_version.lv2/old_version.c index 84d3b2c..ae25ad2 100644 --- a/test/old_version.lv2/old_version.c +++ b/test/old_version.lv2/old_version.c @@ -22,36 +22,33 @@ #define PLUGIN_URI "http://example.org/versioned" -enum { - TEST_INPUT = 0, - TEST_OUTPUT = 1 -}; +enum { TEST_INPUT = 0, TEST_OUTPUT = 1 }; typedef struct { - float* input; - float* output; + float* input; + float* output; } Test; static void cleanup(LV2_Handle instance) { - free((Test*)instance); + free((Test*)instance); } static void connect_port(LV2_Handle instance, uint32_t port, void* data) { - Test* test = (Test*)instance; - switch (port) { - case TEST_INPUT: - test->input = (float*)data; - break; - case TEST_OUTPUT: - test->output = (float*)data; - break; - default: - break; - } + Test* test = (Test*)instance; + switch (port) { + case TEST_INPUT: + test->input = (float*)data; + break; + case TEST_OUTPUT: + test->output = (float*)data; + break; + default: + break; + } } static LV2_Handle @@ -60,35 +57,36 @@ instantiate(const LV2_Descriptor* descriptor, const char* path, const LV2_Feature* const* features) { - Test* test = (Test*)calloc(1, sizeof(Test)); - if (!test) { - return NULL; - } + Test* test = (Test*)calloc(1, sizeof(Test)); + if (!test) { + return NULL; + } - return (LV2_Handle)test; + return (LV2_Handle)test; } static void run(LV2_Handle instance, uint32_t sample_count) { - Test* test = (Test*)instance; + Test* test = (Test*)instance; - *test->output = *test->input; + *test->output = *test->input; } static const LV2_Descriptor descriptor = { - PLUGIN_URI, - instantiate, - connect_port, - NULL, // activate, - run, - NULL, // deactivate, - cleanup, - NULL // extension_data + PLUGIN_URI, + instantiate, + connect_port, + NULL, // activate, + run, + NULL, // deactivate, + cleanup, + NULL // extension_data }; LV2_SYMBOL_EXPORT -const LV2_Descriptor* lv2_descriptor(uint32_t index) +const LV2_Descriptor* +lv2_descriptor(uint32_t index) { - return (index == 0) ? &descriptor : NULL; + return (index == 0) ? &descriptor : NULL; } diff --git a/test/test.lv2/test.c b/test/test.lv2/test.c index b3ddd85..d6b2544 100644 --- a/test/test.lv2/test.c +++ b/test/test.lv2/test.c @@ -23,8 +23,8 @@ #include "lv2/urid/urid.h" #ifdef _MSC_VER -# include <io.h> -# define mkstemp(pat) _mktemp(pat) +# include <io.h> +# define mkstemp(pat) _mktemp(pat) #endif #include <stdint.h> @@ -36,64 +36,57 @@ #define TMP_TEMPLATE "lilv_testXXXXXX" -enum { - TEST_INPUT = 0, - TEST_OUTPUT = 1, - TEST_CONTROL = 2 -}; +enum { TEST_INPUT = 0, TEST_OUTPUT = 1, TEST_CONTROL = 2 }; typedef struct { - LV2_URID_Map* map; - LV2_State_Free_Path* free_path; + LV2_URID_Map* map; + LV2_State_Free_Path* free_path; - struct { - LV2_URID atom_Float; - } uris; + struct { + LV2_URID atom_Float; + } uris; - char tmp_file_path[sizeof(TMP_TEMPLATE)]; - char* rec_file_path; - FILE* rec_file; + char tmp_file_path[sizeof(TMP_TEMPLATE)]; + char* rec_file_path; + FILE* rec_file; - float* input; - float* output; - unsigned num_runs; + float* input; + float* output; + unsigned num_runs; } Test; static void cleanup(LV2_Handle instance) { - Test* test = (Test*)instance; - if (test->rec_file) { - fclose(test->rec_file); - } + Test* test = (Test*)instance; + if (test->rec_file) { + fclose(test->rec_file); + } - if (test->free_path) { - test->free_path->free_path(test->free_path->handle, - test->rec_file_path); - } + if (test->free_path) { + test->free_path->free_path(test->free_path->handle, test->rec_file_path); + } - free(instance); + free(instance); } static void -connect_port(LV2_Handle instance, - uint32_t port, - void* data) +connect_port(LV2_Handle instance, uint32_t port, void* data) { - Test* test = (Test*)instance; - switch (port) { - case TEST_INPUT: - test->input = (float*)data; - break; - case TEST_OUTPUT: - test->output = (float*)data; - break; - case TEST_CONTROL: - test->output = (float*)data; - break; - default: - break; - } + Test* test = (Test*)instance; + switch (port) { + case TEST_INPUT: + test->input = (float*)data; + break; + case TEST_OUTPUT: + test->output = (float*)data; + break; + case TEST_CONTROL: + test->output = (float*)data; + break; + default: + break; + } } static LV2_Handle @@ -102,74 +95,73 @@ instantiate(const LV2_Descriptor* descriptor, const char* path, const LV2_Feature* const* features) { - Test* test = (Test*)calloc(1, sizeof(Test)); - if (!test) { - return NULL; - } - - strncpy(test->tmp_file_path, TMP_TEMPLATE, strlen(TMP_TEMPLATE) + 1); - mkstemp(test->tmp_file_path); - - LV2_State_Make_Path* make_path = NULL; - - for (int i = 0; features[i]; ++i) { - if (!strcmp(features[i]->URI, LV2_URID_URI "#map")) { - test->map = (LV2_URID_Map*)features[i]->data; - test->uris.atom_Float = test->map->map( - 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; - } - } - - if (!test->map) { - fprintf(stderr, "Host does not support urid:map\n"); - free(test); - return NULL; - } - - 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"); - } - fprintf(test->rec_file, "instantiate\n"); - } - - return (LV2_Handle)test; + Test* test = (Test*)calloc(1, sizeof(Test)); + if (!test) { + return NULL; + } + + strncpy(test->tmp_file_path, TMP_TEMPLATE, strlen(TMP_TEMPLATE) + 1); + mkstemp(test->tmp_file_path); + + LV2_State_Make_Path* make_path = NULL; + + for (int i = 0; features[i]; ++i) { + if (!strcmp(features[i]->URI, LV2_URID_URI "#map")) { + test->map = (LV2_URID_Map*)features[i]->data; + test->uris.atom_Float = + test->map->map(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; + } + } + + if (!test->map) { + fprintf(stderr, "Host does not support urid:map\n"); + free(test); + return NULL; + } + + 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"); + } + fprintf(test->rec_file, "instantiate\n"); + } + + return (LV2_Handle)test; } static void -run(LV2_Handle instance, - uint32_t sample_count) +run(LV2_Handle instance, uint32_t sample_count) { - Test* test = (Test*)instance; - *test->output = *test->input; - if (sample_count == 1) { - ++test->num_runs; - } else if (sample_count == 2 && test->rec_file) { - // Append to rec file (changes size) - fprintf(test->rec_file, "run\n"); - } else if (sample_count == 3 && test->rec_file) { - // Change the first byte of rec file (doesn't change size) - fseek(test->rec_file, 0, SEEK_SET); - fprintf(test->rec_file, "X"); - fseek(test->rec_file, 0, SEEK_END); - } + Test* test = (Test*)instance; + *test->output = *test->input; + if (sample_count == 1) { + ++test->num_runs; + } else if (sample_count == 2 && test->rec_file) { + // Append to rec file (changes size) + fprintf(test->rec_file, "run\n"); + } else if (sample_count == 3 && test->rec_file) { + // Change the first byte of rec file (doesn't change size) + fseek(test->rec_file, 0, SEEK_SET); + fprintf(test->rec_file, "X"); + fseek(test->rec_file, 0, SEEK_END); + } } static uint32_t map_uri(Test* plugin, const char* uri) { - return plugin->map->map(plugin->map->handle, uri); + return plugin->map->map(plugin->map->handle, uri); } static LV2_State_Status @@ -179,156 +171,155 @@ save(LV2_Handle instance, uint32_t flags, const LV2_Feature* const* features) { - Test* plugin = (Test*)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", - strlen("hello") + 1, - map_uri(plugin, LV2_ATOM__String), - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); - - const uint32_t urid = map_uri(plugin, "http://example.org/urivalue"); - store(callback_data, - map_uri(plugin, "http://example.org/uri"), - &urid, - sizeof(uint32_t), - map_uri(plugin, LV2_ATOM__URID), - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); - - // Try to store second value for the same property (should fail) - const uint32_t urid2 = map_uri(plugin, "http://example.org/urivalue2"); - if (!store(callback_data, - map_uri(plugin, "http://example.org/uri"), - &urid2, - sizeof(uint32_t), - map_uri(plugin, LV2_ATOM__URID), - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE)) { - return LV2_STATE_ERR_UNKNOWN; - } - - // Try to store with a null key (should fail) - if (!store(callback_data, - 0, - &urid2, - sizeof(uint32_t), - map_uri(plugin, LV2_ATOM__URID), - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE)) { - return LV2_STATE_ERR_UNKNOWN; - } - - store(callback_data, - map_uri(plugin, "http://example.org/num-runs"), - &plugin->num_runs, - sizeof(plugin->num_runs), - map_uri(plugin, LV2_ATOM__Int), - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); - - const float two = 2.0f; - store(callback_data, - map_uri(plugin, "http://example.org/two"), - &two, - sizeof(two), - map_uri(plugin, LV2_ATOM__Float), - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); - - const uint32_t affirmative = 1; - store(callback_data, - map_uri(plugin, "http://example.org/true"), - &affirmative, - sizeof(affirmative), - map_uri(plugin, LV2_ATOM__Bool), - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); - - const uint32_t negative = 0; - store(callback_data, - map_uri(plugin, "http://example.org/false"), - &negative, - sizeof(negative), - map_uri(plugin, LV2_ATOM__Bool), - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); - - const uint8_t blob[] = "I am a blob of arbitrary data."; - store(callback_data, - map_uri(plugin, "http://example.org/blob"), - blob, - sizeof(blob), - map_uri(plugin, "http://example.org/SomeUnknownType"), - LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); - - if (map_path) { - FILE* file = fopen(plugin->tmp_file_path, "w"); - fprintf(file, "Hello\n"); - fclose(file); - char* apath = map_path->abstract_path(map_path->handle, - plugin->tmp_file_path); - char* apath2 = map_path->abstract_path(map_path->handle, - plugin->tmp_file_path); - if (strcmp(apath, apath2)) { - fprintf(stderr, "ERROR: Path %s != %s\n", apath, apath2); - } - - store(callback_data, - map_uri(plugin, "http://example.org/extfile"), - apath, - strlen(apath) + 1, - map_uri(plugin, LV2_ATOM__Path), - LV2_STATE_IS_POD); - - free_path->free_path(free_path->handle, apath); - free_path->free_path(free_path->handle, apath2); - - if (plugin->rec_file) { - fflush(plugin->rec_file); - apath = map_path->abstract_path(map_path->handle, - plugin->rec_file_path); - - store(callback_data, - map_uri(plugin, "http://example.org/recfile"), - apath, - strlen(apath) + 1, - map_uri(plugin, LV2_ATOM__Path), - LV2_STATE_IS_POD); - - free_path->free_path(free_path->handle, apath); - } - - if (make_path) { - char* spath = make_path->path(make_path->handle, "save"); - FILE* sfile = fopen(spath, "w"); - fprintf(sfile, "save"); - fclose(sfile); - - apath = map_path->abstract_path(map_path->handle, spath); - store(callback_data, - map_uri(plugin, "http://example.org/save-file"), - apath, - strlen(apath) + 1, - map_uri(plugin, LV2_ATOM__Path), - LV2_STATE_IS_POD); - free_path->free_path(free_path->handle, apath); - free_path->free_path(free_path->handle, spath); - } - } - - return LV2_STATE_SUCCESS; + Test* plugin = (Test*)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", + strlen("hello") + 1, + map_uri(plugin, LV2_ATOM__String), + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); + + const uint32_t urid = map_uri(plugin, "http://example.org/urivalue"); + store(callback_data, + map_uri(plugin, "http://example.org/uri"), + &urid, + sizeof(uint32_t), + map_uri(plugin, LV2_ATOM__URID), + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); + + // Try to store second value for the same property (should fail) + const uint32_t urid2 = map_uri(plugin, "http://example.org/urivalue2"); + if (!store(callback_data, + map_uri(plugin, "http://example.org/uri"), + &urid2, + sizeof(uint32_t), + map_uri(plugin, LV2_ATOM__URID), + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE)) { + return LV2_STATE_ERR_UNKNOWN; + } + + // Try to store with a null key (should fail) + if (!store(callback_data, + 0, + &urid2, + sizeof(uint32_t), + map_uri(plugin, LV2_ATOM__URID), + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE)) { + return LV2_STATE_ERR_UNKNOWN; + } + + store(callback_data, + map_uri(plugin, "http://example.org/num-runs"), + &plugin->num_runs, + sizeof(plugin->num_runs), + map_uri(plugin, LV2_ATOM__Int), + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); + + const float two = 2.0f; + store(callback_data, + map_uri(plugin, "http://example.org/two"), + &two, + sizeof(two), + map_uri(plugin, LV2_ATOM__Float), + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); + + const uint32_t affirmative = 1; + store(callback_data, + map_uri(plugin, "http://example.org/true"), + &affirmative, + sizeof(affirmative), + map_uri(plugin, LV2_ATOM__Bool), + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); + + const uint32_t negative = 0; + store(callback_data, + map_uri(plugin, "http://example.org/false"), + &negative, + sizeof(negative), + map_uri(plugin, LV2_ATOM__Bool), + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); + + const uint8_t blob[] = "I am a blob of arbitrary data."; + store(callback_data, + map_uri(plugin, "http://example.org/blob"), + blob, + sizeof(blob), + map_uri(plugin, "http://example.org/SomeUnknownType"), + LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); + + if (map_path) { + FILE* file = fopen(plugin->tmp_file_path, "w"); + fprintf(file, "Hello\n"); + fclose(file); + char* apath = + map_path->abstract_path(map_path->handle, plugin->tmp_file_path); + char* apath2 = + map_path->abstract_path(map_path->handle, plugin->tmp_file_path); + if (strcmp(apath, apath2)) { + fprintf(stderr, "ERROR: Path %s != %s\n", apath, apath2); + } + + store(callback_data, + map_uri(plugin, "http://example.org/extfile"), + apath, + strlen(apath) + 1, + map_uri(plugin, LV2_ATOM__Path), + LV2_STATE_IS_POD); + + free_path->free_path(free_path->handle, apath); + free_path->free_path(free_path->handle, apath2); + + if (plugin->rec_file) { + fflush(plugin->rec_file); + apath = map_path->abstract_path(map_path->handle, plugin->rec_file_path); + + store(callback_data, + map_uri(plugin, "http://example.org/recfile"), + apath, + strlen(apath) + 1, + map_uri(plugin, LV2_ATOM__Path), + LV2_STATE_IS_POD); + + free_path->free_path(free_path->handle, apath); + } + + if (make_path) { + char* spath = make_path->path(make_path->handle, "save"); + FILE* sfile = fopen(spath, "w"); + fprintf(sfile, "save"); + fclose(sfile); + + apath = map_path->abstract_path(map_path->handle, spath); + store(callback_data, + map_uri(plugin, "http://example.org/save-file"), + apath, + strlen(apath) + 1, + map_uri(plugin, LV2_ATOM__Path), + LV2_STATE_IS_POD); + free_path->free_path(free_path->handle, apath); + free_path->free_path(free_path->handle, spath); + } + } + + return LV2_STATE_SUCCESS; } static LV2_State_Status @@ -338,102 +329,105 @@ restore(LV2_Handle instance, uint32_t flags, const LV2_Feature* const* features) { - Test* plugin = (Test*)instance; - - 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; - } - } - - size_t size = 0; - uint32_t type = 0; - uint32_t valflags = 0; - - plugin->num_runs = *(int32_t*)retrieve( - callback_data, - map_uri(plugin, "http://example.org/num-runs"), - &size, &type, &valflags); - - if (!map_path || !free_path) { - return LV2_STATE_ERR_NO_FEATURE; - } - - char* apath = (char*)retrieve( - callback_data, - map_uri(plugin, "http://example.org/extfile"), - &size, &type, &valflags); - - if (valflags != LV2_STATE_IS_POD) { - fprintf(stderr, "error: Restored bad file flags\n"); - return LV2_STATE_ERR_BAD_FLAGS; - } - - if (apath) { - char* path = map_path->absolute_path(map_path->handle, apath); - FILE* f = fopen(path, "r"); - char str[8]; - size_t n_read = fread(str, 1, sizeof(str), f); - fclose(f); - if (strncmp(str, "Hello\n", n_read)) { - fprintf(stderr, "error: Restored bad file contents `%s' != `Hello'\n", - str); - } - free_path->free_path(free_path->handle, path); - } - - apath = (char*)retrieve( - callback_data, - map_uri(plugin, "http://example.org/save-file"), - &size, &type, &valflags); - if (apath) { - char* spath = map_path->absolute_path(map_path->handle, apath); - FILE* sfile = fopen(spath, "r"); - if (!sfile) { - fprintf(stderr, "error: Failed to open save file %s\n", spath); - } else { - fclose(sfile); - } - free_path->free_path(free_path->handle, spath); - } else { - fprintf(stderr, "error: Failed to restore save file.\n"); - } - - return LV2_STATE_SUCCESS; + Test* plugin = (Test*)instance; + + 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; + } + } + + size_t size = 0; + uint32_t type = 0; + uint32_t valflags = 0; + + plugin->num_runs = + *(int32_t*)retrieve(callback_data, + map_uri(plugin, "http://example.org/num-runs"), + &size, + &type, + &valflags); + + if (!map_path || !free_path) { + return LV2_STATE_ERR_NO_FEATURE; + } + + char* apath = (char*)retrieve(callback_data, + map_uri(plugin, "http://example.org/extfile"), + &size, + &type, + &valflags); + + if (valflags != LV2_STATE_IS_POD) { + fprintf(stderr, "error: Restored bad file flags\n"); + return LV2_STATE_ERR_BAD_FLAGS; + } + + if (apath) { + char* path = map_path->absolute_path(map_path->handle, apath); + FILE* f = fopen(path, "r"); + char str[8]; + size_t n_read = fread(str, 1, sizeof(str), f); + fclose(f); + if (strncmp(str, "Hello\n", n_read)) { + fprintf( + stderr, "error: Restored bad file contents `%s' != `Hello'\n", str); + } + free_path->free_path(free_path->handle, path); + } + + apath = (char*)retrieve(callback_data, + map_uri(plugin, "http://example.org/save-file"), + &size, + &type, + &valflags); + if (apath) { + char* spath = map_path->absolute_path(map_path->handle, apath); + FILE* sfile = fopen(spath, "r"); + if (!sfile) { + fprintf(stderr, "error: Failed to open save file %s\n", spath); + } else { + fclose(sfile); + } + free_path->free_path(free_path->handle, spath); + } else { + fprintf(stderr, "error: Failed to restore save file.\n"); + } + + return LV2_STATE_SUCCESS; } static const void* extension_data(const char* uri) { - static const LV2_State_Interface state = { save, restore }; - if (!strcmp(uri, LV2_STATE__interface)) { - return &state; - } - return NULL; + static const LV2_State_Interface state = {save, restore}; + if (!strcmp(uri, LV2_STATE__interface)) { + return &state; + } + return NULL; } -static const LV2_Descriptor descriptor = { - TEST_URI, - instantiate, - connect_port, - NULL, // activate, - run, - NULL, // deactivate, - cleanup, - extension_data -}; +static const LV2_Descriptor descriptor = {TEST_URI, + instantiate, + connect_port, + NULL, // activate, + run, + NULL, // deactivate, + cleanup, + extension_data}; LV2_SYMBOL_EXPORT -const LV2_Descriptor* lv2_descriptor(uint32_t index) +const LV2_Descriptor* +lv2_descriptor(uint32_t index) { - switch (index) { - case 0: - return &descriptor; - default: - return NULL; - } + switch (index) { + case 0: + return &descriptor; + default: + return NULL; + } } diff --git a/test/test_bad_port_index.c b/test/test_bad_port_index.c index a4d9ad2..a116760 100644 --- a/test/test_bad_port_index.c +++ b/test/test_bad_port_index.c @@ -38,21 +38,21 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - uint32_t n_ports = lilv_plugin_get_num_ports(plug); - assert(n_ports == 0); + uint32_t n_ports = lilv_plugin_get_num_ports(plug); + assert(n_ports == 0); - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_bad_port_symbol.c b/test/test_bad_port_symbol.c index be00986..16944b6 100644 --- a/test/test_bad_port_symbol.c +++ b/test/test_bad_port_symbol.c @@ -38,21 +38,21 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - uint32_t n_ports = lilv_plugin_get_num_ports(plug); - assert(n_ports == 0); + uint32_t n_ports = lilv_plugin_get_num_ports(plug); + assert(n_ports == 0); - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_classes.c b/test/test_classes.c index 2c74c07..de9fc65 100644 --- a/test/test_classes.c +++ b/test/test_classes.c @@ -38,38 +38,38 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } - const LilvPluginClass* plugin = lilv_world_get_plugin_class(world); - const LilvPluginClasses* classes = lilv_world_get_plugin_classes(world); - LilvPluginClasses* children = lilv_plugin_class_get_children(plugin); + const LilvPluginClass* plugin = lilv_world_get_plugin_class(world); + const LilvPluginClasses* classes = lilv_world_get_plugin_classes(world); + LilvPluginClasses* children = lilv_plugin_class_get_children(plugin); - assert(lilv_plugin_class_get_parent_uri(plugin) == NULL); - assert(lilv_plugin_classes_size(classes) > - lilv_plugin_classes_size(children)); - assert(!strcmp(lilv_node_as_string(lilv_plugin_class_get_label(plugin)), - "Plugin")); - assert(!strcmp(lilv_node_as_string(lilv_plugin_class_get_uri(plugin)), - "http://lv2plug.in/ns/lv2core#Plugin")); + assert(lilv_plugin_class_get_parent_uri(plugin) == NULL); + assert(lilv_plugin_classes_size(classes) > + lilv_plugin_classes_size(children)); + assert(!strcmp(lilv_node_as_string(lilv_plugin_class_get_label(plugin)), + "Plugin")); + assert(!strcmp(lilv_node_as_string(lilv_plugin_class_get_uri(plugin)), + "http://lv2plug.in/ns/lv2core#Plugin")); - LILV_FOREACH (plugin_classes, i, children) { - assert(lilv_node_equals(lilv_plugin_class_get_parent_uri( - lilv_plugin_classes_get(children, i)), - lilv_plugin_class_get_uri(plugin))); - } + LILV_FOREACH (plugin_classes, i, children) { + assert(lilv_node_equals( + lilv_plugin_class_get_parent_uri(lilv_plugin_classes_get(children, i)), + lilv_plugin_class_get_uri(plugin))); + } - LilvNode* some_uri = lilv_new_uri(world, "http://example.org/whatever"); - assert(lilv_plugin_classes_get_by_uri(classes, some_uri) == NULL); - lilv_node_free(some_uri); + LilvNode* some_uri = lilv_new_uri(world, "http://example.org/whatever"); + assert(lilv_plugin_classes_get_by_uri(classes, some_uri) == NULL); + lilv_node_free(some_uri); - lilv_plugin_classes_free(children); - delete_bundle(env); - lilv_test_env_free(env); + lilv_plugin_classes_free(children); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_discovery.c b/test/test_discovery.c index 2585959..f212203 100644 --- a/test/test_discovery.c +++ b/test/test_discovery.c @@ -39,58 +39,56 @@ static int discovery_plugin_found = 0; static void discovery_verify_plugin(const LilvTestEnv* env, const LilvPlugin* plugin) { - const LilvNode* value = lilv_plugin_get_uri(plugin); - if (lilv_node_equals(value, env->plugin1_uri)) { - const LilvNode* lib_uri = NULL; - assert(!lilv_node_equals(value, env->plugin2_uri)); - discovery_plugin_found = 1; - lib_uri = lilv_plugin_get_library_uri(plugin); - assert(lib_uri); - assert(lilv_node_is_uri(lib_uri)); - assert(lilv_node_as_uri(lib_uri)); - assert(strstr(lilv_node_as_uri(lib_uri), "foo" SHLIB_EXT)); - assert(lilv_plugin_verify(plugin)); - } + const LilvNode* value = lilv_plugin_get_uri(plugin); + if (lilv_node_equals(value, env->plugin1_uri)) { + const LilvNode* lib_uri = NULL; + assert(!lilv_node_equals(value, env->plugin2_uri)); + discovery_plugin_found = 1; + lib_uri = lilv_plugin_get_library_uri(plugin); + assert(lib_uri); + assert(lilv_node_is_uri(lib_uri)); + assert(lilv_node_as_uri(lib_uri)); + assert(strstr(lilv_node_as_uri(lib_uri), "foo" SHLIB_EXT)); + assert(lilv_plugin_verify(plugin)); + } } int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - assert(lilv_plugins_size(plugins) > 0); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + assert(lilv_plugins_size(plugins) > 0); - const LilvPlugin* plug1 = - lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + const LilvPlugin* plug1 = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - const LilvPlugin* plug2 = - lilv_plugins_get_by_uri(plugins, env->plugin2_uri); + const LilvPlugin* plug2 = lilv_plugins_get_by_uri(plugins, env->plugin2_uri); - assert(plug1); - assert(!plug2); + assert(plug1); + assert(!plug2); - { - LilvNode* name = lilv_plugin_get_name(plug1); - assert(!strcmp(lilv_node_as_string(name), "Test plugin")); - lilv_node_free(name); - } + { + LilvNode* name = lilv_plugin_get_name(plug1); + assert(!strcmp(lilv_node_as_string(name), "Test plugin")); + lilv_node_free(name); + } - discovery_plugin_found = 0; - LILV_FOREACH (plugins, i, plugins) { - discovery_verify_plugin(env, lilv_plugins_get(plugins, i)); - } + discovery_plugin_found = 0; + LILV_FOREACH (plugins, i, plugins) { + discovery_verify_plugin(env, lilv_plugins_get(plugins, i)); + } - assert(discovery_plugin_found); - plugins = NULL; + assert(discovery_plugin_found); + plugins = NULL; - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_filesystem.c b/test/test_filesystem.c index 7e1968d..761595e 100644 --- a/test/test_filesystem.c +++ b/test/test_filesystem.c @@ -30,523 +30,522 @@ static bool equals(char* string, const char* expected) { - const bool result = !strcmp(string, expected); - free(string); - return result; + const bool result = !strcmp(string, expected); + free(string); + return result; } static void test_temp_directory_path(void) { - char* tmpdir = lilv_temp_directory_path(); + char* tmpdir = lilv_temp_directory_path(); - assert(lilv_is_directory(tmpdir)); + assert(lilv_is_directory(tmpdir)); - free(tmpdir); + free(tmpdir); } static void test_path_is_absolute(void) { - assert(lilv_path_is_absolute("/a/b")); - assert(lilv_path_is_absolute("/a")); - assert(lilv_path_is_absolute("/")); + assert(lilv_path_is_absolute("/a/b")); + assert(lilv_path_is_absolute("/a")); + assert(lilv_path_is_absolute("/")); - assert(!lilv_path_is_absolute("a/b")); - assert(!lilv_path_is_absolute("a")); - assert(!lilv_path_is_absolute(".")); + assert(!lilv_path_is_absolute("a/b")); + assert(!lilv_path_is_absolute("a")); + assert(!lilv_path_is_absolute(".")); #ifdef _WIN32 - assert(lilv_path_is_absolute("C:/a/b")); - assert(lilv_path_is_absolute("C:\\a\\b")); - assert(lilv_path_is_absolute("D:/a/b")); - assert(lilv_path_is_absolute("D:\\a\\b")); + assert(lilv_path_is_absolute("C:/a/b")); + assert(lilv_path_is_absolute("C:\\a\\b")); + assert(lilv_path_is_absolute("D:/a/b")); + assert(lilv_path_is_absolute("D:\\a\\b")); #endif } static void test_path_is_child(void) { - assert(lilv_path_is_child("/a/b", "/a")); - assert(lilv_path_is_child("/a/b", "/a/")); - assert(lilv_path_is_child("/a/b/", "/a")); - assert(lilv_path_is_child("/a/b/", "/a/")); - - assert(!lilv_path_is_child("/a/b", "/a/c")); - assert(!lilv_path_is_child("/a/b", "/a/c/")); - assert(!lilv_path_is_child("/a/b/", "/a/c")); - assert(!lilv_path_is_child("/a/b/", "/a/c/")); - - assert(!lilv_path_is_child("/a/b", "/c")); - assert(!lilv_path_is_child("/a/b", "/c/")); - assert(!lilv_path_is_child("/a/b/", "/c")); - assert(!lilv_path_is_child("/a/b/", "/c/")); + assert(lilv_path_is_child("/a/b", "/a")); + assert(lilv_path_is_child("/a/b", "/a/")); + assert(lilv_path_is_child("/a/b/", "/a")); + assert(lilv_path_is_child("/a/b/", "/a/")); + + assert(!lilv_path_is_child("/a/b", "/a/c")); + assert(!lilv_path_is_child("/a/b", "/a/c/")); + assert(!lilv_path_is_child("/a/b/", "/a/c")); + assert(!lilv_path_is_child("/a/b/", "/a/c/")); + + assert(!lilv_path_is_child("/a/b", "/c")); + assert(!lilv_path_is_child("/a/b", "/c/")); + assert(!lilv_path_is_child("/a/b/", "/c")); + assert(!lilv_path_is_child("/a/b/", "/c/")); } static void test_path_current(void) { - char* cwd = lilv_path_current(); + char* cwd = lilv_path_current(); - assert(lilv_is_directory(cwd)); + assert(lilv_is_directory(cwd)); - free(cwd); + free(cwd); } static void test_path_absolute(void) { - const char* const short_path = "a"; - const char* const long_path = "a/b/c"; + const char* const short_path = "a"; + const char* const long_path = "a/b/c"; - char* const cwd = lilv_path_current(); - char* const expected_short = lilv_path_join(cwd, short_path); - char* const expected_long = lilv_path_join(cwd, long_path); + char* const cwd = lilv_path_current(); + char* const expected_short = lilv_path_join(cwd, short_path); + char* const expected_long = lilv_path_join(cwd, long_path); - assert(equals(lilv_path_absolute(short_path), expected_short)); - assert(equals(lilv_path_absolute(long_path), expected_long)); + 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); + free(expected_long); + free(expected_short); + free(cwd); } static void test_path_absolute_child(void) { - const char* const parent = "/parent"; - const char* const short_path = "a"; - const char* const long_path = "a/b/c"; + const char* const parent = "/parent"; + const char* const short_path = "a"; + const char* const long_path = "a/b/c"; - char* const expected_short = lilv_path_join(parent, short_path); - char* const expected_long = lilv_path_join(parent, long_path); + char* const expected_short = lilv_path_join(parent, short_path); + char* const expected_long = lilv_path_join(parent, long_path); - assert(equals(lilv_path_absolute_child(short_path, parent), - expected_short)); + assert(equals(lilv_path_absolute_child(short_path, parent), expected_short)); - assert(equals(lilv_path_absolute_child(long_path, parent), - expected_long)); + assert(equals(lilv_path_absolute_child(long_path, parent), expected_long)); - free(expected_long); - free(expected_short); + free(expected_long); + free(expected_short); } static void test_path_relative_to(void) { - assert(equals(lilv_path_relative_to("/a/b", "/a/"), "b")); - assert(equals(lilv_path_relative_to("/a", "/b/c/"), "/a")); - assert(equals(lilv_path_relative_to("/a/b/c", "/a/b/d/"), "../c")); - assert(equals(lilv_path_relative_to("/a/b/c", "/a/b/d/e/"), "../../c")); + assert(equals(lilv_path_relative_to("/a/b", "/a/"), "b")); + assert(equals(lilv_path_relative_to("/a", "/b/c/"), "/a")); + assert(equals(lilv_path_relative_to("/a/b/c", "/a/b/d/"), "../c")); + assert(equals(lilv_path_relative_to("/a/b/c", "/a/b/d/e/"), "../../c")); #ifdef _WIN32 - assert(equals(lilv_path_relative_to("C:/a/b", "C:/a/"), "b")); - assert(equals(lilv_path_relative_to("C:/a", "C:/b/c/"), "../../a")); - assert(equals(lilv_path_relative_to("C:/a/b/c", "C:/a/b/d/"), "../c")); - assert(equals(lilv_path_relative_to("C:/a/b/c", "C:/a/b/d/e/"), "../../c")); - - assert(equals(lilv_path_relative_to("C:\\a\\b", "C:\\a\\"), "b")); - assert(equals(lilv_path_relative_to("C:\\a", "C:\\b\\c\\"), "..\\..\\a")); - assert(equals(lilv_path_relative_to("C:\\a\\b\\c", "C:\\a\\b\\d\\"), "..\\c")); - assert(equals(lilv_path_relative_to("C:\\a\\b\\c", "C:\\a\\b\\d\\e\\"), "..\\..\\c")); + assert(equals(lilv_path_relative_to("C:/a/b", "C:/a/"), "b")); + assert(equals(lilv_path_relative_to("C:/a", "C:/b/c/"), "../../a")); + assert(equals(lilv_path_relative_to("C:/a/b/c", "C:/a/b/d/"), "../c")); + assert(equals(lilv_path_relative_to("C:/a/b/c", "C:/a/b/d/e/"), "../../c")); + + assert(equals(lilv_path_relative_to("C:\\a\\b", "C:\\a\\"), "b")); + assert(equals(lilv_path_relative_to("C:\\a", "C:\\b\\c\\"), "..\\..\\a")); + assert( + equals(lilv_path_relative_to("C:\\a\\b\\c", "C:\\a\\b\\d\\"), "..\\c")); + assert(equals(lilv_path_relative_to("C:\\a\\b\\c", "C:\\a\\b\\d\\e\\"), + "..\\..\\c")); #endif } static void test_path_parent(void) { - assert(equals(lilv_path_parent("/"), "/")); - assert(equals(lilv_path_parent("//"), "/")); - assert(equals(lilv_path_parent("/a"), "/")); - assert(equals(lilv_path_parent("/a/"), "/")); - assert(equals(lilv_path_parent("/a///b/"), "/a")); - assert(equals(lilv_path_parent("/a///b//"), "/a")); - assert(equals(lilv_path_parent("/a/b"), "/a")); - assert(equals(lilv_path_parent("/a/b/"), "/a")); - assert(equals(lilv_path_parent("/a/b/c"), "/a/b")); - assert(equals(lilv_path_parent("/a/b/c/"), "/a/b")); - assert(equals(lilv_path_parent("a"), ".")); + assert(equals(lilv_path_parent("/"), "/")); + assert(equals(lilv_path_parent("//"), "/")); + assert(equals(lilv_path_parent("/a"), "/")); + assert(equals(lilv_path_parent("/a/"), "/")); + assert(equals(lilv_path_parent("/a///b/"), "/a")); + assert(equals(lilv_path_parent("/a///b//"), "/a")); + assert(equals(lilv_path_parent("/a/b"), "/a")); + assert(equals(lilv_path_parent("/a/b/"), "/a")); + assert(equals(lilv_path_parent("/a/b/c"), "/a/b")); + assert(equals(lilv_path_parent("/a/b/c/"), "/a/b")); + assert(equals(lilv_path_parent("a"), ".")); } static void test_path_filename(void) { - // Cases from cppreference.com for std::filesystem::path::filename - assert(equals(lilv_path_filename("/foo/bar.txt"), "bar.txt")); - assert(equals(lilv_path_filename("/foo/.bar"), ".bar")); - assert(equals(lilv_path_filename("/foo/bar/"), "")); - assert(equals(lilv_path_filename("/foo/."), ".")); - assert(equals(lilv_path_filename("/foo/.."), "..")); - assert(equals(lilv_path_filename("."), ".")); - assert(equals(lilv_path_filename(".."), "..")); - assert(equals(lilv_path_filename("/"), "")); - assert(equals(lilv_path_filename("//host"), "host")); + // Cases from cppreference.com for std::filesystem::path::filename + assert(equals(lilv_path_filename("/foo/bar.txt"), "bar.txt")); + assert(equals(lilv_path_filename("/foo/.bar"), ".bar")); + assert(equals(lilv_path_filename("/foo/bar/"), "")); + assert(equals(lilv_path_filename("/foo/."), ".")); + assert(equals(lilv_path_filename("/foo/.."), "..")); + assert(equals(lilv_path_filename("."), ".")); + assert(equals(lilv_path_filename(".."), "..")); + assert(equals(lilv_path_filename("/"), "")); + assert(equals(lilv_path_filename("//host"), "host")); #ifdef _WIN32 - assert(equals(lilv_path_filename("C:/foo/bar.txt"), "bar.txt")); - assert(equals(lilv_path_filename("C:\\foo\\bar.txt"), "bar.txt")); - assert(equals(lilv_path_filename("foo/bar.txt"), "bar.txt")); - assert(equals(lilv_path_filename("foo\\bar.txt"), "bar.txt")); + assert(equals(lilv_path_filename("C:/foo/bar.txt"), "bar.txt")); + assert(equals(lilv_path_filename("C:\\foo\\bar.txt"), "bar.txt")); + assert(equals(lilv_path_filename("foo/bar.txt"), "bar.txt")); + assert(equals(lilv_path_filename("foo\\bar.txt"), "bar.txt")); #endif } static void test_path_join(void) { - assert(lilv_path_join(NULL, NULL) == NULL); - assert(lilv_path_join(NULL, "") == NULL); + assert(lilv_path_join(NULL, NULL) == NULL); + assert(lilv_path_join(NULL, "") == NULL); #ifdef _WIN32 - assert(equals(lilv_path_join("", NULL), "\\")); - assert(equals(lilv_path_join("", ""), "\\")); - assert(equals(lilv_path_join("a", ""), "a\\")); - assert(equals(lilv_path_join("a", NULL), "a\\")); - assert(equals(lilv_path_join("a", "b"), "a\\b")); + assert(equals(lilv_path_join("", NULL), "\\")); + assert(equals(lilv_path_join("", ""), "\\")); + assert(equals(lilv_path_join("a", ""), "a\\")); + assert(equals(lilv_path_join("a", NULL), "a\\")); + assert(equals(lilv_path_join("a", "b"), "a\\b")); #else - assert(equals(lilv_path_join("", NULL), "/")); - assert(equals(lilv_path_join("", ""), "/")); - assert(equals(lilv_path_join("a", ""), "a/")); - assert(equals(lilv_path_join("a", NULL), "a/")); - assert(equals(lilv_path_join("a", "b"), "a/b")); + assert(equals(lilv_path_join("", NULL), "/")); + assert(equals(lilv_path_join("", ""), "/")); + assert(equals(lilv_path_join("a", ""), "a/")); + assert(equals(lilv_path_join("a", NULL), "a/")); + assert(equals(lilv_path_join("a", "b"), "a/b")); #endif - assert(equals(lilv_path_join("/a", ""), "/a/")); - assert(equals(lilv_path_join("/a/b", ""), "/a/b/")); - assert(equals(lilv_path_join("/a/", ""), "/a/")); - assert(equals(lilv_path_join("/a/b/", ""), "/a/b/")); - assert(equals(lilv_path_join("a/b", ""), "a/b/")); - assert(equals(lilv_path_join("a/", ""), "a/")); - assert(equals(lilv_path_join("a/b/", ""), "a/b/")); - - assert(equals(lilv_path_join("/a", NULL), "/a/")); - assert(equals(lilv_path_join("/a/b", NULL), "/a/b/")); - assert(equals(lilv_path_join("/a/", NULL), "/a/")); - assert(equals(lilv_path_join("/a/b/", NULL), "/a/b/")); - assert(equals(lilv_path_join("a/b", NULL), "a/b/")); - assert(equals(lilv_path_join("a/", NULL), "a/")); - assert(equals(lilv_path_join("a/b/", NULL), "a/b/")); - - assert(equals(lilv_path_join("/a", "b"), "/a/b")); - assert(equals(lilv_path_join("/a/", "b"), "/a/b")); - assert(equals(lilv_path_join("a/", "b"), "a/b")); - - assert(equals(lilv_path_join("/a", "b/"), "/a/b/")); - assert(equals(lilv_path_join("/a/", "b/"), "/a/b/")); - assert(equals(lilv_path_join("a", "b/"), "a/b/")); - assert(equals(lilv_path_join("a/", "b/"), "a/b/")); + assert(equals(lilv_path_join("/a", ""), "/a/")); + assert(equals(lilv_path_join("/a/b", ""), "/a/b/")); + assert(equals(lilv_path_join("/a/", ""), "/a/")); + assert(equals(lilv_path_join("/a/b/", ""), "/a/b/")); + assert(equals(lilv_path_join("a/b", ""), "a/b/")); + assert(equals(lilv_path_join("a/", ""), "a/")); + assert(equals(lilv_path_join("a/b/", ""), "a/b/")); + + assert(equals(lilv_path_join("/a", NULL), "/a/")); + assert(equals(lilv_path_join("/a/b", NULL), "/a/b/")); + assert(equals(lilv_path_join("/a/", NULL), "/a/")); + assert(equals(lilv_path_join("/a/b/", NULL), "/a/b/")); + assert(equals(lilv_path_join("a/b", NULL), "a/b/")); + assert(equals(lilv_path_join("a/", NULL), "a/")); + assert(equals(lilv_path_join("a/b/", NULL), "a/b/")); + + assert(equals(lilv_path_join("/a", "b"), "/a/b")); + assert(equals(lilv_path_join("/a/", "b"), "/a/b")); + assert(equals(lilv_path_join("a/", "b"), "a/b")); + + assert(equals(lilv_path_join("/a", "b/"), "/a/b/")); + assert(equals(lilv_path_join("/a/", "b/"), "/a/b/")); + assert(equals(lilv_path_join("a", "b/"), "a/b/")); + assert(equals(lilv_path_join("a/", "b/"), "a/b/")); #ifdef _WIN32 - assert(equals(lilv_path_join("C:/a", "b"), "C:/a/b")); - assert(equals(lilv_path_join("C:\\a", "b"), "C:\\a\\b")); - assert(equals(lilv_path_join("C:/a", "b/"), "C:/a/b/")); - assert(equals(lilv_path_join("C:\\a", "b\\"), "C:\\a\\b\\")); + assert(equals(lilv_path_join("C:/a", "b"), "C:/a/b")); + assert(equals(lilv_path_join("C:\\a", "b"), "C:\\a\\b")); + assert(equals(lilv_path_join("C:/a", "b/"), "C:/a/b/")); + assert(equals(lilv_path_join("C:\\a", "b\\"), "C:\\a\\b\\")); #endif } static void test_path_canonical(void) { - char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); - char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); + char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); + char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); - FILE* f = fopen(file_path, "w"); - fprintf(f, "test\n"); - fclose(f); + FILE* f = fopen(file_path, "w"); + fprintf(f, "test\n"); + fclose(f); #ifndef _WIN32 - // Test symlink resolution + // Test symlink resolution - char* const link_path = lilv_path_join(temp_dir, "lilv_test_link"); + char* const link_path = lilv_path_join(temp_dir, "lilv_test_link"); - assert(!lilv_symlink(file_path, link_path)); + 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); + 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(!strcmp(real_file_path, real_link_path)); - assert(!lilv_remove(link_path)); - free(real_link_path); - free(real_file_path); - free(link_path); + assert(!lilv_remove(link_path)); + free(real_link_path); + free(real_file_path); + free(link_path); #endif - // Test dot segment resolution + // Test dot segment resolution - char* const parent_dir_1 = lilv_path_join(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); + char* const parent_dir_1 = lilv_path_join(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)); + assert(!strcmp(real_parent_dir_1, real_parent_dir_2)); - // Clean everything up + // Clean everything up - assert(!lilv_remove(file_path)); - assert(!lilv_remove(temp_dir)); + 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); + 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_path_exists(void) { - char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); - char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); + char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); + char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); - assert(!lilv_path_exists(file_path)); + assert(!lilv_path_exists(file_path)); - FILE* f = fopen(file_path, "w"); - fprintf(f, "test\n"); - fclose(f); + FILE* f = fopen(file_path, "w"); + fprintf(f, "test\n"); + fclose(f); - assert(lilv_path_exists(file_path)); + assert(lilv_path_exists(file_path)); - assert(!lilv_remove(file_path)); - assert(!lilv_remove(temp_dir)); + assert(!lilv_remove(file_path)); + assert(!lilv_remove(temp_dir)); - free(file_path); - free(temp_dir); + free(file_path); + free(temp_dir); } static void test_is_directory(void) { - char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); - char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); + char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); + char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); - assert(lilv_is_directory(temp_dir)); - assert(!lilv_is_directory(file_path)); // Nonexistent + assert(lilv_is_directory(temp_dir)); + assert(!lilv_is_directory(file_path)); // Nonexistent - FILE* f = fopen(file_path, "w"); - fprintf(f, "test\n"); - fclose(f); + FILE* f = fopen(file_path, "w"); + fprintf(f, "test\n"); + fclose(f); - assert(!lilv_is_directory(file_path)); // File + assert(!lilv_is_directory(file_path)); // File - assert(!lilv_remove(file_path)); - assert(!lilv_remove(temp_dir)); + assert(!lilv_remove(file_path)); + assert(!lilv_remove(temp_dir)); - free(file_path); - free(temp_dir); + free(file_path); + free(temp_dir); } static void test_copy_file(void) { - char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); - char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); - char* const copy_path = lilv_path_join(temp_dir, "lilv_test_copy"); - - FILE* f = fopen(file_path, "w"); - fprintf(f, "test\n"); - fclose(f); - - assert(!lilv_copy_file(file_path, copy_path)); - assert(lilv_file_equals(file_path, copy_path)); - - if (lilv_path_exists("/dev/full")) { - // Copy short file (error after flushing) - assert(lilv_copy_file(file_path, "/dev/full") == ENOSPC); - - // Copy long file (error during writing) - f = fopen(file_path, "w"); - for (size_t i = 0; i < 4096; ++i) { - fprintf(f, "test\n"); - } - fclose(f); - assert(lilv_copy_file(file_path, "/dev/full") == ENOSPC); - } - - assert(!lilv_remove(copy_path)); - assert(!lilv_remove(file_path)); - assert(!lilv_remove(temp_dir)); - - free(copy_path); - free(file_path); - free(temp_dir); + char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); + char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); + char* const copy_path = lilv_path_join(temp_dir, "lilv_test_copy"); + + FILE* f = fopen(file_path, "w"); + fprintf(f, "test\n"); + fclose(f); + + assert(!lilv_copy_file(file_path, copy_path)); + assert(lilv_file_equals(file_path, copy_path)); + + if (lilv_path_exists("/dev/full")) { + // Copy short file (error after flushing) + assert(lilv_copy_file(file_path, "/dev/full") == ENOSPC); + + // Copy long file (error during writing) + f = fopen(file_path, "w"); + for (size_t i = 0; i < 4096; ++i) { + fprintf(f, "test\n"); + } + fclose(f); + assert(lilv_copy_file(file_path, "/dev/full") == ENOSPC); + } + + assert(!lilv_remove(copy_path)); + assert(!lilv_remove(file_path)); + assert(!lilv_remove(temp_dir)); + + free(copy_path); + free(file_path); + free(temp_dir); } static void test_flock(void) { - char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); - char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); - - FILE* const f1 = fopen(file_path, "w"); - FILE* const f2 = fopen(file_path, "w"); - - assert(!lilv_flock(f1, true, false)); - assert(lilv_flock(f2, true, false)); - assert(!lilv_flock(f1, false, false)); - - fclose(f2); - fclose(f1); - assert(!lilv_remove(file_path)); - assert(!lilv_remove(temp_dir)); - free(file_path); - free(temp_dir); + char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); + char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); + + FILE* const f1 = fopen(file_path, "w"); + FILE* const f2 = fopen(file_path, "w"); + + assert(!lilv_flock(f1, true, false)); + assert(lilv_flock(f2, true, false)); + assert(!lilv_flock(f1, false, false)); + + fclose(f2); + fclose(f1); + assert(!lilv_remove(file_path)); + assert(!lilv_remove(temp_dir)); + free(file_path); + free(temp_dir); } -typedef struct -{ - size_t n_names; - char** names; +typedef struct { + size_t n_names; + char** names; } FileList; static void visit(const char* const path, const char* const name, void* const data) { - FileList* file_list = (FileList*)data; + FileList* file_list = (FileList*)data; - file_list->names = - (char**)realloc(file_list->names, sizeof(char*) * ++file_list->n_names); + file_list->names = + (char**)realloc(file_list->names, sizeof(char*) * ++file_list->n_names); - file_list->names[file_list->n_names - 1] = lilv_strdup(name); + file_list->names[file_list->n_names - 1] = lilv_strdup(name); } static void test_dir_for_each(void) { - char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); - char* const path1 = lilv_path_join(temp_dir, "lilv_test_1"); - char* const path2 = lilv_path_join(temp_dir, "lilv_test_2"); - - FILE* const f1 = fopen(path1, "w"); - FILE* const f2 = fopen(path2, "w"); - fprintf(f1, "test\n"); - fprintf(f2, "test\n"); - fclose(f2); - fclose(f1); - - FileList file_list = {0, NULL}; - lilv_dir_for_each(temp_dir, &file_list, visit); - - assert((!strcmp(file_list.names[0], "lilv_test_1") && - !strcmp(file_list.names[1], "lilv_test_2")) || - (!strcmp(file_list.names[0], "lilv_test_2") && - !strcmp(file_list.names[1], "lilv_test_1"))); - - assert(!lilv_remove(path2)); - assert(!lilv_remove(path1)); - assert(!lilv_remove(temp_dir)); - - free(file_list.names[0]); - free(file_list.names[1]); - free(file_list.names); - free(path2); - free(path1); - free(temp_dir); + char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); + char* const path1 = lilv_path_join(temp_dir, "lilv_test_1"); + char* const path2 = lilv_path_join(temp_dir, "lilv_test_2"); + + FILE* const f1 = fopen(path1, "w"); + FILE* const f2 = fopen(path2, "w"); + fprintf(f1, "test\n"); + fprintf(f2, "test\n"); + fclose(f2); + fclose(f1); + + FileList file_list = {0, NULL}; + lilv_dir_for_each(temp_dir, &file_list, visit); + + assert((!strcmp(file_list.names[0], "lilv_test_1") && + !strcmp(file_list.names[1], "lilv_test_2")) || + (!strcmp(file_list.names[0], "lilv_test_2") && + !strcmp(file_list.names[1], "lilv_test_1"))); + + assert(!lilv_remove(path2)); + assert(!lilv_remove(path1)); + assert(!lilv_remove(temp_dir)); + + free(file_list.names[0]); + free(file_list.names[1]); + free(file_list.names); + free(path2); + free(path1); + free(temp_dir); } static void test_create_temporary_directory(void) { - char* const path1 = lilv_create_temporary_directory("lilvXXXXXX"); + char* const path1 = lilv_create_temporary_directory("lilvXXXXXX"); - assert(lilv_is_directory(path1)); + assert(lilv_is_directory(path1)); - char* const path2 = lilv_create_temporary_directory("lilvXXXXXX"); + char* const path2 = lilv_create_temporary_directory("lilvXXXXXX"); - assert(strcmp(path1, path2)); - assert(lilv_is_directory(path2)); + assert(strcmp(path1, path2)); + assert(lilv_is_directory(path2)); - assert(!lilv_remove(path2)); - assert(!lilv_remove(path1)); - free(path2); - free(path1); + assert(!lilv_remove(path2)); + assert(!lilv_remove(path1)); + free(path2); + free(path1); } static void test_create_directories(void) { - char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); + char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); - assert(lilv_is_directory(temp_dir)); + assert(lilv_is_directory(temp_dir)); - char* const child_dir = lilv_path_join(temp_dir, "child"); - char* const grandchild_dir = lilv_path_join(child_dir, "grandchild"); + char* const child_dir = lilv_path_join(temp_dir, "child"); + char* const grandchild_dir = lilv_path_join(child_dir, "grandchild"); - assert(!lilv_create_directories(grandchild_dir)); - assert(lilv_is_directory(grandchild_dir)); - assert(lilv_is_directory(child_dir)); + assert(!lilv_create_directories(grandchild_dir)); + assert(lilv_is_directory(grandchild_dir)); + assert(lilv_is_directory(child_dir)); - char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); - FILE* const f = fopen(file_path, "w"); + char* const file_path = lilv_path_join(temp_dir, "lilv_test_file"); + FILE* const f = fopen(file_path, "w"); - fprintf(f, "test\n"); - fclose(f); + fprintf(f, "test\n"); + fclose(f); - assert(lilv_create_directories(file_path)); + assert(lilv_create_directories(file_path)); - assert(!lilv_remove(file_path)); - assert(!lilv_remove(grandchild_dir)); - assert(!lilv_remove(child_dir)); - assert(!lilv_remove(temp_dir)); - free(file_path); - free(child_dir); - free(grandchild_dir); - free(temp_dir); + assert(!lilv_remove(file_path)); + assert(!lilv_remove(grandchild_dir)); + assert(!lilv_remove(child_dir)); + assert(!lilv_remove(temp_dir)); + free(file_path); + free(child_dir); + free(grandchild_dir); + free(temp_dir); } static void test_file_equals(void) { - char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); - char* const path1 = lilv_path_join(temp_dir, "lilv_test_1"); - char* const path2 = lilv_path_join(temp_dir, "lilv_test_2"); + char* const temp_dir = lilv_create_temporary_directory("lilvXXXXXX"); + char* const path1 = lilv_path_join(temp_dir, "lilv_test_1"); + char* const path2 = lilv_path_join(temp_dir, "lilv_test_2"); - FILE* const f1 = fopen(path1, "w"); - FILE* const f2 = fopen(path2, "w"); - fprintf(f1, "test\n"); - fprintf(f2, "test\n"); + FILE* const f1 = fopen(path1, "w"); + FILE* const f2 = fopen(path2, "w"); + fprintf(f1, "test\n"); + fprintf(f2, "test\n"); - assert(lilv_file_equals(path1, path2)); + assert(lilv_file_equals(path1, path2)); - fprintf(f2, "diff\n"); - fflush(f2); + fprintf(f2, "diff\n"); + fflush(f2); - assert(!lilv_file_equals(path1, path2)); + assert(!lilv_file_equals(path1, path2)); - fclose(f2); - fclose(f1); + fclose(f2); + fclose(f1); - assert(!lilv_remove(path2)); - assert(!lilv_remove(path1)); - assert(!lilv_remove(temp_dir)); + assert(!lilv_remove(path2)); + assert(!lilv_remove(path1)); + assert(!lilv_remove(temp_dir)); - free(path2); - free(path1); - free(temp_dir); + free(path2); + free(path1); + free(temp_dir); } int main(void) { - test_temp_directory_path(); - test_path_is_absolute(); - test_path_is_child(); - test_path_current(); - test_path_absolute(); - test_path_absolute_child(); - test_path_relative_to(); - test_path_parent(); - test_path_filename(); - test_path_join(); - test_path_canonical(); - test_path_exists(); - test_is_directory(); - test_copy_file(); - test_flock(); - test_dir_for_each(); - test_create_temporary_directory(); - test_create_directories(); - test_file_equals(); - - return 0; + test_temp_directory_path(); + test_path_is_absolute(); + test_path_is_child(); + test_path_current(); + test_path_absolute(); + test_path_absolute_child(); + test_path_relative_to(); + test_path_parent(); + test_path_filename(); + test_path_join(); + test_path_canonical(); + test_path_exists(); + test_is_directory(); + test_copy_file(); + test_flock(); + test_dir_for_each(); + test_create_temporary_directory(); + test_create_directories(); + test_file_equals(); + + return 0; } diff --git a/test/test_get_symbol.c b/test/test_get_symbol.c index 0427447..e8cb452 100644 --- a/test/test_get_symbol.c +++ b/test/test_get_symbol.c @@ -37,45 +37,45 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, manifest_ttl, plugin_ttl)) { - return 1; - } + if (start_bundle(env, manifest_ttl, plugin_ttl)) { + return 1; + } - LilvNode* plug_sym = lilv_world_get_symbol(world, env->plugin1_uri); - LilvNode* path = lilv_new_uri(world, "http://example.org/foo"); - LilvNode* path_sym = lilv_world_get_symbol(world, path); - LilvNode* query = lilv_new_uri(world, "http://example.org/foo?bar=baz"); - LilvNode* query_sym = lilv_world_get_symbol(world, query); - LilvNode* frag = lilv_new_uri(world, "http://example.org/foo#bar"); - LilvNode* frag_sym = lilv_world_get_symbol(world, frag); - LilvNode* queryfrag = - lilv_new_uri(world, "http://example.org/foo?bar=baz#quux"); - LilvNode* queryfrag_sym = lilv_world_get_symbol(world, queryfrag); - LilvNode* nonuri = lilv_new_int(world, 42); + LilvNode* plug_sym = lilv_world_get_symbol(world, env->plugin1_uri); + LilvNode* path = lilv_new_uri(world, "http://example.org/foo"); + LilvNode* path_sym = lilv_world_get_symbol(world, path); + LilvNode* query = lilv_new_uri(world, "http://example.org/foo?bar=baz"); + LilvNode* query_sym = lilv_world_get_symbol(world, query); + LilvNode* frag = lilv_new_uri(world, "http://example.org/foo#bar"); + LilvNode* frag_sym = lilv_world_get_symbol(world, frag); + LilvNode* queryfrag = + lilv_new_uri(world, "http://example.org/foo?bar=baz#quux"); + LilvNode* queryfrag_sym = lilv_world_get_symbol(world, queryfrag); + LilvNode* nonuri = lilv_new_int(world, 42); - assert(lilv_world_get_symbol(world, nonuri) == NULL); - assert(!strcmp(lilv_node_as_string(plug_sym), "plugsym")); - assert(!strcmp(lilv_node_as_string(path_sym), "foo")); - assert(!strcmp(lilv_node_as_string(query_sym), "bar_baz")); - assert(!strcmp(lilv_node_as_string(frag_sym), "bar")); - assert(!strcmp(lilv_node_as_string(queryfrag_sym), "quux")); + assert(lilv_world_get_symbol(world, nonuri) == NULL); + assert(!strcmp(lilv_node_as_string(plug_sym), "plugsym")); + assert(!strcmp(lilv_node_as_string(path_sym), "foo")); + assert(!strcmp(lilv_node_as_string(query_sym), "bar_baz")); + assert(!strcmp(lilv_node_as_string(frag_sym), "bar")); + assert(!strcmp(lilv_node_as_string(queryfrag_sym), "quux")); - lilv_node_free(nonuri); - lilv_node_free(queryfrag_sym); - lilv_node_free(queryfrag); - lilv_node_free(frag_sym); - lilv_node_free(frag); - lilv_node_free(query_sym); - lilv_node_free(query); - lilv_node_free(path_sym); - lilv_node_free(path); - lilv_node_free(plug_sym); + lilv_node_free(nonuri); + lilv_node_free(queryfrag_sym); + lilv_node_free(queryfrag); + lilv_node_free(frag_sym); + lilv_node_free(frag); + lilv_node_free(query_sym); + lilv_node_free(query); + lilv_node_free(path_sym); + lilv_node_free(path); + lilv_node_free(plug_sym); - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_no_author.c b/test/test_no_author.c index 9cceedc..b67a284 100644 --- a/test/test_no_author.c +++ b/test/test_no_author.c @@ -60,28 +60,28 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(plug); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + assert(plug); - LilvNode* author_name = lilv_plugin_get_author_name(plug); - assert(!author_name); + LilvNode* author_name = lilv_plugin_get_author_name(plug); + assert(!author_name); - LilvNode* author_email = lilv_plugin_get_author_email(plug); - assert(!author_email); + LilvNode* author_email = lilv_plugin_get_author_email(plug); + assert(!author_email); - LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug); - assert(!author_homepage); + LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug); + assert(!author_homepage); - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_no_verify.c b/test/test_no_verify.c index 70812a5..cf6e0fd 100644 --- a/test/test_no_verify.c +++ b/test/test_no_verify.c @@ -27,22 +27,21 @@ static const char* const plugin_ttl = ":plug a lv2:Plugin .\n"; int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* explug = - lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* explug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(explug); - assert(!lilv_plugin_verify(explug)); + assert(explug); + assert(!lilv_plugin_verify(explug)); - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_plugin.c b/test/test_plugin.c index 6eab638..4b5645c 100644 --- a/test/test_plugin.c +++ b/test/test_plugin.c @@ -79,218 +79,213 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; - - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } - - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(plug); - - const LilvPluginClass* klass = lilv_plugin_get_class(plug); - const LilvNode* klass_uri = lilv_plugin_class_get_uri(klass); - assert(!strcmp(lilv_node_as_string(klass_uri), - "http://lv2plug.in/ns/lv2core#CompressorPlugin")); - - LilvNode* rdf_type = - lilv_new_uri(world, "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); - assert( - lilv_world_ask(world, lilv_plugin_get_uri(plug), rdf_type, klass_uri)); - lilv_node_free(rdf_type); - - assert(!lilv_plugin_is_replaced(plug)); - assert(!lilv_plugin_get_related(plug, NULL)); - - const LilvNode* plug_bundle_uri = lilv_plugin_get_bundle_uri(plug); - assert(!strcmp(lilv_node_as_string(plug_bundle_uri), env->test_bundle_uri)); - - const LilvNodes* data_uris = lilv_plugin_get_data_uris(plug); - assert(lilv_nodes_size(data_uris) == 2); - - LilvNode* project = lilv_plugin_get_project(plug); - assert(!project); - - char* manifest_uri = lilv_strjoin(lilv_node_as_string(plug_bundle_uri), - "manifest.ttl", - NULL); - - char* data_uri = - lilv_strjoin(lilv_node_as_string(plug_bundle_uri), "plugin.ttl", NULL); - - LilvNode* manifest_uri_val = lilv_new_uri(world, manifest_uri); - assert(lilv_nodes_contains(data_uris, manifest_uri_val)); - lilv_node_free(manifest_uri_val); - - LilvNode* data_uri_val = lilv_new_uri(world, data_uri); - assert(lilv_nodes_contains(data_uris, data_uri_val)); - lilv_node_free(data_uri_val); - - LilvNode* unknown_uri_val = - lilv_new_uri(world, "http://example.org/unknown"); - assert(!lilv_nodes_contains(data_uris, unknown_uri_val)); - lilv_node_free(unknown_uri_val); - - free(manifest_uri); - free(data_uri); - - float mins[3]; - float maxs[3]; - float defs[3]; - lilv_plugin_get_port_ranges_float(plug, mins, maxs, defs); - assert(mins[0] == -1.0f); - assert(maxs[0] == 1.0f); - assert(defs[0] == 0.5f); - - LilvNode* audio_class = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#AudioPort"); - LilvNode* control_class = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#ControlPort"); - LilvNode* in_class = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#InputPort"); - LilvNode* out_class = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#OutputPort"); - - assert(lilv_plugin_get_num_ports_of_class(plug, control_class, NULL) == 3); - assert(lilv_plugin_get_num_ports_of_class(plug, audio_class, NULL) == 0); - assert(lilv_plugin_get_num_ports_of_class(plug, in_class, NULL) == 2); - assert(lilv_plugin_get_num_ports_of_class(plug, out_class, NULL) == 1); - assert(lilv_plugin_get_num_ports_of_class( - plug, control_class, in_class, NULL) == 2); - assert(lilv_plugin_get_num_ports_of_class( - plug, control_class, out_class, NULL) == 1); - assert( - lilv_plugin_get_num_ports_of_class(plug, audio_class, in_class, NULL) == - 0); - assert(lilv_plugin_get_num_ports_of_class( - plug, audio_class, out_class, NULL) == 0); - - assert(lilv_plugin_has_latency(plug)); - assert(lilv_plugin_get_latency_port_index(plug) == 2); - - LilvNode* lv2_latency = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#latency"); - const LilvPort* latency_port = - lilv_plugin_get_port_by_designation(plug, out_class, lv2_latency); - lilv_node_free(lv2_latency); - - assert(latency_port); - assert(lilv_port_get_index(plug, latency_port) == 2); - assert(lilv_node_is_blank(lilv_port_get_node(plug, latency_port))); - - LilvNode* rt_feature = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#hardRTCapable"); - LilvNode* event_feature = - lilv_new_uri(world, "http://lv2plug.in/ns/ext/event"); - LilvNode* pretend_feature = - lilv_new_uri(world, "http://example.org/solvesWorldHunger"); - - assert(lilv_plugin_has_feature(plug, rt_feature)); - assert(lilv_plugin_has_feature(plug, event_feature)); - assert(!lilv_plugin_has_feature(plug, pretend_feature)); - - lilv_node_free(rt_feature); - lilv_node_free(event_feature); - lilv_node_free(pretend_feature); - - LilvNodes* supported = lilv_plugin_get_supported_features(plug); - LilvNodes* required = lilv_plugin_get_required_features(plug); - LilvNodes* optional = lilv_plugin_get_optional_features(plug); - assert(lilv_nodes_size(supported) == 2); - assert(lilv_nodes_size(required) == 1); - assert(lilv_nodes_size(optional) == 1); - lilv_nodes_free(supported); - lilv_nodes_free(required); - lilv_nodes_free(optional); - - LilvNode* foo_p = lilv_new_uri(world, "http://example.org/foo"); - LilvNodes* foos = lilv_plugin_get_value(plug, foo_p); - assert(lilv_nodes_size(foos) == 1); - assert(fabs(lilv_node_as_float(lilv_nodes_get_first(foos)) - 1.6180) < - FLT_EPSILON); - lilv_node_free(foo_p); - lilv_nodes_free(foos); - - LilvNode* bar_p = lilv_new_uri(world, "http://example.org/bar"); - LilvNodes* bars = lilv_plugin_get_value(plug, bar_p); - assert(lilv_nodes_size(bars) == 1); - assert(lilv_node_as_bool(lilv_nodes_get_first(bars)) == true); - lilv_node_free(bar_p); - lilv_nodes_free(bars); - - LilvNode* baz_p = lilv_new_uri(world, "http://example.org/baz"); - LilvNodes* bazs = lilv_plugin_get_value(plug, baz_p); - assert(lilv_nodes_size(bazs) == 1); - assert(lilv_node_as_bool(lilv_nodes_get_first(bazs)) == false); - lilv_node_free(baz_p); - lilv_nodes_free(bazs); - - LilvNode* blank_p = lilv_new_uri(world, "http://example.org/blank"); - LilvNodes* blanks = lilv_plugin_get_value(plug, blank_p); - assert(lilv_nodes_size(blanks) == 1); - LilvNode* blank = lilv_nodes_get_first(blanks); - assert(lilv_node_is_blank(blank)); - const char* blank_str = lilv_node_as_blank(blank); - char* blank_tok = lilv_node_get_turtle_token(blank); - assert(!strncmp(blank_tok, "_:", 2)); - assert(!strcmp(blank_tok + 2, blank_str)); - lilv_free(blank_tok); - lilv_node_free(blank_p); - lilv_nodes_free(blanks); - - LilvNode* author_name = lilv_plugin_get_author_name(plug); - assert(!strcmp(lilv_node_as_string(author_name), "David Robillard")); - lilv_node_free(author_name); - - LilvNode* author_email = lilv_plugin_get_author_email(plug); - assert(!strcmp(lilv_node_as_string(author_email), "mailto:d@drobilla.net")); - lilv_node_free(author_email); - - LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug); - assert( - !strcmp(lilv_node_as_string(author_homepage), "http://drobilla.net")); - lilv_node_free(author_homepage); - - LilvNode* thing_uri = lilv_new_uri(world, "http://example.org/thing"); - LilvNode* name_p = lilv_new_uri(world, "http://usefulinc.com/ns/doap#name"); - LilvNodes* thing_names = - lilv_world_find_nodes(world, thing_uri, name_p, NULL); - assert(lilv_nodes_size(thing_names) == 1); - LilvNode* thing_name = lilv_nodes_get_first(thing_names); - assert(thing_name); - assert(lilv_node_is_string(thing_name)); - assert(!strcmp(lilv_node_as_string(thing_name), "Something else")); - LilvNode* thing_name2 = lilv_world_get(world, thing_uri, name_p, NULL); - assert(lilv_node_equals(thing_name, thing_name2)); - - LilvUIs* uis = lilv_plugin_get_uis(plug); - assert(lilv_uis_size(uis) == 0); - lilv_uis_free(uis); - - LilvNode* extdata = lilv_new_uri(world, "http://example.org/extdata"); - LilvNode* noextdata = lilv_new_uri(world, "http://example.org/noextdata"); - LilvNodes* extdatas = lilv_plugin_get_extension_data(plug); - assert(lilv_plugin_has_extension_data(plug, extdata)); - assert(!lilv_plugin_has_extension_data(plug, noextdata)); - assert(lilv_nodes_size(extdatas) == 1); - assert(lilv_node_equals(lilv_nodes_get_first(extdatas), extdata)); - lilv_node_free(noextdata); - lilv_node_free(extdata); - lilv_nodes_free(extdatas); - - lilv_nodes_free(thing_names); - lilv_node_free(thing_uri); - lilv_node_free(thing_name2); - lilv_node_free(name_p); - lilv_node_free(control_class); - lilv_node_free(audio_class); - lilv_node_free(in_class); - lilv_node_free(out_class); - - delete_bundle(env); - lilv_test_env_free(env); - - return 0; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; + + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } + + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + assert(plug); + + const LilvPluginClass* klass = lilv_plugin_get_class(plug); + const LilvNode* klass_uri = lilv_plugin_class_get_uri(klass); + assert(!strcmp(lilv_node_as_string(klass_uri), + "http://lv2plug.in/ns/lv2core#CompressorPlugin")); + + LilvNode* rdf_type = + lilv_new_uri(world, "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); + assert(lilv_world_ask(world, lilv_plugin_get_uri(plug), rdf_type, klass_uri)); + lilv_node_free(rdf_type); + + assert(!lilv_plugin_is_replaced(plug)); + assert(!lilv_plugin_get_related(plug, NULL)); + + const LilvNode* plug_bundle_uri = lilv_plugin_get_bundle_uri(plug); + assert(!strcmp(lilv_node_as_string(plug_bundle_uri), env->test_bundle_uri)); + + const LilvNodes* data_uris = lilv_plugin_get_data_uris(plug); + assert(lilv_nodes_size(data_uris) == 2); + + LilvNode* project = lilv_plugin_get_project(plug); + assert(!project); + + char* manifest_uri = + lilv_strjoin(lilv_node_as_string(plug_bundle_uri), "manifest.ttl", NULL); + + char* data_uri = + lilv_strjoin(lilv_node_as_string(plug_bundle_uri), "plugin.ttl", NULL); + + LilvNode* manifest_uri_val = lilv_new_uri(world, manifest_uri); + assert(lilv_nodes_contains(data_uris, manifest_uri_val)); + lilv_node_free(manifest_uri_val); + + LilvNode* data_uri_val = lilv_new_uri(world, data_uri); + assert(lilv_nodes_contains(data_uris, data_uri_val)); + lilv_node_free(data_uri_val); + + LilvNode* unknown_uri_val = lilv_new_uri(world, "http://example.org/unknown"); + assert(!lilv_nodes_contains(data_uris, unknown_uri_val)); + lilv_node_free(unknown_uri_val); + + free(manifest_uri); + free(data_uri); + + float mins[3]; + float maxs[3]; + float defs[3]; + lilv_plugin_get_port_ranges_float(plug, mins, maxs, defs); + assert(mins[0] == -1.0f); + assert(maxs[0] == 1.0f); + assert(defs[0] == 0.5f); + + LilvNode* audio_class = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#AudioPort"); + LilvNode* control_class = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#ControlPort"); + LilvNode* in_class = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#InputPort"); + LilvNode* out_class = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#OutputPort"); + + assert(lilv_plugin_get_num_ports_of_class(plug, control_class, NULL) == 3); + assert(lilv_plugin_get_num_ports_of_class(plug, audio_class, NULL) == 0); + assert(lilv_plugin_get_num_ports_of_class(plug, in_class, NULL) == 2); + assert(lilv_plugin_get_num_ports_of_class(plug, out_class, NULL) == 1); + assert(lilv_plugin_get_num_ports_of_class( + plug, control_class, in_class, NULL) == 2); + assert(lilv_plugin_get_num_ports_of_class( + plug, control_class, out_class, NULL) == 1); + assert( + lilv_plugin_get_num_ports_of_class(plug, audio_class, in_class, NULL) == 0); + assert(lilv_plugin_get_num_ports_of_class( + plug, audio_class, out_class, NULL) == 0); + + assert(lilv_plugin_has_latency(plug)); + assert(lilv_plugin_get_latency_port_index(plug) == 2); + + LilvNode* lv2_latency = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#latency"); + const LilvPort* latency_port = + lilv_plugin_get_port_by_designation(plug, out_class, lv2_latency); + lilv_node_free(lv2_latency); + + assert(latency_port); + assert(lilv_port_get_index(plug, latency_port) == 2); + assert(lilv_node_is_blank(lilv_port_get_node(plug, latency_port))); + + LilvNode* rt_feature = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#hardRTCapable"); + LilvNode* event_feature = + lilv_new_uri(world, "http://lv2plug.in/ns/ext/event"); + LilvNode* pretend_feature = + lilv_new_uri(world, "http://example.org/solvesWorldHunger"); + + assert(lilv_plugin_has_feature(plug, rt_feature)); + assert(lilv_plugin_has_feature(plug, event_feature)); + assert(!lilv_plugin_has_feature(plug, pretend_feature)); + + lilv_node_free(rt_feature); + lilv_node_free(event_feature); + lilv_node_free(pretend_feature); + + LilvNodes* supported = lilv_plugin_get_supported_features(plug); + LilvNodes* required = lilv_plugin_get_required_features(plug); + LilvNodes* optional = lilv_plugin_get_optional_features(plug); + assert(lilv_nodes_size(supported) == 2); + assert(lilv_nodes_size(required) == 1); + assert(lilv_nodes_size(optional) == 1); + lilv_nodes_free(supported); + lilv_nodes_free(required); + lilv_nodes_free(optional); + + LilvNode* foo_p = lilv_new_uri(world, "http://example.org/foo"); + LilvNodes* foos = lilv_plugin_get_value(plug, foo_p); + assert(lilv_nodes_size(foos) == 1); + assert(fabs(lilv_node_as_float(lilv_nodes_get_first(foos)) - 1.6180) < + FLT_EPSILON); + lilv_node_free(foo_p); + lilv_nodes_free(foos); + + LilvNode* bar_p = lilv_new_uri(world, "http://example.org/bar"); + LilvNodes* bars = lilv_plugin_get_value(plug, bar_p); + assert(lilv_nodes_size(bars) == 1); + assert(lilv_node_as_bool(lilv_nodes_get_first(bars)) == true); + lilv_node_free(bar_p); + lilv_nodes_free(bars); + + LilvNode* baz_p = lilv_new_uri(world, "http://example.org/baz"); + LilvNodes* bazs = lilv_plugin_get_value(plug, baz_p); + assert(lilv_nodes_size(bazs) == 1); + assert(lilv_node_as_bool(lilv_nodes_get_first(bazs)) == false); + lilv_node_free(baz_p); + lilv_nodes_free(bazs); + + LilvNode* blank_p = lilv_new_uri(world, "http://example.org/blank"); + LilvNodes* blanks = lilv_plugin_get_value(plug, blank_p); + assert(lilv_nodes_size(blanks) == 1); + LilvNode* blank = lilv_nodes_get_first(blanks); + assert(lilv_node_is_blank(blank)); + const char* blank_str = lilv_node_as_blank(blank); + char* blank_tok = lilv_node_get_turtle_token(blank); + assert(!strncmp(blank_tok, "_:", 2)); + assert(!strcmp(blank_tok + 2, blank_str)); + lilv_free(blank_tok); + lilv_node_free(blank_p); + lilv_nodes_free(blanks); + + LilvNode* author_name = lilv_plugin_get_author_name(plug); + assert(!strcmp(lilv_node_as_string(author_name), "David Robillard")); + lilv_node_free(author_name); + + LilvNode* author_email = lilv_plugin_get_author_email(plug); + assert(!strcmp(lilv_node_as_string(author_email), "mailto:d@drobilla.net")); + lilv_node_free(author_email); + + LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug); + assert(!strcmp(lilv_node_as_string(author_homepage), "http://drobilla.net")); + lilv_node_free(author_homepage); + + LilvNode* thing_uri = lilv_new_uri(world, "http://example.org/thing"); + LilvNode* name_p = lilv_new_uri(world, "http://usefulinc.com/ns/doap#name"); + LilvNodes* thing_names = + lilv_world_find_nodes(world, thing_uri, name_p, NULL); + assert(lilv_nodes_size(thing_names) == 1); + LilvNode* thing_name = lilv_nodes_get_first(thing_names); + assert(thing_name); + assert(lilv_node_is_string(thing_name)); + assert(!strcmp(lilv_node_as_string(thing_name), "Something else")); + LilvNode* thing_name2 = lilv_world_get(world, thing_uri, name_p, NULL); + assert(lilv_node_equals(thing_name, thing_name2)); + + LilvUIs* uis = lilv_plugin_get_uis(plug); + assert(lilv_uis_size(uis) == 0); + lilv_uis_free(uis); + + LilvNode* extdata = lilv_new_uri(world, "http://example.org/extdata"); + LilvNode* noextdata = lilv_new_uri(world, "http://example.org/noextdata"); + LilvNodes* extdatas = lilv_plugin_get_extension_data(plug); + assert(lilv_plugin_has_extension_data(plug, extdata)); + assert(!lilv_plugin_has_extension_data(plug, noextdata)); + assert(lilv_nodes_size(extdatas) == 1); + assert(lilv_node_equals(lilv_nodes_get_first(extdatas), extdata)); + lilv_node_free(noextdata); + lilv_node_free(extdata); + lilv_nodes_free(extdatas); + + lilv_nodes_free(thing_names); + lilv_node_free(thing_uri); + lilv_node_free(thing_name2); + lilv_node_free(name_p); + lilv_node_free(control_class); + lilv_node_free(audio_class); + lilv_node_free(in_class); + lilv_node_free(out_class); + + delete_bundle(env); + lilv_test_env_free(env); + + return 0; } diff --git a/test/test_port.c b/test/test_port.c index 0aba6ea..48812b2 100644 --- a/test/test_port.c +++ b/test/test_port.c @@ -77,257 +77,252 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; - - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } - - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(plug); - - LilvNode* psym = lilv_new_string(world, "foo"); - const LilvPort* p = lilv_plugin_get_port_by_index(plug, 0); - const LilvPort* p2 = lilv_plugin_get_port_by_symbol(plug, psym); - lilv_node_free(psym); - assert(p != NULL); - assert(p2 != NULL); - assert(p == p2); - - LilvNode* nopsym = lilv_new_string(world, "thisaintnoportfoo"); - const LilvPort* p3 = lilv_plugin_get_port_by_symbol(plug, nopsym); - assert(p3 == NULL); - lilv_node_free(nopsym); - - // Try getting an invalid property - LilvNode* num = lilv_new_int(world, 1); - LilvNodes* nothing = lilv_port_get_value(plug, p, num); - assert(!nothing); - lilv_node_free(num); - - LilvNode* audio_class = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#AudioPort"); - LilvNode* control_class = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#ControlPort"); - LilvNode* in_class = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#InputPort"); - LilvNode* out_class = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#OutputPort"); - - assert(lilv_nodes_size(lilv_port_get_classes(plug, p)) == 2); - assert(lilv_plugin_get_num_ports(plug) == 4); - assert(lilv_port_is_a(plug, p, control_class)); - assert(lilv_port_is_a(plug, p, in_class)); - assert(!lilv_port_is_a(plug, p, audio_class)); - - LilvNodes* port_properties = lilv_port_get_properties(plug, p); - assert(lilv_nodes_size(port_properties) == 1); - lilv_nodes_free(port_properties); - - // Untranslated name (current locale is set to "C" in main) - assert(!strcmp(lilv_node_as_string(lilv_port_get_symbol(plug, p)), "foo")); - LilvNode* name = lilv_port_get_name(plug, p); - assert(!strcmp(lilv_node_as_string(name), "store")); - lilv_node_free(name); - - // Exact language match - set_env("LANG", "de_DE"); - name = lilv_port_get_name(plug, p); - assert(!strcmp(lilv_node_as_string(name), "Laden")); - lilv_node_free(name); - - // Exact language match (with charset suffix) - set_env("LANG", "de_AT.utf8"); - name = lilv_port_get_name(plug, p); - assert(!strcmp(lilv_node_as_string(name), "Geschaeft")); - lilv_node_free(name); - - // Partial language match (choose value translated for different country) - set_env("LANG", "de_CH"); - name = lilv_port_get_name(plug, p); - assert((!strcmp(lilv_node_as_string(name), "Laden")) || - (!strcmp(lilv_node_as_string(name), "Geschaeft"))); - lilv_node_free(name); - - // Partial language match (choose country-less language tagged value) - set_env("LANG", "es_MX"); - name = lilv_port_get_name(plug, p); - assert(!strcmp(lilv_node_as_string(name), "tienda")); - lilv_node_free(name); - - // No language match (choose untranslated value) - set_env("LANG", "cn"); - name = lilv_port_get_name(plug, p); - assert(!strcmp(lilv_node_as_string(name), "store")); - lilv_node_free(name); - - // Invalid language - set_env("LANG", "1!"); - name = lilv_port_get_name(plug, p); - assert(!strcmp(lilv_node_as_string(name), "store")); - lilv_node_free(name); - - set_env("LANG", "en_CA.utf-8"); - - // Language tagged value with no untranslated values - LilvNode* rdfs_comment = lilv_new_uri(world, LILV_NS_RDFS "comment"); - LilvNodes* comments = lilv_port_get_value(plug, p, rdfs_comment); - assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(comments)), - "comment")); - LilvNode* comment = lilv_port_get(plug, p, rdfs_comment); - assert(!strcmp(lilv_node_as_string(comment), "comment")); - lilv_node_free(comment); - lilv_nodes_free(comments); - - set_env("LANG", "fr"); - - comments = lilv_port_get_value(plug, p, rdfs_comment); - assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(comments)), - "commentaires")); - lilv_nodes_free(comments); - - set_env("LANG", "cn"); - - comments = lilv_port_get_value(plug, p, rdfs_comment); - assert(!comments); - lilv_nodes_free(comments); - - lilv_node_free(rdfs_comment); - - set_env("LANG", "C"); // Reset locale - - LilvScalePoints* points = lilv_port_get_scale_points(plug, p); - assert(lilv_scale_points_size(points) == 2); - - LilvIter* sp_iter = lilv_scale_points_begin(points); - const LilvScalePoint* sp0 = lilv_scale_points_get(points, sp_iter); - assert(sp0); - sp_iter = lilv_scale_points_next(points, sp_iter); - const LilvScalePoint* sp1 = lilv_scale_points_get(points, sp_iter); - assert(sp1); - - assert(((!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp0)), - "Sin") && - lilv_node_as_float(lilv_scale_point_get_value(sp0)) == 3) && - (!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp1)), - "Cos") && - lilv_node_as_float(lilv_scale_point_get_value(sp1)) == 4)) || - ((!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp0)), - "Cos") && - lilv_node_as_float(lilv_scale_point_get_value(sp0)) == 4) && - (!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp1)), - "Sin") && - lilv_node_as_float(lilv_scale_point_get_value(sp1)) == 3))); - - LilvNode* homepage_p = - lilv_new_uri(world, "http://usefulinc.com/ns/doap#homepage"); - LilvNodes* homepages = lilv_plugin_get_value(plug, homepage_p); - assert(lilv_nodes_size(homepages) == 1); - assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(homepages)), - "http://example.org/someplug")); - - LilvNode* min = NULL; - LilvNode* max = NULL; - LilvNode* def = NULL; - lilv_port_get_range(plug, p, &def, &min, &max); - assert(def); - assert(min); - assert(max); - assert(lilv_node_as_float(def) == 0.5); - assert(lilv_node_as_float(min) == -1.0); - assert(lilv_node_as_float(max) == 1.0); - - LilvNode* integer_prop = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#integer"); - LilvNode* toggled_prop = - lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#toggled"); - - assert(lilv_port_has_property(plug, p, integer_prop)); - assert(!lilv_port_has_property(plug, p, toggled_prop)); - - const LilvPort* ep = lilv_plugin_get_port_by_index(plug, 1); - - LilvNode* event_type = lilv_new_uri(world, "http://example.org/event"); - LilvNode* event_type_2 = - lilv_new_uri(world, "http://example.org/otherEvent"); - LilvNode* atom_event = lilv_new_uri(world, "http://example.org/atomEvent"); - assert(lilv_port_supports_event(plug, ep, event_type)); - assert(!lilv_port_supports_event(plug, ep, event_type_2)); - assert(lilv_port_supports_event(plug, ep, atom_event)); - - LilvNode* name_p = lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#name"); - LilvNodes* names = lilv_port_get_value(plug, p, name_p); - assert(lilv_nodes_size(names) == 1); - assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(names)), "store")); - lilv_nodes_free(names); - - LilvNode* true_val = lilv_new_bool(world, true); - LilvNode* false_val = lilv_new_bool(world, false); - - assert(!lilv_node_equals(true_val, false_val)); - - lilv_world_set_option(world, LILV_OPTION_FILTER_LANG, false_val); - names = lilv_port_get_value(plug, p, name_p); - assert(lilv_nodes_size(names) == 4); - lilv_nodes_free(names); - lilv_world_set_option(world, LILV_OPTION_FILTER_LANG, true_val); - - lilv_node_free(false_val); - lilv_node_free(true_val); - - names = lilv_port_get_value(plug, ep, name_p); - assert(lilv_nodes_size(names) == 1); - assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(names)), - "Event Input")); - - const LilvPort* ap_in = lilv_plugin_get_port_by_index(plug, 2); - - assert(lilv_port_is_a(plug, ap_in, in_class)); - assert(!lilv_port_is_a(plug, ap_in, out_class)); - assert(lilv_port_is_a(plug, ap_in, audio_class)); - assert(!lilv_port_is_a(plug, ap_in, control_class)); - - const LilvPort* ap_out = lilv_plugin_get_port_by_index(plug, 3); - - assert(lilv_port_is_a(plug, ap_out, out_class)); - assert(!lilv_port_is_a(plug, ap_out, in_class)); - assert(lilv_port_is_a(plug, ap_out, audio_class)); - assert(!lilv_port_is_a(plug, ap_out, control_class)); - - assert(lilv_plugin_get_num_ports_of_class( - plug, control_class, in_class, NULL) == 1); - assert( - lilv_plugin_get_num_ports_of_class(plug, audio_class, in_class, NULL) == - 1); - assert(lilv_plugin_get_num_ports_of_class( - plug, audio_class, out_class, NULL) == 1); - - lilv_nodes_free(names); - lilv_node_free(name_p); - - lilv_node_free(integer_prop); - lilv_node_free(toggled_prop); - lilv_node_free(event_type); - lilv_node_free(event_type_2); - lilv_node_free(atom_event); - - lilv_node_free(min); - lilv_node_free(max); - lilv_node_free(def); - - lilv_node_free(homepage_p); - lilv_nodes_free(homepages); - - lilv_scale_points_free(points); - lilv_node_free(control_class); - lilv_node_free(audio_class); - lilv_node_free(out_class); - lilv_node_free(in_class); - - delete_bundle(env); - lilv_test_env_free(env); - - return 0; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; + + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } + + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + assert(plug); + + LilvNode* psym = lilv_new_string(world, "foo"); + const LilvPort* p = lilv_plugin_get_port_by_index(plug, 0); + const LilvPort* p2 = lilv_plugin_get_port_by_symbol(plug, psym); + lilv_node_free(psym); + assert(p != NULL); + assert(p2 != NULL); + assert(p == p2); + + LilvNode* nopsym = lilv_new_string(world, "thisaintnoportfoo"); + const LilvPort* p3 = lilv_plugin_get_port_by_symbol(plug, nopsym); + assert(p3 == NULL); + lilv_node_free(nopsym); + + // Try getting an invalid property + LilvNode* num = lilv_new_int(world, 1); + LilvNodes* nothing = lilv_port_get_value(plug, p, num); + assert(!nothing); + lilv_node_free(num); + + LilvNode* audio_class = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#AudioPort"); + LilvNode* control_class = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#ControlPort"); + LilvNode* in_class = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#InputPort"); + LilvNode* out_class = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#OutputPort"); + + assert(lilv_nodes_size(lilv_port_get_classes(plug, p)) == 2); + assert(lilv_plugin_get_num_ports(plug) == 4); + assert(lilv_port_is_a(plug, p, control_class)); + assert(lilv_port_is_a(plug, p, in_class)); + assert(!lilv_port_is_a(plug, p, audio_class)); + + LilvNodes* port_properties = lilv_port_get_properties(plug, p); + assert(lilv_nodes_size(port_properties) == 1); + lilv_nodes_free(port_properties); + + // Untranslated name (current locale is set to "C" in main) + assert(!strcmp(lilv_node_as_string(lilv_port_get_symbol(plug, p)), "foo")); + LilvNode* name = lilv_port_get_name(plug, p); + assert(!strcmp(lilv_node_as_string(name), "store")); + lilv_node_free(name); + + // Exact language match + set_env("LANG", "de_DE"); + name = lilv_port_get_name(plug, p); + assert(!strcmp(lilv_node_as_string(name), "Laden")); + lilv_node_free(name); + + // Exact language match (with charset suffix) + set_env("LANG", "de_AT.utf8"); + name = lilv_port_get_name(plug, p); + assert(!strcmp(lilv_node_as_string(name), "Geschaeft")); + lilv_node_free(name); + + // Partial language match (choose value translated for different country) + set_env("LANG", "de_CH"); + name = lilv_port_get_name(plug, p); + assert((!strcmp(lilv_node_as_string(name), "Laden")) || + (!strcmp(lilv_node_as_string(name), "Geschaeft"))); + lilv_node_free(name); + + // Partial language match (choose country-less language tagged value) + set_env("LANG", "es_MX"); + name = lilv_port_get_name(plug, p); + assert(!strcmp(lilv_node_as_string(name), "tienda")); + lilv_node_free(name); + + // No language match (choose untranslated value) + set_env("LANG", "cn"); + name = lilv_port_get_name(plug, p); + assert(!strcmp(lilv_node_as_string(name), "store")); + lilv_node_free(name); + + // Invalid language + set_env("LANG", "1!"); + name = lilv_port_get_name(plug, p); + assert(!strcmp(lilv_node_as_string(name), "store")); + lilv_node_free(name); + + set_env("LANG", "en_CA.utf-8"); + + // Language tagged value with no untranslated values + LilvNode* rdfs_comment = lilv_new_uri(world, LILV_NS_RDFS "comment"); + LilvNodes* comments = lilv_port_get_value(plug, p, rdfs_comment); + assert( + !strcmp(lilv_node_as_string(lilv_nodes_get_first(comments)), "comment")); + LilvNode* comment = lilv_port_get(plug, p, rdfs_comment); + assert(!strcmp(lilv_node_as_string(comment), "comment")); + lilv_node_free(comment); + lilv_nodes_free(comments); + + set_env("LANG", "fr"); + + comments = lilv_port_get_value(plug, p, rdfs_comment); + assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(comments)), + "commentaires")); + lilv_nodes_free(comments); + + set_env("LANG", "cn"); + + comments = lilv_port_get_value(plug, p, rdfs_comment); + assert(!comments); + lilv_nodes_free(comments); + + lilv_node_free(rdfs_comment); + + set_env("LANG", "C"); // Reset locale + + LilvScalePoints* points = lilv_port_get_scale_points(plug, p); + assert(lilv_scale_points_size(points) == 2); + + LilvIter* sp_iter = lilv_scale_points_begin(points); + const LilvScalePoint* sp0 = lilv_scale_points_get(points, sp_iter); + assert(sp0); + sp_iter = lilv_scale_points_next(points, sp_iter); + const LilvScalePoint* sp1 = lilv_scale_points_get(points, sp_iter); + assert(sp1); + + assert( + ((!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp0)), "Sin") && + lilv_node_as_float(lilv_scale_point_get_value(sp0)) == 3) && + (!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp1)), "Cos") && + lilv_node_as_float(lilv_scale_point_get_value(sp1)) == 4)) || + ((!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp0)), "Cos") && + lilv_node_as_float(lilv_scale_point_get_value(sp0)) == 4) && + (!strcmp(lilv_node_as_string(lilv_scale_point_get_label(sp1)), "Sin") && + lilv_node_as_float(lilv_scale_point_get_value(sp1)) == 3))); + + LilvNode* homepage_p = + lilv_new_uri(world, "http://usefulinc.com/ns/doap#homepage"); + LilvNodes* homepages = lilv_plugin_get_value(plug, homepage_p); + assert(lilv_nodes_size(homepages) == 1); + assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(homepages)), + "http://example.org/someplug")); + + LilvNode* min = NULL; + LilvNode* max = NULL; + LilvNode* def = NULL; + lilv_port_get_range(plug, p, &def, &min, &max); + assert(def); + assert(min); + assert(max); + assert(lilv_node_as_float(def) == 0.5); + assert(lilv_node_as_float(min) == -1.0); + assert(lilv_node_as_float(max) == 1.0); + + LilvNode* integer_prop = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#integer"); + LilvNode* toggled_prop = + lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#toggled"); + + assert(lilv_port_has_property(plug, p, integer_prop)); + assert(!lilv_port_has_property(plug, p, toggled_prop)); + + const LilvPort* ep = lilv_plugin_get_port_by_index(plug, 1); + + LilvNode* event_type = lilv_new_uri(world, "http://example.org/event"); + LilvNode* event_type_2 = lilv_new_uri(world, "http://example.org/otherEvent"); + LilvNode* atom_event = lilv_new_uri(world, "http://example.org/atomEvent"); + assert(lilv_port_supports_event(plug, ep, event_type)); + assert(!lilv_port_supports_event(plug, ep, event_type_2)); + assert(lilv_port_supports_event(plug, ep, atom_event)); + + LilvNode* name_p = lilv_new_uri(world, "http://lv2plug.in/ns/lv2core#name"); + LilvNodes* names = lilv_port_get_value(plug, p, name_p); + assert(lilv_nodes_size(names) == 1); + assert(!strcmp(lilv_node_as_string(lilv_nodes_get_first(names)), "store")); + lilv_nodes_free(names); + + LilvNode* true_val = lilv_new_bool(world, true); + LilvNode* false_val = lilv_new_bool(world, false); + + assert(!lilv_node_equals(true_val, false_val)); + + lilv_world_set_option(world, LILV_OPTION_FILTER_LANG, false_val); + names = lilv_port_get_value(plug, p, name_p); + assert(lilv_nodes_size(names) == 4); + lilv_nodes_free(names); + lilv_world_set_option(world, LILV_OPTION_FILTER_LANG, true_val); + + lilv_node_free(false_val); + lilv_node_free(true_val); + + names = lilv_port_get_value(plug, ep, name_p); + assert(lilv_nodes_size(names) == 1); + assert( + !strcmp(lilv_node_as_string(lilv_nodes_get_first(names)), "Event Input")); + + const LilvPort* ap_in = lilv_plugin_get_port_by_index(plug, 2); + + assert(lilv_port_is_a(plug, ap_in, in_class)); + assert(!lilv_port_is_a(plug, ap_in, out_class)); + assert(lilv_port_is_a(plug, ap_in, audio_class)); + assert(!lilv_port_is_a(plug, ap_in, control_class)); + + const LilvPort* ap_out = lilv_plugin_get_port_by_index(plug, 3); + + assert(lilv_port_is_a(plug, ap_out, out_class)); + assert(!lilv_port_is_a(plug, ap_out, in_class)); + assert(lilv_port_is_a(plug, ap_out, audio_class)); + assert(!lilv_port_is_a(plug, ap_out, control_class)); + + assert(lilv_plugin_get_num_ports_of_class( + plug, control_class, in_class, NULL) == 1); + assert( + lilv_plugin_get_num_ports_of_class(plug, audio_class, in_class, NULL) == 1); + assert(lilv_plugin_get_num_ports_of_class( + plug, audio_class, out_class, NULL) == 1); + + lilv_nodes_free(names); + lilv_node_free(name_p); + + lilv_node_free(integer_prop); + lilv_node_free(toggled_prop); + lilv_node_free(event_type); + lilv_node_free(event_type_2); + lilv_node_free(atom_event); + + lilv_node_free(min); + lilv_node_free(max); + lilv_node_free(def); + + lilv_node_free(homepage_p); + lilv_nodes_free(homepages); + + lilv_scale_points_free(points); + lilv_node_free(control_class); + lilv_node_free(audio_class); + lilv_node_free(out_class); + lilv_node_free(in_class); + + delete_bundle(env); + lilv_test_env_free(env); + + return 0; } diff --git a/test/test_preset.c b/test/test_preset.c index d26d844..604d693 100644 --- a/test/test_preset.c +++ b/test/test_preset.c @@ -67,27 +67,27 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(plug); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + assert(plug); - LilvNode* pset_Preset = lilv_new_uri(world, LV2_PRESETS__Preset); - LilvNodes* related = lilv_plugin_get_related(plug, pset_Preset); + LilvNode* pset_Preset = lilv_new_uri(world, LV2_PRESETS__Preset); + LilvNodes* related = lilv_plugin_get_related(plug, pset_Preset); - assert(lilv_nodes_size(related) == 1); + assert(lilv_nodes_size(related) == 1); - lilv_node_free(pset_Preset); - lilv_nodes_free(related); + lilv_node_free(pset_Preset); + lilv_nodes_free(related); - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_project.c b/test/test_project.c index bc2e2c3..7080959 100644 --- a/test/test_project.c +++ b/test/test_project.c @@ -66,32 +66,31 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(plug); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + assert(plug); - LilvNode* author_name = lilv_plugin_get_author_name(plug); - assert(!strcmp(lilv_node_as_string(author_name), "David Robillard")); - lilv_node_free(author_name); + LilvNode* author_name = lilv_plugin_get_author_name(plug); + assert(!strcmp(lilv_node_as_string(author_name), "David Robillard")); + lilv_node_free(author_name); - LilvNode* author_email = lilv_plugin_get_author_email(plug); - assert(!strcmp(lilv_node_as_string(author_email), "mailto:d@drobilla.net")); - lilv_node_free(author_email); + LilvNode* author_email = lilv_plugin_get_author_email(plug); + assert(!strcmp(lilv_node_as_string(author_email), "mailto:d@drobilla.net")); + lilv_node_free(author_email); - LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug); - assert( - !strcmp(lilv_node_as_string(author_homepage), "http://drobilla.net")); - lilv_node_free(author_homepage); + LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug); + assert(!strcmp(lilv_node_as_string(author_homepage), "http://drobilla.net")); + lilv_node_free(author_homepage); - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_project_no_author.c b/test/test_project_no_author.c index 017d359..a2bdcc9 100644 --- a/test/test_project_no_author.c +++ b/test/test_project_no_author.c @@ -60,28 +60,28 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(plug); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + assert(plug); - LilvNode* author_name = lilv_plugin_get_author_name(plug); - assert(!author_name); + LilvNode* author_name = lilv_plugin_get_author_name(plug); + assert(!author_name); - LilvNode* author_email = lilv_plugin_get_author_email(plug); - assert(!author_email); + LilvNode* author_email = lilv_plugin_get_author_email(plug); + assert(!author_email); - LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug); - assert(!author_homepage); + LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug); + assert(!author_homepage); - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_prototype.c b/test/test_prototype.c index 4ad516e..77282eb 100644 --- a/test/test_prototype.c +++ b/test/test_prototype.c @@ -73,28 +73,28 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, manifest_ttl, plugin_ttl)) { - return 1; - } + if (start_bundle(env, manifest_ttl, plugin_ttl)) { + return 1; + } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(plug); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + assert(plug); - // Test non-inherited property - LilvNode* name = lilv_plugin_get_name(plug); - assert(!strcmp(lilv_node_as_string(name), "Instance")); - lilv_node_free(name); + // Test non-inherited property + LilvNode* name = lilv_plugin_get_name(plug); + assert(!strcmp(lilv_node_as_string(name), "Instance")); + lilv_node_free(name); - // Test inherited property - const LilvNode* binary = lilv_plugin_get_library_uri(plug); - assert(strstr(lilv_node_as_string(binary), "inst" SHLIB_EXT)); + // Test inherited property + const LilvNode* binary = lilv_plugin_get_library_uri(plug); + assert(strstr(lilv_node_as_string(binary), "inst" SHLIB_EXT)); - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_reload_bundle.c b/test/test_reload_bundle.c index 19644ff..888f601 100644 --- a/test/test_reload_bundle.c +++ b/test/test_reload_bundle.c @@ -26,67 +26,66 @@ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; - - // Create a simple plugin bundle - create_bundle(env, - ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT - "> ; rdfs:seeAlso <plugin.ttl> .\n", - ":plug a lv2:Plugin ; " - "doap:name \"First name\" ."); - - lilv_world_load_specifications(world); - - // Load bundle - LilvNode* bundle_uri = lilv_new_uri(world, env->test_bundle_uri); - lilv_world_load_bundle(world, bundle_uri); - - // Check that plugin is present - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(plug); - - // Check that plugin name is correct - LilvNode* name = lilv_plugin_get_name(plug); - assert(!strcmp(lilv_node_as_string(name), "First name")); - lilv_node_free(name); - - // Unload bundle from world and delete it - lilv_world_unload_bundle(world, bundle_uri); - delete_bundle(env); - - // Create a new version of the same bundle, but with a different name - create_bundle(env, - ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT - "> ; rdfs:seeAlso <plugin.ttl> .\n", - ":plug a lv2:Plugin ; " - "doap:name \"Second name\" ."); - - // Check that plugin is no longer in the world's plugin list - assert(lilv_plugins_size(plugins) == 0); - - // Load new bundle - lilv_world_load_bundle(world, bundle_uri); - - // Check that plugin is present again and is the same LilvPlugin - const LilvPlugin* plug2 = - lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(plug2); - assert(plug2 == plug); - - // Check that plugin now has new name - LilvNode* name2 = lilv_plugin_get_name(plug2); - assert(name2); - assert(!strcmp(lilv_node_as_string(name2), "Second name")); - lilv_node_free(name2); - - // Load new bundle again (noop) - lilv_world_load_bundle(world, bundle_uri); - - lilv_node_free(bundle_uri); - delete_bundle(env); - lilv_test_env_free(env); - - return 0; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; + + // Create a simple plugin bundle + create_bundle(env, + ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT + "> ; rdfs:seeAlso <plugin.ttl> .\n", + ":plug a lv2:Plugin ; " + "doap:name \"First name\" ."); + + lilv_world_load_specifications(world); + + // Load bundle + LilvNode* bundle_uri = lilv_new_uri(world, env->test_bundle_uri); + lilv_world_load_bundle(world, bundle_uri); + + // Check that plugin is present + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + assert(plug); + + // Check that plugin name is correct + LilvNode* name = lilv_plugin_get_name(plug); + assert(!strcmp(lilv_node_as_string(name), "First name")); + lilv_node_free(name); + + // Unload bundle from world and delete it + lilv_world_unload_bundle(world, bundle_uri); + delete_bundle(env); + + // Create a new version of the same bundle, but with a different name + create_bundle(env, + ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT + "> ; rdfs:seeAlso <plugin.ttl> .\n", + ":plug a lv2:Plugin ; " + "doap:name \"Second name\" ."); + + // Check that plugin is no longer in the world's plugin list + assert(lilv_plugins_size(plugins) == 0); + + // Load new bundle + lilv_world_load_bundle(world, bundle_uri); + + // Check that plugin is present again and is the same LilvPlugin + const LilvPlugin* plug2 = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + assert(plug2); + assert(plug2 == plug); + + // Check that plugin now has new name + LilvNode* name2 = lilv_plugin_get_name(plug2); + assert(name2); + assert(!strcmp(lilv_node_as_string(name2), "Second name")); + lilv_node_free(name2); + + // Load new bundle again (noop) + lilv_world_load_bundle(world, bundle_uri); + + lilv_node_free(bundle_uri); + delete_bundle(env); + lilv_test_env_free(env); + + return 0; } diff --git a/test/test_replace_version.c b/test/test_replace_version.c index a686572..66b690d 100644 --- a/test/test_replace_version.c +++ b/test/test_replace_version.c @@ -30,76 +30,76 @@ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; - - LilvNode* plug_uri = lilv_new_uri(world, "http://example.org/versioned"); - LilvNode* lv2_minorVersion = lilv_new_uri(world, LV2_CORE__minorVersion); - LilvNode* lv2_microVersion = lilv_new_uri(world, LV2_CORE__microVersion); - LilvNode* minor = NULL; - LilvNode* micro = NULL; - - char* old_bundle_path = lilv_strjoin(LILV_TEST_DIR, "old_version.lv2/", 0); - - // Load plugin from old bundle - LilvNode* old_bundle = lilv_new_file_uri(world, NULL, old_bundle_path); - lilv_world_load_bundle(world, old_bundle); - lilv_world_load_resource(world, plug_uri); - - // Check version - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* old_plug = lilv_plugins_get_by_uri(plugins, plug_uri); - assert(old_plug); - minor = lilv_world_get(world, plug_uri, lv2_minorVersion, 0); - micro = lilv_world_get(world, plug_uri, lv2_microVersion, 0); - assert(!strcmp(lilv_node_as_string(minor), "1")); - assert(!strcmp(lilv_node_as_string(micro), "0")); - lilv_node_free(micro); - lilv_node_free(minor); - - char* new_bundle_path = lilv_strjoin(LILV_TEST_DIR, "new_version.lv2/", 0); - - // Load plugin from new bundle - LilvNode* new_bundle = lilv_new_file_uri(world, NULL, new_bundle_path); - lilv_world_load_bundle(world, new_bundle); - lilv_world_load_resource(world, plug_uri); - - // Check that version in the world model has changed - plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* new_plug = lilv_plugins_get_by_uri(plugins, plug_uri); - assert(new_plug); - assert(lilv_node_equals(lilv_plugin_get_bundle_uri(new_plug), new_bundle)); - minor = lilv_world_get(world, plug_uri, lv2_minorVersion, 0); - micro = lilv_world_get(world, plug_uri, lv2_microVersion, 0); - assert(!strcmp(lilv_node_as_string(minor), "2")); - assert(!strcmp(lilv_node_as_string(micro), "1")); - lilv_node_free(micro); - lilv_node_free(minor); - - // Try to load the old version again - lilv_world_load_bundle(world, old_bundle); - lilv_world_load_resource(world, plug_uri); - - // Check that version in the world model has not changed - plugins = lilv_world_get_all_plugins(world); - new_plug = lilv_plugins_get_by_uri(plugins, plug_uri); - assert(new_plug); - minor = lilv_world_get(world, plug_uri, lv2_minorVersion, 0); - micro = lilv_world_get(world, plug_uri, lv2_microVersion, 0); - assert(!strcmp(lilv_node_as_string(minor), "2")); - assert(!strcmp(lilv_node_as_string(micro), "1")); - lilv_node_free(micro); - lilv_node_free(minor); - - lilv_node_free(new_bundle); - lilv_node_free(old_bundle); - free(new_bundle_path); - free(old_bundle_path); - lilv_node_free(plug_uri); - lilv_node_free(lv2_minorVersion); - lilv_node_free(lv2_microVersion); - - lilv_test_env_free(env); - - return 0; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; + + LilvNode* plug_uri = lilv_new_uri(world, "http://example.org/versioned"); + LilvNode* lv2_minorVersion = lilv_new_uri(world, LV2_CORE__minorVersion); + LilvNode* lv2_microVersion = lilv_new_uri(world, LV2_CORE__microVersion); + LilvNode* minor = NULL; + LilvNode* micro = NULL; + + char* old_bundle_path = lilv_strjoin(LILV_TEST_DIR, "old_version.lv2/", 0); + + // Load plugin from old bundle + LilvNode* old_bundle = lilv_new_file_uri(world, NULL, old_bundle_path); + lilv_world_load_bundle(world, old_bundle); + lilv_world_load_resource(world, plug_uri); + + // Check version + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* old_plug = lilv_plugins_get_by_uri(plugins, plug_uri); + assert(old_plug); + minor = lilv_world_get(world, plug_uri, lv2_minorVersion, 0); + micro = lilv_world_get(world, plug_uri, lv2_microVersion, 0); + assert(!strcmp(lilv_node_as_string(minor), "1")); + assert(!strcmp(lilv_node_as_string(micro), "0")); + lilv_node_free(micro); + lilv_node_free(minor); + + char* new_bundle_path = lilv_strjoin(LILV_TEST_DIR, "new_version.lv2/", 0); + + // Load plugin from new bundle + LilvNode* new_bundle = lilv_new_file_uri(world, NULL, new_bundle_path); + lilv_world_load_bundle(world, new_bundle); + lilv_world_load_resource(world, plug_uri); + + // Check that version in the world model has changed + plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* new_plug = lilv_plugins_get_by_uri(plugins, plug_uri); + assert(new_plug); + assert(lilv_node_equals(lilv_plugin_get_bundle_uri(new_plug), new_bundle)); + minor = lilv_world_get(world, plug_uri, lv2_minorVersion, 0); + micro = lilv_world_get(world, plug_uri, lv2_microVersion, 0); + assert(!strcmp(lilv_node_as_string(minor), "2")); + assert(!strcmp(lilv_node_as_string(micro), "1")); + lilv_node_free(micro); + lilv_node_free(minor); + + // Try to load the old version again + lilv_world_load_bundle(world, old_bundle); + lilv_world_load_resource(world, plug_uri); + + // Check that version in the world model has not changed + plugins = lilv_world_get_all_plugins(world); + new_plug = lilv_plugins_get_by_uri(plugins, plug_uri); + assert(new_plug); + minor = lilv_world_get(world, plug_uri, lv2_minorVersion, 0); + micro = lilv_world_get(world, plug_uri, lv2_microVersion, 0); + assert(!strcmp(lilv_node_as_string(minor), "2")); + assert(!strcmp(lilv_node_as_string(micro), "1")); + lilv_node_free(micro); + lilv_node_free(minor); + + lilv_node_free(new_bundle); + lilv_node_free(old_bundle); + free(new_bundle_path); + free(old_bundle_path); + lilv_node_free(plug_uri); + lilv_node_free(lv2_minorVersion); + lilv_node_free(lv2_microVersion); + + lilv_test_env_free(env); + + return 0; } diff --git a/test/test_state.c b/test/test_state.c index dffacee..24106ac 100644 --- a/test/test_state.c +++ b/test/test_state.c @@ -28,10 +28,10 @@ #include "serd/serd.h" #ifdef _WIN32 -# include <direct.h> -# define mkdir(path, flags) _mkdir(path) +# include <direct.h> +# define mkdir(path, flags) _mkdir(path) #else -# include <sys/stat.h> +# include <sys/stat.h> #endif #include <assert.h> @@ -43,143 +43,141 @@ #define TEST_PLUGIN_URI "http://example.org/lilv-test-plugin" -typedef struct -{ - LilvTestEnv* env; - LilvTestUriMap uri_map; - LV2_URID_Map map; - LV2_Feature map_feature; - LV2_URID_Unmap unmap; - LV2_Feature unmap_feature; - LV2_State_Free_Path free_path; - LV2_Feature free_path_feature; - const LV2_Feature* features[4]; - LV2_URID atom_Float; - float in; - float out; - float control; +typedef struct { + LilvTestEnv* env; + LilvTestUriMap uri_map; + LV2_URID_Map map; + LV2_Feature map_feature; + LV2_URID_Unmap unmap; + LV2_Feature unmap_feature; + LV2_State_Free_Path free_path; + LV2_Feature free_path_feature; + const LV2_Feature* features[4]; + LV2_URID atom_Float; + float in; + float out; + float control; } TestContext; -typedef struct -{ - char* top; ///< Temporary directory that contains everything - char* shared; ///< Common parent for shared directoryes (top/shared) - char* scratch; ///< Scratch file directory (top/shared/scratch) - char* copy; ///< Copy directory (top/shared/scratch) - char* link; ///< Link directory (top/shared/scratch) +typedef struct { + char* top; ///< Temporary directory that contains everything + char* shared; ///< Common parent for shared directoryes (top/shared) + char* scratch; ///< Scratch file directory (top/shared/scratch) + char* copy; ///< Copy directory (top/shared/scratch) + char* link; ///< Link directory (top/shared/scratch) } TestDirectories; static void lilv_free_path(LV2_State_Free_Path_Handle handle, char* path) { - (void)handle; + (void)handle; - lilv_free(path); + lilv_free(path); } static TestContext* test_context_new(void) { - TestContext* ctx = (TestContext*)calloc(1, sizeof(TestContext)); - - lilv_test_uri_map_init(&ctx->uri_map); - - ctx->env = lilv_test_env_new(); - ctx->map.handle = &ctx->uri_map; - ctx->map.map = map_uri; - ctx->map_feature.URI = LV2_URID_MAP_URI; - ctx->map_feature.data = &ctx->map; - ctx->unmap.handle = &ctx->uri_map; - ctx->unmap.unmap = unmap_uri; - ctx->unmap_feature.URI = LV2_URID_UNMAP_URI; - ctx->unmap_feature.data = &ctx->unmap; - ctx->free_path.free_path = lilv_free_path; - ctx->free_path_feature.URI = LV2_STATE__freePath; - ctx->free_path_feature.data = &ctx->free_path; - ctx->features[0] = &ctx->map_feature; - ctx->features[1] = &ctx->unmap_feature; - ctx->features[2] = &ctx->free_path_feature; - ctx->features[3] = NULL; - - ctx->atom_Float = - map_uri(&ctx->uri_map, "http://lv2plug.in/ns/ext/atom#Float"); - - ctx->in = 1.0; - ctx->out = 42.0; - ctx->control = 1234.0; - - return ctx; + TestContext* ctx = (TestContext*)calloc(1, sizeof(TestContext)); + + lilv_test_uri_map_init(&ctx->uri_map); + + ctx->env = lilv_test_env_new(); + ctx->map.handle = &ctx->uri_map; + ctx->map.map = map_uri; + ctx->map_feature.URI = LV2_URID_MAP_URI; + ctx->map_feature.data = &ctx->map; + ctx->unmap.handle = &ctx->uri_map; + ctx->unmap.unmap = unmap_uri; + ctx->unmap_feature.URI = LV2_URID_UNMAP_URI; + ctx->unmap_feature.data = &ctx->unmap; + ctx->free_path.free_path = lilv_free_path; + ctx->free_path_feature.URI = LV2_STATE__freePath; + ctx->free_path_feature.data = &ctx->free_path; + ctx->features[0] = &ctx->map_feature; + ctx->features[1] = &ctx->unmap_feature; + ctx->features[2] = &ctx->free_path_feature; + ctx->features[3] = NULL; + + ctx->atom_Float = + map_uri(&ctx->uri_map, "http://lv2plug.in/ns/ext/atom#Float"); + + ctx->in = 1.0; + ctx->out = 42.0; + ctx->control = 1234.0; + + return ctx; } static void test_context_free(TestContext* ctx) { - lilv_test_uri_map_clear(&ctx->uri_map); - lilv_test_env_free(ctx->env); - free(ctx); + lilv_test_uri_map_clear(&ctx->uri_map); + lilv_test_env_free(ctx->env); + free(ctx); } static TestDirectories create_test_directories(void) { - TestDirectories dirs; + TestDirectories dirs; - char* const top = lilv_create_temporary_directory("lilv_XXXXXX"); - assert(top); + char* const top = lilv_create_temporary_directory("lilv_XXXXXX"); + assert(top); - /* On MacOS, temporary directories from mkdtemp involve symlinks, so - resolve it here so that path comparisons in tests work. */ + /* 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.shared = lilv_path_join(dirs.top, "shared"); - dirs.scratch = lilv_path_join(dirs.shared, "scratch"); - dirs.copy = lilv_path_join(dirs.shared, "copy"); - dirs.link = lilv_path_join(dirs.shared, "link"); + dirs.top = lilv_path_canonical(top); + dirs.shared = lilv_path_join(dirs.top, "shared"); + dirs.scratch = lilv_path_join(dirs.shared, "scratch"); + dirs.copy = lilv_path_join(dirs.shared, "copy"); + dirs.link = lilv_path_join(dirs.shared, "link"); - assert(!mkdir(dirs.shared, 0700)); - assert(!mkdir(dirs.scratch, 0700)); - assert(!mkdir(dirs.copy, 0700)); - assert(!mkdir(dirs.link, 0700)); + assert(!mkdir(dirs.shared, 0700)); + assert(!mkdir(dirs.scratch, 0700)); + assert(!mkdir(dirs.copy, 0700)); + assert(!mkdir(dirs.link, 0700)); - free(top); + free(top); - return dirs; + return dirs; } static TestDirectories no_test_directories(void) { - TestDirectories dirs = {NULL, NULL, NULL, NULL, NULL}; + TestDirectories dirs = {NULL, NULL, NULL, NULL, NULL}; - return dirs; + return dirs; } static void remove_file(const char* path, const char* name, void* data) { - char* const full_path = lilv_path_join(path, name); - assert(!lilv_remove(full_path)); - free(full_path); + char* const full_path = lilv_path_join(path, name); + assert(!lilv_remove(full_path)); + free(full_path); } static void cleanup_test_directories(const TestDirectories dirs) { - lilv_dir_for_each(dirs.scratch, NULL, remove_file); - lilv_dir_for_each(dirs.copy, NULL, remove_file); - lilv_dir_for_each(dirs.link, NULL, remove_file); - - assert(!lilv_remove(dirs.link)); - assert(!lilv_remove(dirs.copy)); - assert(!lilv_remove(dirs.scratch)); - assert(!lilv_remove(dirs.shared)); - assert(!lilv_remove(dirs.top)); - - free(dirs.link); - free(dirs.copy); - free(dirs.scratch); - free(dirs.shared); - free(dirs.top); + lilv_dir_for_each(dirs.scratch, NULL, remove_file); + lilv_dir_for_each(dirs.copy, NULL, remove_file); + lilv_dir_for_each(dirs.link, NULL, remove_file); + + assert(!lilv_remove(dirs.link)); + assert(!lilv_remove(dirs.copy)); + assert(!lilv_remove(dirs.scratch)); + assert(!lilv_remove(dirs.shared)); + assert(!lilv_remove(dirs.top)); + + free(dirs.link); + free(dirs.copy); + free(dirs.scratch); + free(dirs.shared); + free(dirs.top); } static const void* @@ -188,27 +186,26 @@ get_port_value(const char* port_symbol, uint32_t* size, uint32_t* type) { - TestContext* ctx = (TestContext*)user_data; - - if (!strcmp(port_symbol, "input")) { - *size = sizeof(float); - *type = ctx->atom_Float; - return &ctx->in; - } else if (!strcmp(port_symbol, "output")) { - *size = sizeof(float); - *type = ctx->atom_Float; - return &ctx->out; - } else if (!strcmp(port_symbol, "control")) { - *size = sizeof(float); - *type = ctx->atom_Float; - return &ctx->control; - } else { - fprintf(stderr, - "error: get_port_value for nonexistent port `%s'\n", - port_symbol); - *size = *type = 0; - return NULL; - } + TestContext* ctx = (TestContext*)user_data; + + if (!strcmp(port_symbol, "input")) { + *size = sizeof(float); + *type = ctx->atom_Float; + return &ctx->in; + } else if (!strcmp(port_symbol, "output")) { + *size = sizeof(float); + *type = ctx->atom_Float; + return &ctx->out; + } else if (!strcmp(port_symbol, "control")) { + *size = sizeof(float); + *type = ctx->atom_Float; + return &ctx->control; + } else { + fprintf( + stderr, "error: get_port_value for nonexistent port `%s'\n", port_symbol); + *size = *type = 0; + return NULL; + } } static void @@ -218,50 +215,49 @@ set_port_value(const char* port_symbol, uint32_t size, uint32_t type) { - TestContext* ctx = (TestContext*)user_data; - - if (!strcmp(port_symbol, "input")) { - ctx->in = *(const float*)value; - } else if (!strcmp(port_symbol, "output")) { - ctx->out = *(const float*)value; - } else if (!strcmp(port_symbol, "control")) { - ctx->control = *(const float*)value; - } else { - fprintf(stderr, - "error: set_port_value for nonexistent port `%s'\n", - port_symbol); - } + TestContext* ctx = (TestContext*)user_data; + + if (!strcmp(port_symbol, "input")) { + ctx->in = *(const float*)value; + } else if (!strcmp(port_symbol, "output")) { + ctx->out = *(const float*)value; + } else if (!strcmp(port_symbol, "control")) { + ctx->control = *(const float*)value; + } else { + fprintf( + stderr, "error: set_port_value for nonexistent port `%s'\n", port_symbol); + } } static char* make_scratch_path(LV2_State_Make_Path_Handle handle, const char* path) { - TestDirectories* dirs = (TestDirectories*)handle; + TestDirectories* dirs = (TestDirectories*)handle; - return lilv_path_join(dirs->scratch, path); + return lilv_path_join(dirs->scratch, path); } static const LilvPlugin* load_test_plugin(const TestContext* const ctx) { - LilvWorld* world = ctx->env->world; - uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(LILV_TEST_BUNDLE); - SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); - LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); - LilvNode* plugin_uri = lilv_new_uri(world, TEST_PLUGIN_URI); + LilvWorld* world = ctx->env->world; + uint8_t* abs_bundle = (uint8_t*)lilv_path_absolute(LILV_TEST_BUNDLE); + SerdNode bundle = serd_node_new_file_uri(abs_bundle, 0, 0, true); + LilvNode* bundle_uri = lilv_new_uri(world, (const char*)bundle.buf); + LilvNode* plugin_uri = lilv_new_uri(world, TEST_PLUGIN_URI); - lilv_world_load_bundle(world, bundle_uri); + lilv_world_load_bundle(world, bundle_uri); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, plugin_uri); - lilv_node_free(plugin_uri); - lilv_node_free(bundle_uri); - serd_node_free(&bundle); - free(abs_bundle); + lilv_node_free(plugin_uri); + lilv_node_free(bundle_uri); + serd_node_free(&bundle); + free(abs_bundle); - assert(plugin); - return plugin; + assert(plugin); + return plugin; } static LilvState* @@ -271,262 +267,262 @@ state_from_instance(const LilvPlugin* const plugin, const TestDirectories* const dirs, const char* const bundle_path) { - return lilv_state_new_from_instance(plugin, - instance, - &ctx->map, - dirs->scratch, - dirs->copy, - dirs->link, - bundle_path, - get_port_value, - ctx, - 0, - NULL); + return lilv_state_new_from_instance(plugin, + instance, + &ctx->map, + dirs->scratch, + dirs->copy, + dirs->link, + bundle_path, + get_port_value, + ctx, + 0, + NULL); } static void test_instance_state(void) { - TestContext* const ctx = test_context_new(); - const TestDirectories dirs = no_test_directories(); - const LilvPlugin* const plugin = load_test_plugin(ctx); - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, ctx->features); + TestContext* const ctx = test_context_new(); + const TestDirectories dirs = no_test_directories(); + const LilvPlugin* const plugin = load_test_plugin(ctx); + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, ctx->features); - assert(instance); + assert(instance); - // Get instance state - LilvState* const state = - state_from_instance(plugin, instance, ctx, &dirs, NULL); + // Get instance state + LilvState* const state = + state_from_instance(plugin, instance, ctx, &dirs, NULL); - // Check that state contains properties saved by the plugin - assert(lilv_state_get_num_properties(state) == 8); + // Check that state contains properties saved by the plugin + assert(lilv_state_get_num_properties(state) == 8); - // Check that state has no URI - assert(!lilv_state_get_uri(state)); + // Check that state has no URI + assert(!lilv_state_get_uri(state)); - // Check that state can't be saved without a URI - assert(!lilv_state_to_string( - ctx->env->world, &ctx->map, &ctx->unmap, state, NULL, NULL)); + // Check that state can't be saved without a URI + assert(!lilv_state_to_string( + ctx->env->world, &ctx->map, &ctx->unmap, state, NULL, NULL)); - // Check that we can't delete unsaved state - assert(lilv_state_delete(ctx->env->world, state)); + // Check that we can't delete unsaved state + assert(lilv_state_delete(ctx->env->world, state)); - lilv_state_free(state); - lilv_instance_free(instance); - test_context_free(ctx); + lilv_state_free(state); + lilv_instance_free(instance); + test_context_free(ctx); } static void test_equal(void) { - TestContext* const ctx = test_context_new(); - const TestDirectories dirs = no_test_directories(); - const LilvPlugin* const plugin = load_test_plugin(ctx); - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, ctx->features); + TestContext* const ctx = test_context_new(); + const TestDirectories dirs = no_test_directories(); + const LilvPlugin* const plugin = load_test_plugin(ctx); + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, ctx->features); - assert(instance); + assert(instance); - // Get instance state - LilvState* const state_1 = - state_from_instance(plugin, instance, ctx, &dirs, NULL); + // Get instance state + LilvState* const state_1 = + state_from_instance(plugin, instance, ctx, &dirs, NULL); - // Get another instance state - LilvState* const state_2 = - state_from_instance(plugin, instance, ctx, &dirs, NULL); + // Get another instance state + LilvState* const state_2 = + state_from_instance(plugin, instance, ctx, &dirs, NULL); - // Ensure they are equal - assert(lilv_state_equals(state_1, state_2)); + // Ensure they are equal + assert(lilv_state_equals(state_1, state_2)); - // Set a label on the second state - assert(lilv_state_get_label(state_2) == NULL); - lilv_state_set_label(state_2, "Test State Old Label"); + // Set a label on the second state + assert(lilv_state_get_label(state_2) == NULL); + lilv_state_set_label(state_2, "Test State Old Label"); - // Ensure they are no longer equal - assert(!lilv_state_equals(state_1, state_2)); + // Ensure they are no longer equal + assert(!lilv_state_equals(state_1, state_2)); - lilv_state_free(state_2); - lilv_state_free(state_1); - lilv_instance_free(instance); - test_context_free(ctx); + lilv_state_free(state_2); + lilv_state_free(state_1); + lilv_instance_free(instance); + test_context_free(ctx); } static void test_changed_plugin_data(void) { - TestContext* const ctx = test_context_new(); - const TestDirectories dirs = no_test_directories(); - const LilvPlugin* const plugin = load_test_plugin(ctx); - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, ctx->features); - - assert(instance); - - // Get initial state - LilvState* const initial_state = - state_from_instance(plugin, instance, ctx, &dirs, NULL); - - // Run plugin to change internal state - lilv_instance_activate(instance); - lilv_instance_connect_port(instance, 0, &ctx->in); - lilv_instance_connect_port(instance, 1, &ctx->out); - lilv_instance_run(instance, 1); - assert(ctx->in == 1.0); - assert(ctx->out == 1.0); - - // Get a new instance state (which should now differ) - LilvState* const changed_state = - state_from_instance(plugin, instance, ctx, &dirs, NULL); - - // Ensure state has changed - assert(!lilv_state_equals(initial_state, changed_state)); - - lilv_state_free(changed_state); - lilv_state_free(initial_state); - lilv_instance_free(instance); - test_context_free(ctx); + TestContext* const ctx = test_context_new(); + const TestDirectories dirs = no_test_directories(); + const LilvPlugin* const plugin = load_test_plugin(ctx); + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, ctx->features); + + assert(instance); + + // Get initial state + LilvState* const initial_state = + state_from_instance(plugin, instance, ctx, &dirs, NULL); + + // Run plugin to change internal state + lilv_instance_activate(instance); + lilv_instance_connect_port(instance, 0, &ctx->in); + lilv_instance_connect_port(instance, 1, &ctx->out); + lilv_instance_run(instance, 1); + assert(ctx->in == 1.0); + assert(ctx->out == 1.0); + + // Get a new instance state (which should now differ) + LilvState* const changed_state = + state_from_instance(plugin, instance, ctx, &dirs, NULL); + + // Ensure state has changed + assert(!lilv_state_equals(initial_state, changed_state)); + + lilv_state_free(changed_state); + lilv_state_free(initial_state); + lilv_instance_free(instance); + test_context_free(ctx); } static void test_changed_metadata(void) { - TestContext* const ctx = test_context_new(); - const TestDirectories dirs = no_test_directories(); - LV2_URID_Map* const map = &ctx->map; - const LilvPlugin* const plugin = load_test_plugin(ctx); - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, ctx->features); - - assert(instance); - - // Get initial state - LilvState* const initial_state = - state_from_instance(plugin, instance, ctx, &dirs, NULL); - - // Save initial state to a string - char* const initial_string = - lilv_state_to_string(ctx->env->world, - &ctx->map, - &ctx->unmap, - initial_state, - "http://example.org/initial", - NULL); - - // Get another state - LilvState* const changed_state = - state_from_instance(plugin, instance, ctx, &dirs, NULL); - - // Set a metadata property - const LV2_URID key = map->map(map->handle, "http://example.org/extra"); - const int32_t value = 1; - const LV2_URID type = - map->map(map->handle, "http://lv2plug.in/ns/ext/atom#Int"); - lilv_state_set_metadata(changed_state, - key, - &value, - sizeof(value), - type, - LV2_STATE_IS_PORTABLE | LV2_STATE_IS_POD); - - // Save changed state to a string - char* const changed_string = - lilv_state_to_string(ctx->env->world, - &ctx->map, - &ctx->unmap, - changed_state, - "http://example.org/changed", - NULL); - - // Ensure that strings differ (metadata does not affect state equality) - assert(strcmp(initial_string, changed_string)); - - free(changed_string); - lilv_state_free(changed_state); - free(initial_string); - lilv_state_free(initial_state); - lilv_instance_free(instance); - test_context_free(ctx); + TestContext* const ctx = test_context_new(); + const TestDirectories dirs = no_test_directories(); + LV2_URID_Map* const map = &ctx->map; + const LilvPlugin* const plugin = load_test_plugin(ctx); + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, ctx->features); + + assert(instance); + + // Get initial state + LilvState* const initial_state = + state_from_instance(plugin, instance, ctx, &dirs, NULL); + + // Save initial state to a string + char* const initial_string = + lilv_state_to_string(ctx->env->world, + &ctx->map, + &ctx->unmap, + initial_state, + "http://example.org/initial", + NULL); + + // Get another state + LilvState* const changed_state = + state_from_instance(plugin, instance, ctx, &dirs, NULL); + + // Set a metadata property + const LV2_URID key = map->map(map->handle, "http://example.org/extra"); + const int32_t value = 1; + const LV2_URID type = + map->map(map->handle, "http://lv2plug.in/ns/ext/atom#Int"); + lilv_state_set_metadata(changed_state, + key, + &value, + sizeof(value), + type, + LV2_STATE_IS_PORTABLE | LV2_STATE_IS_POD); + + // Save changed state to a string + char* const changed_string = + lilv_state_to_string(ctx->env->world, + &ctx->map, + &ctx->unmap, + changed_state, + "http://example.org/changed", + NULL); + + // Ensure that strings differ (metadata does not affect state equality) + assert(strcmp(initial_string, changed_string)); + + free(changed_string); + lilv_state_free(changed_state); + free(initial_string); + lilv_state_free(initial_state); + lilv_instance_free(instance); + test_context_free(ctx); } static void test_to_string(void) { - TestContext* const ctx = test_context_new(); - const TestDirectories dirs = no_test_directories(); - const LilvPlugin* const plugin = load_test_plugin(ctx); - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, ctx->features); - - assert(instance); - - // Get initial state - LilvState* const initial_state = - state_from_instance(plugin, instance, ctx, &dirs, NULL); - - // Run plugin to change internal state - lilv_instance_activate(instance); - lilv_instance_connect_port(instance, 0, &ctx->in); - lilv_instance_connect_port(instance, 1, &ctx->out); - lilv_instance_run(instance, 1); - assert(ctx->in == 1.0); - assert(ctx->out == 1.0); - - // Restore instance state to original state - lilv_state_restore(initial_state, instance, set_port_value, ctx, 0, NULL); - - // Take a new snapshot of the state - LilvState* const restored = - state_from_instance(plugin, instance, ctx, &dirs, NULL); - - // Check that new state matches the initial state - assert(lilv_state_equals(initial_state, restored)); - - lilv_state_free(restored); - lilv_state_free(initial_state); - lilv_instance_free(instance); - test_context_free(ctx); + TestContext* const ctx = test_context_new(); + const TestDirectories dirs = no_test_directories(); + const LilvPlugin* const plugin = load_test_plugin(ctx); + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, ctx->features); + + assert(instance); + + // Get initial state + LilvState* const initial_state = + state_from_instance(plugin, instance, ctx, &dirs, NULL); + + // Run plugin to change internal state + lilv_instance_activate(instance); + lilv_instance_connect_port(instance, 0, &ctx->in); + lilv_instance_connect_port(instance, 1, &ctx->out); + lilv_instance_run(instance, 1); + assert(ctx->in == 1.0); + assert(ctx->out == 1.0); + + // Restore instance state to original state + lilv_state_restore(initial_state, instance, set_port_value, ctx, 0, NULL); + + // Take a new snapshot of the state + LilvState* const restored = + state_from_instance(plugin, instance, ctx, &dirs, NULL); + + // Check that new state matches the initial state + assert(lilv_state_equals(initial_state, restored)); + + lilv_state_free(restored); + lilv_state_free(initial_state); + lilv_instance_free(instance); + test_context_free(ctx); } static void test_string_round_trip(void) { - TestContext* const ctx = test_context_new(); - const TestDirectories dirs = no_test_directories(); - const LilvPlugin* const plugin = load_test_plugin(ctx); - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, ctx->features); - - assert(instance); - - // Get initial state - LilvState* const initial_state = - state_from_instance(plugin, instance, ctx, &dirs, NULL); - - // Save state to a string - char* const string = lilv_state_to_string(ctx->env->world, - &ctx->map, - &ctx->unmap, - initial_state, - "http://example.org/string", - NULL); - - // Restore from string - LilvState* const restored = - lilv_state_new_from_string(ctx->env->world, &ctx->map, string); - - // Ensure they are equal - assert(lilv_state_equals(initial_state, restored)); - - // Check that the restored state refers to the correct plugin - const LilvNode* state_plugin_uri = lilv_state_get_plugin_uri(restored); - assert(!strcmp(lilv_node_as_string(state_plugin_uri), TEST_PLUGIN_URI)); - - lilv_state_free(restored); - free(string); - lilv_state_free(initial_state); - lilv_instance_free(instance); - test_context_free(ctx); + TestContext* const ctx = test_context_new(); + const TestDirectories dirs = no_test_directories(); + const LilvPlugin* const plugin = load_test_plugin(ctx); + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, ctx->features); + + assert(instance); + + // Get initial state + LilvState* const initial_state = + state_from_instance(plugin, instance, ctx, &dirs, NULL); + + // Save state to a string + char* const string = lilv_state_to_string(ctx->env->world, + &ctx->map, + &ctx->unmap, + initial_state, + "http://example.org/string", + NULL); + + // Restore from string + LilvState* const restored = + lilv_state_new_from_string(ctx->env->world, &ctx->map, string); + + // Ensure they are equal + assert(lilv_state_equals(initial_state, restored)); + + // Check that the restored state refers to the correct plugin + const LilvNode* state_plugin_uri = lilv_state_get_plugin_uri(restored); + assert(!strcmp(lilv_node_as_string(state_plugin_uri), TEST_PLUGIN_URI)); + + lilv_state_free(restored); + free(string); + lilv_state_free(initial_state); + lilv_instance_free(instance); + test_context_free(ctx); } static SerdStatus @@ -539,582 +535,563 @@ count_sink(void* const handle, const SerdNode* const object_datatype, const SerdNode* const object_lang) { - size_t* const n_statements = (size_t*)handle; + size_t* const n_statements = (size_t*)handle; - ++(*n_statements); + ++(*n_statements); - return SERD_SUCCESS; + return SERD_SUCCESS; } static size_t count_statements(const char* path) { - size_t n_statements = 0; + size_t n_statements = 0; - SerdReader* reader = serd_reader_new( - SERD_TURTLE, &n_statements, NULL, NULL, NULL, count_sink, NULL); + SerdReader* reader = serd_reader_new( + SERD_TURTLE, &n_statements, NULL, NULL, NULL, count_sink, NULL); - SerdNode uri = - serd_node_new_file_uri((const uint8_t*)path, NULL, NULL, true); + SerdNode uri = serd_node_new_file_uri((const uint8_t*)path, NULL, NULL, true); - assert(!serd_reader_read_file(reader, uri.buf)); + assert(!serd_reader_read_file(reader, uri.buf)); - serd_node_free(&uri); - serd_reader_free(reader); + serd_node_free(&uri); + serd_reader_free(reader); - return n_statements; + return n_statements; } static void test_to_files(void) { - TestContext* const ctx = test_context_new(); - TestDirectories dirs = create_test_directories(); - const LilvPlugin* const plugin = load_test_plugin(ctx); - - LV2_State_Make_Path make_path = {&dirs, make_scratch_path}; - LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path}; - - const LV2_Feature* const instance_features[] = {&ctx->map_feature, - &ctx->free_path_feature, - &make_path_feature, - NULL}; - - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, instance_features); - - assert(instance); - - // Run plugin to generate some recording file data - lilv_instance_activate(instance); - lilv_instance_connect_port(instance, 0, &ctx->in); - lilv_instance_connect_port(instance, 1, &ctx->out); - lilv_instance_run(instance, 1); - lilv_instance_run(instance, 2); - assert(ctx->in == 1.0); - assert(ctx->out == 1.0); - - // Check that the test plugin has made its recording scratch file - char* const recfile_path = lilv_path_join(dirs.scratch, "recfile"); - assert(lilv_path_exists(recfile_path)); - - // Get state - char* const bundle_1_path = lilv_path_join(dirs.top, "state1.lv2"); - LilvState* const state_1 = - state_from_instance(plugin, instance, ctx, &dirs, bundle_1_path); - - // Check that state contains properties saved by the plugin (with files) - assert(lilv_state_get_num_properties(state_1) == 10); - - // Check that a snapshop of the recfile was created - char* const recfile_copy_1 = lilv_path_join(dirs.copy, "recfile"); - assert(lilv_path_exists(recfile_copy_1)); - - // Save state to a bundle - assert(!lilv_state_save(ctx->env->world, - &ctx->map, - &ctx->unmap, - state_1, - "http://example.org/state1", - bundle_1_path, - "state.ttl")); - - // Check that a manifest exists - char* const manifest_path = lilv_path_join(bundle_1_path, "manifest.ttl"); - assert(lilv_path_exists(manifest_path)); - - // Check that the expected statements are in the manifest file - assert(count_statements(manifest_path) == 3); - - // Check that a link to the recfile exists in the saved bundle - char* const recfile_link_1 = lilv_path_join(bundle_1_path, "recfile"); - assert(lilv_path_exists(recfile_link_1)); - - // Check that link points to the corresponding copy - assert(lilv_file_equals(recfile_link_1, recfile_copy_1)); - - // Run plugin again to modify recording file data - lilv_instance_run(instance, 2); - - // Get updated state - char* const bundle_2_path = lilv_path_join(dirs.top, "state2.lv2"); - LilvState* const state_2 = - state_from_instance(plugin, instance, ctx, &dirs, bundle_2_path); - - // Save updated state to a bundle - assert(!lilv_state_save(ctx->env->world, - &ctx->map, - &ctx->unmap, - state_2, - NULL, - bundle_2_path, - "state.ttl")); - - // Check that a new snapshop of the recfile was created - char* const recfile_copy_2 = lilv_path_join(dirs.copy, "recfile.2"); - assert(lilv_path_exists(recfile_copy_2)); - - // Check that a link to the recfile exists in the updated bundle - char* const recfile_link_2 = lilv_path_join(bundle_2_path, "recfile"); - assert(lilv_path_exists(recfile_link_2)); - - // Check that link points to the corresponding copy - assert(lilv_file_equals(recfile_link_2, recfile_copy_2)); - - lilv_instance_free(instance); - lilv_dir_for_each(bundle_2_path, NULL, remove_file); - lilv_dir_for_each(bundle_1_path, NULL, remove_file); - assert(!lilv_remove(bundle_2_path)); - assert(!lilv_remove(bundle_1_path)); - cleanup_test_directories(dirs); - - free(recfile_link_2); - free(recfile_copy_2); - lilv_state_free(state_2); - free(bundle_2_path); - free(recfile_link_1); - free(manifest_path); - free(recfile_copy_1); - lilv_state_free(state_1); - free(bundle_1_path); - free(recfile_path); - test_context_free(ctx); + TestContext* const ctx = test_context_new(); + TestDirectories dirs = create_test_directories(); + const LilvPlugin* const plugin = load_test_plugin(ctx); + + LV2_State_Make_Path make_path = {&dirs, make_scratch_path}; + LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path}; + + const LV2_Feature* const instance_features[] = { + &ctx->map_feature, &ctx->free_path_feature, &make_path_feature, NULL}; + + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, instance_features); + + assert(instance); + + // Run plugin to generate some recording file data + lilv_instance_activate(instance); + lilv_instance_connect_port(instance, 0, &ctx->in); + lilv_instance_connect_port(instance, 1, &ctx->out); + lilv_instance_run(instance, 1); + lilv_instance_run(instance, 2); + assert(ctx->in == 1.0); + assert(ctx->out == 1.0); + + // Check that the test plugin has made its recording scratch file + char* const recfile_path = lilv_path_join(dirs.scratch, "recfile"); + assert(lilv_path_exists(recfile_path)); + + // Get state + char* const bundle_1_path = lilv_path_join(dirs.top, "state1.lv2"); + LilvState* const state_1 = + state_from_instance(plugin, instance, ctx, &dirs, bundle_1_path); + + // Check that state contains properties saved by the plugin (with files) + assert(lilv_state_get_num_properties(state_1) == 10); + + // Check that a snapshop of the recfile was created + char* const recfile_copy_1 = lilv_path_join(dirs.copy, "recfile"); + assert(lilv_path_exists(recfile_copy_1)); + + // Save state to a bundle + assert(!lilv_state_save(ctx->env->world, + &ctx->map, + &ctx->unmap, + state_1, + "http://example.org/state1", + bundle_1_path, + "state.ttl")); + + // Check that a manifest exists + char* const manifest_path = lilv_path_join(bundle_1_path, "manifest.ttl"); + assert(lilv_path_exists(manifest_path)); + + // Check that the expected statements are in the manifest file + assert(count_statements(manifest_path) == 3); + + // Check that a link to the recfile exists in the saved bundle + char* const recfile_link_1 = lilv_path_join(bundle_1_path, "recfile"); + assert(lilv_path_exists(recfile_link_1)); + + // Check that link points to the corresponding copy + assert(lilv_file_equals(recfile_link_1, recfile_copy_1)); + + // Run plugin again to modify recording file data + lilv_instance_run(instance, 2); + + // Get updated state + char* const bundle_2_path = lilv_path_join(dirs.top, "state2.lv2"); + LilvState* const state_2 = + state_from_instance(plugin, instance, ctx, &dirs, bundle_2_path); + + // Save updated state to a bundle + assert(!lilv_state_save(ctx->env->world, + &ctx->map, + &ctx->unmap, + state_2, + NULL, + bundle_2_path, + "state.ttl")); + + // Check that a new snapshop of the recfile was created + char* const recfile_copy_2 = lilv_path_join(dirs.copy, "recfile.2"); + assert(lilv_path_exists(recfile_copy_2)); + + // Check that a link to the recfile exists in the updated bundle + char* const recfile_link_2 = lilv_path_join(bundle_2_path, "recfile"); + assert(lilv_path_exists(recfile_link_2)); + + // Check that link points to the corresponding copy + assert(lilv_file_equals(recfile_link_2, recfile_copy_2)); + + lilv_instance_free(instance); + lilv_dir_for_each(bundle_2_path, NULL, remove_file); + lilv_dir_for_each(bundle_1_path, NULL, remove_file); + assert(!lilv_remove(bundle_2_path)); + assert(!lilv_remove(bundle_1_path)); + cleanup_test_directories(dirs); + + free(recfile_link_2); + free(recfile_copy_2); + lilv_state_free(state_2); + free(bundle_2_path); + free(recfile_link_1); + free(manifest_path); + free(recfile_copy_1); + lilv_state_free(state_1); + free(bundle_1_path); + free(recfile_path); + test_context_free(ctx); } static void test_multi_save(void) { - TestContext* const ctx = test_context_new(); - TestDirectories dirs = create_test_directories(); - const LilvPlugin* const plugin = load_test_plugin(ctx); - - LV2_State_Make_Path make_path = {&dirs, make_scratch_path}; - LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path}; - - const LV2_Feature* const instance_features[] = {&ctx->map_feature, - &ctx->free_path_feature, - &make_path_feature, - NULL}; - - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, instance_features); - - assert(instance); - - // Get state - char* const bundle_1_path = lilv_path_join(dirs.top, "state1.lv2"); - LilvState* const state_1 = - state_from_instance(plugin, instance, ctx, &dirs, bundle_1_path); - - // Save state to a bundle - assert(!lilv_state_save(ctx->env->world, - &ctx->map, - &ctx->unmap, - state_1, - "http://example.org/state1", - bundle_1_path, - "state.ttl")); - - // Check that a manifest exists - char* const manifest_path = lilv_path_join(bundle_1_path, "manifest.ttl"); - assert(lilv_path_exists(manifest_path)); - - // Check that the state file exists - char* const state_path = lilv_path_join(bundle_1_path, "state.ttl"); - assert(lilv_path_exists(state_path)); - - // Check that the expected statements are in the files - assert(count_statements(manifest_path) == 3); - assert(count_statements(state_path) == 21); - - // Save state again to the same bundle - assert(!lilv_state_save(ctx->env->world, - &ctx->map, - &ctx->unmap, - state_1, - "http://example.org/state1", - bundle_1_path, - "state.ttl")); - - // Check that everything is the same - assert(lilv_path_exists(manifest_path)); - assert(lilv_path_exists(state_path)); - assert(count_statements(manifest_path) == 3); - assert(count_statements(state_path) == 21); - - lilv_instance_free(instance); - lilv_dir_for_each(bundle_1_path, NULL, remove_file); - lilv_remove(bundle_1_path); - cleanup_test_directories(dirs); - - free(state_path); - free(manifest_path); - lilv_state_free(state_1); - free(bundle_1_path); - test_context_free(ctx); + TestContext* const ctx = test_context_new(); + TestDirectories dirs = create_test_directories(); + const LilvPlugin* const plugin = load_test_plugin(ctx); + + LV2_State_Make_Path make_path = {&dirs, make_scratch_path}; + LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path}; + + const LV2_Feature* const instance_features[] = { + &ctx->map_feature, &ctx->free_path_feature, &make_path_feature, NULL}; + + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, instance_features); + + assert(instance); + + // Get state + char* const bundle_1_path = lilv_path_join(dirs.top, "state1.lv2"); + LilvState* const state_1 = + state_from_instance(plugin, instance, ctx, &dirs, bundle_1_path); + + // Save state to a bundle + assert(!lilv_state_save(ctx->env->world, + &ctx->map, + &ctx->unmap, + state_1, + "http://example.org/state1", + bundle_1_path, + "state.ttl")); + + // Check that a manifest exists + char* const manifest_path = lilv_path_join(bundle_1_path, "manifest.ttl"); + assert(lilv_path_exists(manifest_path)); + + // Check that the state file exists + char* const state_path = lilv_path_join(bundle_1_path, "state.ttl"); + assert(lilv_path_exists(state_path)); + + // Check that the expected statements are in the files + assert(count_statements(manifest_path) == 3); + assert(count_statements(state_path) == 21); + + // Save state again to the same bundle + assert(!lilv_state_save(ctx->env->world, + &ctx->map, + &ctx->unmap, + state_1, + "http://example.org/state1", + bundle_1_path, + "state.ttl")); + + // Check that everything is the same + assert(lilv_path_exists(manifest_path)); + assert(lilv_path_exists(state_path)); + assert(count_statements(manifest_path) == 3); + assert(count_statements(state_path) == 21); + + lilv_instance_free(instance); + lilv_dir_for_each(bundle_1_path, NULL, remove_file); + lilv_remove(bundle_1_path); + cleanup_test_directories(dirs); + + free(state_path); + free(manifest_path); + lilv_state_free(state_1); + free(bundle_1_path); + test_context_free(ctx); } static void test_files_round_trip(void) { - TestContext* const ctx = test_context_new(); - TestDirectories dirs = create_test_directories(); - const LilvPlugin* const plugin = load_test_plugin(ctx); - - LV2_State_Make_Path make_path = {&dirs, make_scratch_path}; - LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path}; - - const LV2_Feature* const instance_features[] = {&ctx->map_feature, - &ctx->free_path_feature, - &make_path_feature, - NULL}; - - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, instance_features); - - assert(instance); - - // Run plugin to generate some recording file data - lilv_instance_activate(instance); - lilv_instance_connect_port(instance, 0, &ctx->in); - lilv_instance_connect_port(instance, 1, &ctx->out); - lilv_instance_run(instance, 1); - lilv_instance_run(instance, 2); - assert(ctx->in == 1.0); - assert(ctx->out == 1.0); - - // Save first state to a bundle - char* const bundle_1_1_path = lilv_path_join(dirs.top, "state1_1.lv2"); - LilvState* const state_1_1 = - state_from_instance(plugin, instance, ctx, &dirs, bundle_1_1_path); - - assert(!lilv_state_save(ctx->env->world, - &ctx->map, - &ctx->unmap, - state_1_1, - NULL, - bundle_1_1_path, - "state.ttl")); - - // Save first state to another bundle - char* const bundle_1_2_path = lilv_path_join(dirs.top, "state1_2.lv2"); - LilvState* const state_1_2 = - state_from_instance(plugin, instance, ctx, &dirs, bundle_1_2_path); - - assert(!lilv_state_save(ctx->env->world, - &ctx->map, - &ctx->unmap, - state_1_2, - NULL, - bundle_1_2_path, - "state.ttl")); - - // Load both first state bundles and check that the results are equal - char* const state_1_1_path = lilv_path_join(bundle_1_1_path, "state.ttl"); - char* const state_1_2_path = lilv_path_join(bundle_1_2_path, "state.ttl"); - - LilvState* state_1_1_loaded = lilv_state_new_from_file(ctx->env->world, - &ctx->map, - NULL, - state_1_1_path); - - LilvState* state_1_2_loaded = lilv_state_new_from_file(ctx->env->world, - &ctx->map, - NULL, - state_1_2_path); - - assert(state_1_1_loaded); - assert(state_1_2_loaded); - assert(lilv_state_equals(state_1_1_loaded, state_1_2_loaded)); - - // Run plugin again to modify recording file data - lilv_instance_run(instance, 2); - - // Save updated state to a bundle - char* const bundle_2_path = lilv_path_join(dirs.top, "state2.lv2"); - LilvState* const state_2 = - state_from_instance(plugin, instance, ctx, &dirs, bundle_2_path); - - assert(!lilv_state_save(ctx->env->world, - &ctx->map, - &ctx->unmap, - state_2, - NULL, - bundle_2_path, - "state.ttl")); - - // Load updated state bundle and check that it differs from the others - char* const state_2_path = lilv_path_join(bundle_2_path, "state.ttl"); - - LilvState* state_2_loaded = lilv_state_new_from_file(ctx->env->world, - &ctx->map, - NULL, - state_2_path); - - assert(state_2_loaded); - assert(!lilv_state_equals(state_1_1_loaded, state_2_loaded)); - - lilv_instance_free(instance); - lilv_dir_for_each(bundle_1_1_path, NULL, remove_file); - lilv_dir_for_each(bundle_1_2_path, NULL, remove_file); - lilv_dir_for_each(bundle_2_path, NULL, remove_file); - lilv_remove(bundle_1_1_path); - lilv_remove(bundle_1_2_path); - lilv_remove(bundle_2_path); - cleanup_test_directories(dirs); - - lilv_state_free(state_2_loaded); - free(state_2_path); - lilv_state_free(state_2); - free(bundle_2_path); - lilv_state_free(state_1_2_loaded); - lilv_state_free(state_1_1_loaded); - free(state_1_2_path); - free(state_1_1_path); - lilv_state_free(state_1_2); - free(bundle_1_2_path); - lilv_state_free(state_1_1); - free(bundle_1_1_path); - test_context_free(ctx); + TestContext* const ctx = test_context_new(); + TestDirectories dirs = create_test_directories(); + const LilvPlugin* const plugin = load_test_plugin(ctx); + + LV2_State_Make_Path make_path = {&dirs, make_scratch_path}; + LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path}; + + const LV2_Feature* const instance_features[] = { + &ctx->map_feature, &ctx->free_path_feature, &make_path_feature, NULL}; + + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, instance_features); + + assert(instance); + + // Run plugin to generate some recording file data + lilv_instance_activate(instance); + lilv_instance_connect_port(instance, 0, &ctx->in); + lilv_instance_connect_port(instance, 1, &ctx->out); + lilv_instance_run(instance, 1); + lilv_instance_run(instance, 2); + assert(ctx->in == 1.0); + assert(ctx->out == 1.0); + + // Save first state to a bundle + char* const bundle_1_1_path = lilv_path_join(dirs.top, "state1_1.lv2"); + LilvState* const state_1_1 = + state_from_instance(plugin, instance, ctx, &dirs, bundle_1_1_path); + + assert(!lilv_state_save(ctx->env->world, + &ctx->map, + &ctx->unmap, + state_1_1, + NULL, + bundle_1_1_path, + "state.ttl")); + + // Save first state to another bundle + char* const bundle_1_2_path = lilv_path_join(dirs.top, "state1_2.lv2"); + LilvState* const state_1_2 = + state_from_instance(plugin, instance, ctx, &dirs, bundle_1_2_path); + + assert(!lilv_state_save(ctx->env->world, + &ctx->map, + &ctx->unmap, + state_1_2, + NULL, + bundle_1_2_path, + "state.ttl")); + + // Load both first state bundles and check that the results are equal + char* const state_1_1_path = lilv_path_join(bundle_1_1_path, "state.ttl"); + char* const state_1_2_path = lilv_path_join(bundle_1_2_path, "state.ttl"); + + LilvState* state_1_1_loaded = + lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_1_1_path); + + LilvState* state_1_2_loaded = + lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_1_2_path); + + assert(state_1_1_loaded); + assert(state_1_2_loaded); + assert(lilv_state_equals(state_1_1_loaded, state_1_2_loaded)); + + // Run plugin again to modify recording file data + lilv_instance_run(instance, 2); + + // Save updated state to a bundle + char* const bundle_2_path = lilv_path_join(dirs.top, "state2.lv2"); + LilvState* const state_2 = + state_from_instance(plugin, instance, ctx, &dirs, bundle_2_path); + + assert(!lilv_state_save(ctx->env->world, + &ctx->map, + &ctx->unmap, + state_2, + NULL, + bundle_2_path, + "state.ttl")); + + // Load updated state bundle and check that it differs from the others + char* const state_2_path = lilv_path_join(bundle_2_path, "state.ttl"); + + LilvState* state_2_loaded = + lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_2_path); + + assert(state_2_loaded); + assert(!lilv_state_equals(state_1_1_loaded, state_2_loaded)); + + lilv_instance_free(instance); + lilv_dir_for_each(bundle_1_1_path, NULL, remove_file); + lilv_dir_for_each(bundle_1_2_path, NULL, remove_file); + lilv_dir_for_each(bundle_2_path, NULL, remove_file); + lilv_remove(bundle_1_1_path); + lilv_remove(bundle_1_2_path); + lilv_remove(bundle_2_path); + cleanup_test_directories(dirs); + + lilv_state_free(state_2_loaded); + free(state_2_path); + lilv_state_free(state_2); + free(bundle_2_path); + lilv_state_free(state_1_2_loaded); + lilv_state_free(state_1_1_loaded); + free(state_1_2_path); + free(state_1_1_path); + lilv_state_free(state_1_2); + free(bundle_1_2_path); + lilv_state_free(state_1_1); + free(bundle_1_1_path); + test_context_free(ctx); } static void test_world_round_trip(void) { - TestContext* const ctx = test_context_new(); - LilvWorld* const world = ctx->env->world; - TestDirectories dirs = create_test_directories(); - const LilvPlugin* const plugin = load_test_plugin(ctx); - static const char* const state_uri = "http://example.org/worldState"; - - LV2_State_Make_Path make_path = {&dirs, make_scratch_path}; - LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path}; - - const LV2_Feature* const instance_features[] = {&ctx->map_feature, - &ctx->free_path_feature, - &make_path_feature, - NULL}; - - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, instance_features); - - assert(instance); - - // Run plugin to generate some recording file data - lilv_instance_activate(instance); - lilv_instance_connect_port(instance, 0, &ctx->in); - lilv_instance_connect_port(instance, 1, &ctx->out); - lilv_instance_run(instance, 1); - lilv_instance_run(instance, 2); - assert(ctx->in == 1.0); - assert(ctx->out == 1.0); - - // Save state to a bundle - char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/"); - LilvState* const start_state = - state_from_instance(plugin, instance, ctx, &dirs, bundle_path); - - assert(!lilv_state_save(ctx->env->world, - &ctx->map, - &ctx->unmap, - start_state, - state_uri, - bundle_path, - "state.ttl")); - - // Load state bundle into world - SerdNode bundle_uri = - serd_node_new_file_uri((const uint8_t*)bundle_path, 0, 0, true); - LilvNode* const bundle_node = - lilv_new_uri(world, (const char*)bundle_uri.buf); - LilvNode* const state_node = lilv_new_uri(world, state_uri); - lilv_world_load_bundle(world, bundle_node); - lilv_world_load_resource(world, state_node); - - // Ensure the state loaded from the world matches - LilvState* const restored = - lilv_state_new_from_world(world, &ctx->map, state_node); - assert(lilv_state_equals(start_state, restored)); - - // Unload state from world - lilv_world_unload_resource(world, state_node); - lilv_world_unload_bundle(world, bundle_node); - - // Ensure that it is no longer present - assert(!lilv_state_new_from_world(world, &ctx->map, state_node)); - - lilv_instance_free(instance); - lilv_state_delete(world, start_state); - cleanup_test_directories(dirs); - - lilv_state_free(restored); - lilv_node_free(state_node); - lilv_node_free(bundle_node); - serd_node_free(&bundle_uri); - lilv_state_free(start_state); - free(bundle_path); - test_context_free(ctx); + TestContext* const ctx = test_context_new(); + LilvWorld* const world = ctx->env->world; + TestDirectories dirs = create_test_directories(); + const LilvPlugin* const plugin = load_test_plugin(ctx); + static const char* const state_uri = "http://example.org/worldState"; + + LV2_State_Make_Path make_path = {&dirs, make_scratch_path}; + LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path}; + + const LV2_Feature* const instance_features[] = { + &ctx->map_feature, &ctx->free_path_feature, &make_path_feature, NULL}; + + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, instance_features); + + assert(instance); + + // Run plugin to generate some recording file data + lilv_instance_activate(instance); + lilv_instance_connect_port(instance, 0, &ctx->in); + lilv_instance_connect_port(instance, 1, &ctx->out); + lilv_instance_run(instance, 1); + lilv_instance_run(instance, 2); + assert(ctx->in == 1.0); + assert(ctx->out == 1.0); + + // Save state to a bundle + char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/"); + LilvState* const start_state = + state_from_instance(plugin, instance, ctx, &dirs, bundle_path); + + assert(!lilv_state_save(ctx->env->world, + &ctx->map, + &ctx->unmap, + start_state, + state_uri, + bundle_path, + "state.ttl")); + + // Load state bundle into world + SerdNode bundle_uri = + serd_node_new_file_uri((const uint8_t*)bundle_path, 0, 0, true); + LilvNode* const bundle_node = + lilv_new_uri(world, (const char*)bundle_uri.buf); + LilvNode* const state_node = lilv_new_uri(world, state_uri); + lilv_world_load_bundle(world, bundle_node); + lilv_world_load_resource(world, state_node); + + // Ensure the state loaded from the world matches + LilvState* const restored = + lilv_state_new_from_world(world, &ctx->map, state_node); + assert(lilv_state_equals(start_state, restored)); + + // Unload state from world + lilv_world_unload_resource(world, state_node); + lilv_world_unload_bundle(world, bundle_node); + + // Ensure that it is no longer present + assert(!lilv_state_new_from_world(world, &ctx->map, state_node)); + + lilv_instance_free(instance); + lilv_state_delete(world, start_state); + cleanup_test_directories(dirs); + + lilv_state_free(restored); + lilv_node_free(state_node); + lilv_node_free(bundle_node); + serd_node_free(&bundle_uri); + lilv_state_free(start_state); + free(bundle_path); + test_context_free(ctx); } static void test_label_round_trip(void) { - TestContext* const ctx = test_context_new(); - const TestDirectories dirs = create_test_directories(); - const LilvPlugin* const plugin = load_test_plugin(ctx); - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, ctx->features); - - assert(instance); - - // Get initial state - LilvState* const state = - state_from_instance(plugin, instance, ctx, &dirs, NULL); - - // Set a label - lilv_state_set_label(state, "Monopoly on violence"); - - // Save to a bundle - char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/"); - assert(!lilv_state_save(ctx->env->world, - &ctx->map, - &ctx->unmap, - state, - NULL, - bundle_path, - "state.ttl")); - - // Load bundle and check the label and that the states are equal - char* const state_path = lilv_path_join(bundle_path, "state.ttl"); - - LilvState* const loaded = - lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_path); - - assert(loaded); - assert(lilv_state_equals(state, loaded)); - assert(!strcmp(lilv_state_get_label(loaded), "Monopoly on violence")); - - lilv_instance_free(instance); - lilv_state_delete(ctx->env->world, state); - cleanup_test_directories(dirs); - - lilv_state_free(loaded); - free(state_path); - free(bundle_path); - lilv_state_free(state); - test_context_free(ctx); + TestContext* const ctx = test_context_new(); + const TestDirectories dirs = create_test_directories(); + const LilvPlugin* const plugin = load_test_plugin(ctx); + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, ctx->features); + + assert(instance); + + // Get initial state + LilvState* const state = + state_from_instance(plugin, instance, ctx, &dirs, NULL); + + // Set a label + lilv_state_set_label(state, "Monopoly on violence"); + + // Save to a bundle + char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/"); + assert(!lilv_state_save(ctx->env->world, + &ctx->map, + &ctx->unmap, + state, + NULL, + bundle_path, + "state.ttl")); + + // Load bundle and check the label and that the states are equal + char* const state_path = lilv_path_join(bundle_path, "state.ttl"); + + LilvState* const loaded = + lilv_state_new_from_file(ctx->env->world, &ctx->map, NULL, state_path); + + assert(loaded); + assert(lilv_state_equals(state, loaded)); + assert(!strcmp(lilv_state_get_label(loaded), "Monopoly on violence")); + + lilv_instance_free(instance); + lilv_state_delete(ctx->env->world, state); + cleanup_test_directories(dirs); + + lilv_state_free(loaded); + free(state_path); + free(bundle_path); + lilv_state_free(state); + test_context_free(ctx); } static void test_bad_subject(void) { - TestContext* const ctx = test_context_new(); - LilvNode* const string = lilv_new_string(ctx->env->world, "Not a URI"); + TestContext* const ctx = test_context_new(); + LilvNode* const string = lilv_new_string(ctx->env->world, "Not a URI"); - LilvState* const file_state = lilv_state_new_from_file(ctx->env->world, - &ctx->map, - string, - "/I/do/not/matter"); + LilvState* const file_state = lilv_state_new_from_file( + ctx->env->world, &ctx->map, string, "/I/do/not/matter"); - assert(!file_state); + assert(!file_state); - LilvState* const world_state = - lilv_state_new_from_world(ctx->env->world, &ctx->map, string); + LilvState* const world_state = + lilv_state_new_from_world(ctx->env->world, &ctx->map, string); - assert(!world_state); + assert(!world_state); - lilv_node_free(string); - test_context_free(ctx); + lilv_node_free(string); + test_context_free(ctx); } static void count_file(const char* path, const char* name, void* data) { - *(unsigned*)data += 1; + *(unsigned*)data += 1; } static void test_delete(void) { - TestContext* const ctx = test_context_new(); - TestDirectories dirs = create_test_directories(); - const LilvPlugin* const plugin = load_test_plugin(ctx); - - LV2_State_Make_Path make_path = {&dirs, make_scratch_path}; - LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path}; - - const LV2_Feature* const instance_features[] = {&ctx->map_feature, - &ctx->free_path_feature, - &make_path_feature, - NULL}; - - LilvInstance* const instance = - lilv_plugin_instantiate(plugin, 48000.0, instance_features); - - assert(instance); - - // Run plugin to generate some recording file data - lilv_instance_activate(instance); - lilv_instance_connect_port(instance, 0, &ctx->in); - lilv_instance_connect_port(instance, 1, &ctx->out); - lilv_instance_run(instance, 1); - lilv_instance_run(instance, 2); - assert(ctx->in == 1.0); - assert(ctx->out == 1.0); - - // Save state to a bundle - char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/"); - LilvState* const state = - state_from_instance(plugin, instance, ctx, &dirs, bundle_path); - - assert(!lilv_state_save(ctx->env->world, - &ctx->map, - &ctx->unmap, - state, - NULL, - bundle_path, - "state.ttl")); - - // Count the number of shared files before doing anything - unsigned n_shared_files_before = 0; - lilv_dir_for_each(dirs.shared, &n_shared_files_before, count_file); - - lilv_instance_free(instance); - - // Delete the state - assert(!lilv_state_delete(ctx->env->world, state)); - - // Ensure the number of shared files is the same after deletion - unsigned n_shared_files_after = 0; - lilv_dir_for_each(dirs.shared, &n_shared_files_after, count_file); - assert(n_shared_files_before == n_shared_files_after); - - // Ensure the state directory has been deleted - assert(!lilv_path_exists(bundle_path)); - - cleanup_test_directories(dirs); - - lilv_state_free(state); - free(bundle_path); - test_context_free(ctx); + TestContext* const ctx = test_context_new(); + TestDirectories dirs = create_test_directories(); + const LilvPlugin* const plugin = load_test_plugin(ctx); + + LV2_State_Make_Path make_path = {&dirs, make_scratch_path}; + LV2_Feature make_path_feature = {LV2_STATE__makePath, &make_path}; + + const LV2_Feature* const instance_features[] = { + &ctx->map_feature, &ctx->free_path_feature, &make_path_feature, NULL}; + + LilvInstance* const instance = + lilv_plugin_instantiate(plugin, 48000.0, instance_features); + + assert(instance); + + // Run plugin to generate some recording file data + lilv_instance_activate(instance); + lilv_instance_connect_port(instance, 0, &ctx->in); + lilv_instance_connect_port(instance, 1, &ctx->out); + lilv_instance_run(instance, 1); + lilv_instance_run(instance, 2); + assert(ctx->in == 1.0); + assert(ctx->out == 1.0); + + // Save state to a bundle + char* const bundle_path = lilv_path_join(dirs.top, "state.lv2/"); + LilvState* const state = + state_from_instance(plugin, instance, ctx, &dirs, bundle_path); + + assert(!lilv_state_save(ctx->env->world, + &ctx->map, + &ctx->unmap, + state, + NULL, + bundle_path, + "state.ttl")); + + // Count the number of shared files before doing anything + unsigned n_shared_files_before = 0; + lilv_dir_for_each(dirs.shared, &n_shared_files_before, count_file); + + lilv_instance_free(instance); + + // Delete the state + assert(!lilv_state_delete(ctx->env->world, state)); + + // Ensure the number of shared files is the same after deletion + unsigned n_shared_files_after = 0; + lilv_dir_for_each(dirs.shared, &n_shared_files_after, count_file); + assert(n_shared_files_before == n_shared_files_after); + + // Ensure the state directory has been deleted + assert(!lilv_path_exists(bundle_path)); + + cleanup_test_directories(dirs); + + lilv_state_free(state); + free(bundle_path); + test_context_free(ctx); } int main(void) { - test_instance_state(); - test_equal(); - test_changed_plugin_data(); - test_changed_metadata(); - test_to_string(); - test_string_round_trip(); - test_to_files(); - test_multi_save(); - test_files_round_trip(); - test_world_round_trip(); - test_label_round_trip(); - test_bad_subject(); - test_delete(); - - return 0; + test_instance_state(); + test_equal(); + test_changed_plugin_data(); + test_changed_metadata(); + test_to_string(); + test_string_round_trip(); + test_to_files(); + test_multi_save(); + test_files_round_trip(); + test_world_round_trip(); + test_label_round_trip(); + test_bad_subject(); + test_delete(); + + return 0; } diff --git a/test/test_string.c b/test/test_string.c index 9eb2456..e66accf 100644 --- a/test/test_string.c +++ b/test/test_string.c @@ -21,9 +21,9 @@ #include "../src/lilv_internal.h" #ifdef _WIN32 -# include <windows.h> -# define setenv(n, v, r) SetEnvironmentVariable((n), (v)) -# define unsetenv(n) SetEnvironmentVariable((n), NULL) +# include <windows.h> +# define setenv(n, v, r) SetEnvironmentVariable((n), (v)) +# define unsetenv(n) SetEnvironmentVariable((n), NULL) #endif #include <assert.h> @@ -34,23 +34,23 @@ int main(void) { #ifndef _WIN32 - char* s = NULL; - - setenv("LILV_TEST_1", "test", 1); - char* home_foo = lilv_strjoin(getenv("HOME"), "/foo", NULL); - assert(!strcmp((s = lilv_expand("$LILV_TEST_1")), "test")); - free(s); - assert(!strcmp((s = lilv_expand("~")), getenv("HOME"))); - free(s); - assert(!strcmp((s = lilv_expand("~foo")), "~foo")); - free(s); - assert(!strcmp((s = lilv_expand("~/foo")), home_foo)); - free(s); - assert(!strcmp((s = lilv_expand("$NOT_A_VAR")), "$NOT_A_VAR")); - free(s); - free(home_foo); - unsetenv("LILV_TEST_1"); + char* s = NULL; + + setenv("LILV_TEST_1", "test", 1); + char* home_foo = lilv_strjoin(getenv("HOME"), "/foo", NULL); + assert(!strcmp((s = lilv_expand("$LILV_TEST_1")), "test")); + free(s); + assert(!strcmp((s = lilv_expand("~")), getenv("HOME"))); + free(s); + assert(!strcmp((s = lilv_expand("~foo")), "~foo")); + free(s); + assert(!strcmp((s = lilv_expand("~/foo")), home_foo)); + free(s); + assert(!strcmp((s = lilv_expand("$NOT_A_VAR")), "$NOT_A_VAR")); + free(s); + free(home_foo); + unsetenv("LILV_TEST_1"); #endif - return 0; + return 0; } diff --git a/test/test_ui.c b/test/test_ui.c index 6230318..032bfbc 100644 --- a/test/test_ui.c +++ b/test/test_ui.c @@ -86,95 +86,95 @@ static const char* const plugin_ttl = "\ static unsigned ui_supported(const char* container_type_uri, const char* ui_type_uri) { - return !strcmp(container_type_uri, ui_type_uri); + return !strcmp(container_type_uri, ui_type_uri); } int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(plug); + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + assert(plug); - LilvUIs* uis = lilv_plugin_get_uis(plug); - assert(lilv_uis_size(uis) == 4); + LilvUIs* uis = lilv_plugin_get_uis(plug); + assert(lilv_uis_size(uis) == 4); - const LilvUI* ui0 = lilv_uis_get(uis, lilv_uis_begin(uis)); - assert(ui0); + const LilvUI* ui0 = lilv_uis_get(uis, lilv_uis_begin(uis)); + assert(ui0); - LilvNode* ui_uri = lilv_new_uri(world, "http://example.org/ui"); - LilvNode* ui2_uri = lilv_new_uri(world, "http://example.org/ui3"); - LilvNode* ui3_uri = lilv_new_uri(world, "http://example.org/ui4"); - LilvNode* noui_uri = lilv_new_uri(world, "http://example.org/notaui"); + LilvNode* ui_uri = lilv_new_uri(world, "http://example.org/ui"); + LilvNode* ui2_uri = lilv_new_uri(world, "http://example.org/ui3"); + LilvNode* ui3_uri = lilv_new_uri(world, "http://example.org/ui4"); + LilvNode* noui_uri = lilv_new_uri(world, "http://example.org/notaui"); - const LilvUI* ui0_2 = lilv_uis_get_by_uri(uis, ui_uri); - assert(ui0 == ui0_2); - assert(lilv_node_equals(lilv_ui_get_uri(ui0_2), ui_uri)); + const LilvUI* ui0_2 = lilv_uis_get_by_uri(uis, ui_uri); + assert(ui0 == ui0_2); + assert(lilv_node_equals(lilv_ui_get_uri(ui0_2), ui_uri)); - const LilvUI* ui2 = lilv_uis_get_by_uri(uis, ui2_uri); - assert(ui2 != ui0); + const LilvUI* ui2 = lilv_uis_get_by_uri(uis, ui2_uri); + assert(ui2 != ui0); - const LilvUI* ui3 = lilv_uis_get_by_uri(uis, ui3_uri); - assert(ui3 != ui0); + const LilvUI* ui3 = lilv_uis_get_by_uri(uis, ui3_uri); + assert(ui3 != ui0); - const LilvUI* noui = lilv_uis_get_by_uri(uis, noui_uri); - assert(noui == NULL); + const LilvUI* noui = lilv_uis_get_by_uri(uis, noui_uri); + assert(noui == NULL); - const LilvNodes* classes = lilv_ui_get_classes(ui0); - assert(lilv_nodes_size(classes) == 1); + const LilvNodes* classes = lilv_ui_get_classes(ui0); + assert(lilv_nodes_size(classes) == 1); - LilvNode* ui_class_uri = - lilv_new_uri(world, "http://lv2plug.in/ns/extensions/ui#GtkUI"); + LilvNode* ui_class_uri = + lilv_new_uri(world, "http://lv2plug.in/ns/extensions/ui#GtkUI"); - LilvNode* unknown_ui_class_uri = - lilv_new_uri(world, "http://example.org/mysteryUI"); + LilvNode* unknown_ui_class_uri = + lilv_new_uri(world, "http://example.org/mysteryUI"); - assert(lilv_node_equals(lilv_nodes_get_first(classes), ui_class_uri)); - assert(lilv_ui_is_a(ui0, ui_class_uri)); + assert(lilv_node_equals(lilv_nodes_get_first(classes), ui_class_uri)); + assert(lilv_ui_is_a(ui0, ui_class_uri)); - const LilvNode* ui_type = NULL; - assert(lilv_ui_is_supported(ui0, ui_supported, ui_class_uri, &ui_type)); - assert(!lilv_ui_is_supported( - ui0, ui_supported, unknown_ui_class_uri, &ui_type)); - assert(lilv_node_equals(ui_type, ui_class_uri)); + const LilvNode* ui_type = NULL; + assert(lilv_ui_is_supported(ui0, ui_supported, ui_class_uri, &ui_type)); + assert( + !lilv_ui_is_supported(ui0, ui_supported, unknown_ui_class_uri, &ui_type)); + assert(lilv_node_equals(ui_type, ui_class_uri)); - const LilvNode* plug_bundle_uri = lilv_plugin_get_bundle_uri(plug); - const LilvNode* ui_bundle_uri = lilv_ui_get_bundle_uri(ui0); - assert(lilv_node_equals(plug_bundle_uri, ui_bundle_uri)); + const LilvNode* plug_bundle_uri = lilv_plugin_get_bundle_uri(plug); + const LilvNode* ui_bundle_uri = lilv_ui_get_bundle_uri(ui0); + assert(lilv_node_equals(plug_bundle_uri, ui_bundle_uri)); - const size_t ui_binary_uri_str_len = - strlen(lilv_node_as_string(plug_bundle_uri)) + strlen("ui" SHLIB_EXT); + const size_t ui_binary_uri_str_len = + strlen(lilv_node_as_string(plug_bundle_uri)) + strlen("ui" SHLIB_EXT); - char* ui_binary_uri_str = (char*)calloc(1, ui_binary_uri_str_len + 1); - snprintf(ui_binary_uri_str, - ui_binary_uri_str_len + 1, - "%s%s", - lilv_node_as_string(plug_bundle_uri), - "ui" SHLIB_EXT); + char* ui_binary_uri_str = (char*)calloc(1, ui_binary_uri_str_len + 1); + snprintf(ui_binary_uri_str, + ui_binary_uri_str_len + 1, + "%s%s", + lilv_node_as_string(plug_bundle_uri), + "ui" SHLIB_EXT); - const LilvNode* ui_binary_uri = lilv_ui_get_binary_uri(ui0); + const LilvNode* ui_binary_uri = lilv_ui_get_binary_uri(ui0); - LilvNode* expected_uri = lilv_new_uri(world, ui_binary_uri_str); - assert(lilv_node_equals(expected_uri, ui_binary_uri)); + LilvNode* expected_uri = lilv_new_uri(world, ui_binary_uri_str); + assert(lilv_node_equals(expected_uri, ui_binary_uri)); - free(ui_binary_uri_str); - lilv_node_free(unknown_ui_class_uri); - lilv_node_free(ui_class_uri); - lilv_node_free(ui_uri); - lilv_node_free(ui2_uri); - lilv_node_free(ui3_uri); - lilv_node_free(noui_uri); - lilv_node_free(expected_uri); - lilv_uis_free(uis); + free(ui_binary_uri_str); + lilv_node_free(unknown_ui_class_uri); + lilv_node_free(ui_class_uri); + lilv_node_free(ui_uri); + lilv_node_free(ui2_uri); + lilv_node_free(ui3_uri); + lilv_node_free(noui_uri); + lilv_node_free(expected_uri); + lilv_uis_free(uis); - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_util.c b/test/test_util.c index 9055e88..db7eaed 100644 --- a/test/test_util.c +++ b/test/test_util.c @@ -19,14 +19,14 @@ #undef NDEBUG #ifdef _WIN32 -# include "lilv_internal.h" +# include "lilv_internal.h" #endif #include "../src/filesystem.h" #ifdef _WIN32 -# include <io.h> -# define mkstemp(pat) _mktemp(pat) +# include <io.h> +# define mkstemp(pat) _mktemp(pat) #endif #include <assert.h> @@ -37,31 +37,31 @@ int main(void) { - assert(!lilv_path_canonical(NULL)); + assert(!lilv_path_canonical(NULL)); - char a_path[16]; - char b_path[16]; - strncpy(a_path, "copy_a_XXXXXX", sizeof(a_path)); - strncpy(b_path, "copy_b_XXXXXX", sizeof(b_path)); - mkstemp(a_path); - mkstemp(b_path); + char a_path[16]; + char b_path[16]; + strncpy(a_path, "copy_a_XXXXXX", sizeof(a_path)); + strncpy(b_path, "copy_b_XXXXXX", sizeof(b_path)); + mkstemp(a_path); + mkstemp(b_path); - FILE* fa = fopen(a_path, "w"); - FILE* fb = fopen(b_path, "w"); - fprintf(fa, "AA\n"); - fprintf(fb, "AB\n"); - fclose(fa); - fclose(fb); + FILE* fa = fopen(a_path, "w"); + FILE* fb = fopen(b_path, "w"); + fprintf(fa, "AA\n"); + fprintf(fb, "AB\n"); + fclose(fa); + fclose(fb); - assert(lilv_copy_file("does/not/exist", "copy")); - assert(lilv_copy_file(a_path, "not/a/dir/copy")); - assert(!lilv_copy_file(a_path, "copy_c")); - assert(!lilv_file_equals(a_path, b_path)); - assert(lilv_file_equals(a_path, a_path)); - assert(lilv_file_equals(a_path, "copy_c")); - assert(!lilv_file_equals("does/not/exist", b_path)); - assert(!lilv_file_equals(a_path, "does/not/exist")); - assert(!lilv_file_equals("does/not/exist", "/does/not/either")); + assert(lilv_copy_file("does/not/exist", "copy")); + assert(lilv_copy_file(a_path, "not/a/dir/copy")); + assert(!lilv_copy_file(a_path, "copy_c")); + assert(!lilv_file_equals(a_path, b_path)); + assert(lilv_file_equals(a_path, a_path)); + assert(lilv_file_equals(a_path, "copy_c")); + assert(!lilv_file_equals("does/not/exist", b_path)); + assert(!lilv_file_equals(a_path, "does/not/exist")); + assert(!lilv_file_equals("does/not/exist", "/does/not/either")); - return 0; + return 0; } diff --git a/test/test_value.c b/test/test_value.c index a6a1fd0..1b3a63e 100644 --- a/test/test_value.c +++ b/test/test_value.c @@ -39,135 +39,135 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; - - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } - - LilvNode* uval = lilv_new_uri(world, "http://example.org"); - LilvNode* sval = lilv_new_string(world, "Foo"); - LilvNode* ival = lilv_new_int(world, 42); - LilvNode* fval = lilv_new_float(world, 1.6180f); - - assert(lilv_node_is_uri(uval)); - assert(lilv_node_is_string(sval)); - assert(lilv_node_is_int(ival)); - assert(lilv_node_is_float(fval)); - - assert(!lilv_node_is_literal(NULL)); - assert(!lilv_node_is_literal(uval)); - assert(lilv_node_is_literal(sval)); - assert(lilv_node_is_literal(ival)); - assert(lilv_node_is_literal(fval)); - assert(!lilv_node_get_path(fval, NULL)); - - assert(!strcmp(lilv_node_as_uri(uval), "http://example.org")); - assert(!strcmp(lilv_node_as_string(sval), "Foo")); - assert(lilv_node_as_int(ival) == 42); - assert(fabs(lilv_node_as_float(fval) - 1.6180) < FLT_EPSILON); - assert(isnan(lilv_node_as_float(sval))); + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; + + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } + + LilvNode* uval = lilv_new_uri(world, "http://example.org"); + LilvNode* sval = lilv_new_string(world, "Foo"); + LilvNode* ival = lilv_new_int(world, 42); + LilvNode* fval = lilv_new_float(world, 1.6180f); + + assert(lilv_node_is_uri(uval)); + assert(lilv_node_is_string(sval)); + assert(lilv_node_is_int(ival)); + assert(lilv_node_is_float(fval)); + + assert(!lilv_node_is_literal(NULL)); + assert(!lilv_node_is_literal(uval)); + assert(lilv_node_is_literal(sval)); + assert(lilv_node_is_literal(ival)); + assert(lilv_node_is_literal(fval)); + assert(!lilv_node_get_path(fval, NULL)); + + assert(!strcmp(lilv_node_as_uri(uval), "http://example.org")); + assert(!strcmp(lilv_node_as_string(sval), "Foo")); + assert(lilv_node_as_int(ival) == 42); + assert(fabs(lilv_node_as_float(fval) - 1.6180) < FLT_EPSILON); + assert(isnan(lilv_node_as_float(sval))); #if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated-declarations" #elif defined(__GNUC__) && __GNUC__ > 4 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif - assert(!strcmp(lilv_uri_to_path("file:///foo"), "/foo")); + assert(!strcmp(lilv_uri_to_path("file:///foo"), "/foo")); #if defined(__clang__) -# pragma clang diagnostic pop +# pragma clang diagnostic pop #elif defined(__GNUC__) && __GNUC__ > 4 -# pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif - LilvNode* loc_abs = lilv_new_file_uri(world, NULL, "/foo/bar"); - LilvNode* loc_rel = lilv_new_file_uri(world, NULL, "foo"); - LilvNode* host_abs = lilv_new_file_uri(world, "host", "/foo/bar"); - LilvNode* host_rel = lilv_new_file_uri(world, "host", "foo"); - - assert(!strcmp(lilv_node_as_uri(loc_abs), "file:///foo/bar")); - assert(!strncmp(lilv_node_as_uri(loc_rel), "file:///", 8)); - assert(!strcmp(lilv_node_as_uri(host_abs), "file://host/foo/bar")); - assert(!strncmp(lilv_node_as_uri(host_rel), "file://host/", 12)); - - lilv_node_free(host_rel); - lilv_node_free(host_abs); - lilv_node_free(loc_rel); - lilv_node_free(loc_abs); - - char* tok = lilv_node_get_turtle_token(uval); - assert(!strcmp(tok, "<http://example.org>")); - lilv_free(tok); - tok = lilv_node_get_turtle_token(sval); - assert(!strcmp(tok, "Foo")); - lilv_free(tok); - tok = lilv_node_get_turtle_token(ival); - assert(!strcmp(tok, "42")); - lilv_free(tok); - tok = lilv_node_get_turtle_token(fval); - assert(!strncmp(tok, "1.6180", 6)); - lilv_free(tok); - - LilvNode* uval_e = lilv_new_uri(world, "http://example.org"); - LilvNode* sval_e = lilv_new_string(world, "Foo"); - LilvNode* ival_e = lilv_new_int(world, 42); - LilvNode* fval_e = lilv_new_float(world, 1.6180f); - LilvNode* uval_ne = lilv_new_uri(world, "http://no-example.org"); - LilvNode* sval_ne = lilv_new_string(world, "Bar"); - LilvNode* ival_ne = lilv_new_int(world, 24); - LilvNode* fval_ne = lilv_new_float(world, 3.14159f); - - assert(lilv_node_equals(uval, uval_e)); - assert(lilv_node_equals(sval, sval_e)); - assert(lilv_node_equals(ival, ival_e)); - assert(lilv_node_equals(fval, fval_e)); - - assert(!lilv_node_equals(uval, uval_ne)); - assert(!lilv_node_equals(sval, sval_ne)); - assert(!lilv_node_equals(ival, ival_ne)); - assert(!lilv_node_equals(fval, fval_ne)); - - assert(!lilv_node_equals(uval, sval)); - assert(!lilv_node_equals(sval, ival)); - assert(!lilv_node_equals(ival, fval)); - - LilvNode* uval_dup = lilv_node_duplicate(uval); - assert(lilv_node_equals(uval, uval_dup)); - - LilvNode* ifval = lilv_new_float(world, 42.0); - assert(!lilv_node_equals(ival, ifval)); - lilv_node_free(ifval); - - LilvNode* nil = NULL; - assert(!lilv_node_equals(uval, nil)); - assert(!lilv_node_equals(nil, uval)); - assert(lilv_node_equals(nil, nil)); - - LilvNode* nil2 = lilv_node_duplicate(nil); - assert(lilv_node_equals(nil, nil2)); - - lilv_node_free(uval); - lilv_node_free(sval); - lilv_node_free(ival); - lilv_node_free(fval); - lilv_node_free(uval_e); - lilv_node_free(sval_e); - lilv_node_free(ival_e); - lilv_node_free(fval_e); - lilv_node_free(uval_ne); - lilv_node_free(sval_ne); - lilv_node_free(ival_ne); - lilv_node_free(fval_ne); - lilv_node_free(uval_dup); - lilv_node_free(nil2); - - delete_bundle(env); - lilv_test_env_free(env); - - return 0; + LilvNode* loc_abs = lilv_new_file_uri(world, NULL, "/foo/bar"); + LilvNode* loc_rel = lilv_new_file_uri(world, NULL, "foo"); + LilvNode* host_abs = lilv_new_file_uri(world, "host", "/foo/bar"); + LilvNode* host_rel = lilv_new_file_uri(world, "host", "foo"); + + assert(!strcmp(lilv_node_as_uri(loc_abs), "file:///foo/bar")); + assert(!strncmp(lilv_node_as_uri(loc_rel), "file:///", 8)); + assert(!strcmp(lilv_node_as_uri(host_abs), "file://host/foo/bar")); + assert(!strncmp(lilv_node_as_uri(host_rel), "file://host/", 12)); + + lilv_node_free(host_rel); + lilv_node_free(host_abs); + lilv_node_free(loc_rel); + lilv_node_free(loc_abs); + + char* tok = lilv_node_get_turtle_token(uval); + assert(!strcmp(tok, "<http://example.org>")); + lilv_free(tok); + tok = lilv_node_get_turtle_token(sval); + assert(!strcmp(tok, "Foo")); + lilv_free(tok); + tok = lilv_node_get_turtle_token(ival); + assert(!strcmp(tok, "42")); + lilv_free(tok); + tok = lilv_node_get_turtle_token(fval); + assert(!strncmp(tok, "1.6180", 6)); + lilv_free(tok); + + LilvNode* uval_e = lilv_new_uri(world, "http://example.org"); + LilvNode* sval_e = lilv_new_string(world, "Foo"); + LilvNode* ival_e = lilv_new_int(world, 42); + LilvNode* fval_e = lilv_new_float(world, 1.6180f); + LilvNode* uval_ne = lilv_new_uri(world, "http://no-example.org"); + LilvNode* sval_ne = lilv_new_string(world, "Bar"); + LilvNode* ival_ne = lilv_new_int(world, 24); + LilvNode* fval_ne = lilv_new_float(world, 3.14159f); + + assert(lilv_node_equals(uval, uval_e)); + assert(lilv_node_equals(sval, sval_e)); + assert(lilv_node_equals(ival, ival_e)); + assert(lilv_node_equals(fval, fval_e)); + + assert(!lilv_node_equals(uval, uval_ne)); + assert(!lilv_node_equals(sval, sval_ne)); + assert(!lilv_node_equals(ival, ival_ne)); + assert(!lilv_node_equals(fval, fval_ne)); + + assert(!lilv_node_equals(uval, sval)); + assert(!lilv_node_equals(sval, ival)); + assert(!lilv_node_equals(ival, fval)); + + LilvNode* uval_dup = lilv_node_duplicate(uval); + assert(lilv_node_equals(uval, uval_dup)); + + LilvNode* ifval = lilv_new_float(world, 42.0); + assert(!lilv_node_equals(ival, ifval)); + lilv_node_free(ifval); + + LilvNode* nil = NULL; + assert(!lilv_node_equals(uval, nil)); + assert(!lilv_node_equals(nil, uval)); + assert(lilv_node_equals(nil, nil)); + + LilvNode* nil2 = lilv_node_duplicate(nil); + assert(lilv_node_equals(nil, nil2)); + + lilv_node_free(uval); + lilv_node_free(sval); + lilv_node_free(ival); + lilv_node_free(fval); + lilv_node_free(uval_e); + lilv_node_free(sval_e); + lilv_node_free(ival_e); + lilv_node_free(fval_e); + lilv_node_free(uval_ne); + lilv_node_free(sval_ne); + lilv_node_free(ival_ne); + lilv_node_free(fval_ne); + lilv_node_free(uval_dup); + lilv_node_free(nil2); + + delete_bundle(env); + lilv_test_env_free(env); + + return 0; } diff --git a/test/test_verify.c b/test/test_verify.c index dd88ba5..bce2919 100644 --- a/test/test_verify.c +++ b/test/test_verify.c @@ -36,22 +36,21 @@ static const char* const plugin_ttl = "\ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { - return 1; - } + if (start_bundle(env, SIMPLE_MANIFEST_TTL, plugin_ttl)) { + return 1; + } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* explug = - lilv_plugins_get_by_uri(plugins, env->plugin1_uri); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* explug = lilv_plugins_get_by_uri(plugins, env->plugin1_uri); - assert(explug); - assert(lilv_plugin_verify(explug)); + assert(explug); + assert(lilv_plugin_verify(explug)); - delete_bundle(env); - lilv_test_env_free(env); + delete_bundle(env); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/test/test_world.c b/test/test_world.c index b8572d2..57518ca 100644 --- a/test/test_world.c +++ b/test/test_world.c @@ -26,26 +26,26 @@ int main(void) { - LilvTestEnv* const env = lilv_test_env_new(); - LilvWorld* const world = env->world; + LilvTestEnv* const env = lilv_test_env_new(); + LilvWorld* const world = env->world; - LilvNode* num = lilv_new_int(env->world, 4); - LilvNode* uri = lilv_new_uri(env->world, "http://example.org/object"); + LilvNode* num = lilv_new_int(env->world, 4); + LilvNode* uri = lilv_new_uri(env->world, "http://example.org/object"); - LilvNodes* matches = lilv_world_find_nodes(world, num, NULL, NULL); - assert(!matches); + LilvNodes* matches = lilv_world_find_nodes(world, num, NULL, NULL); + assert(!matches); - matches = lilv_world_find_nodes(world, NULL, num, NULL); - assert(!matches); + matches = lilv_world_find_nodes(world, NULL, num, NULL); + assert(!matches); - matches = lilv_world_find_nodes(world, NULL, uri, NULL); - assert(!matches); + matches = lilv_world_find_nodes(world, NULL, uri, NULL); + assert(!matches); - lilv_node_free(uri); - lilv_node_free(num); + lilv_node_free(uri); + lilv_node_free(num); - lilv_world_unload_bundle(world, NULL); - lilv_test_env_free(env); + lilv_world_unload_bundle(world, NULL); + lilv_test_env_free(env); - return 0; + return 0; } diff --git a/utils/bench.h b/utils/bench.h index a04996b..28e5221 100644 --- a/utils/bench.h +++ b/utils/bench.h @@ -30,24 +30,24 @@ typedef struct timespec BenchmarkTime; static inline double bench_elapsed_s(const BenchmarkTime* start, const BenchmarkTime* end) { - return ((end->tv_sec - start->tv_sec) - + ((end->tv_nsec - start->tv_nsec) * 0.000000001)); + return ((end->tv_sec - start->tv_sec) + + ((end->tv_nsec - start->tv_nsec) * 0.000000001)); } static inline BenchmarkTime bench_start(void) { - BenchmarkTime start_t; - clock_gettime(CLOCK_REALTIME, &start_t); - return start_t; + BenchmarkTime start_t; + clock_gettime(CLOCK_REALTIME, &start_t); + return start_t; } static inline double bench_end(const BenchmarkTime* start_t) { - BenchmarkTime end_t; - clock_gettime(CLOCK_REALTIME, &end_t); - return bench_elapsed_s(start_t, &end_t); + BenchmarkTime end_t; + clock_gettime(CLOCK_REALTIME, &end_t); + return bench_elapsed_s(start_t, &end_t); } -#endif /* BENCH_H */ +#endif /* BENCH_H */ diff --git a/utils/lilv-bench.c b/utils/lilv-bench.c index 59e49fe..3068123 100644 --- a/utils/lilv-bench.c +++ b/utils/lilv-bench.c @@ -19,16 +19,16 @@ int main(int argc, char** argv) { - LilvWorld* world = lilv_world_new(); - lilv_world_load_all(world); + LilvWorld* world = lilv_world_new(); + lilv_world_load_all(world); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - LILV_FOREACH(plugins, p, plugins) { - const LilvPlugin* plugin = lilv_plugins_get(plugins, p); - lilv_plugin_get_class(plugin); - } + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + LILV_FOREACH (plugins, p, plugins) { + const LilvPlugin* plugin = lilv_plugins_get(plugins, p); + lilv_plugin_get_class(plugin); + } - lilv_world_free(world); + lilv_world_free(world); - return 0; + return 0; } diff --git a/utils/lv2apply.c b/utils/lv2apply.c index 1d11c50..0a1123a 100644 --- a/utils/lv2apply.c +++ b/utils/lv2apply.c @@ -28,73 +28,71 @@ #include <string.h> #if defined(__GNUC__) -# define LILV_LOG_FUNC(fmt, arg1) __attribute__((format(printf, fmt, arg1))) +# define LILV_LOG_FUNC(fmt, arg1) __attribute__((format(printf, fmt, arg1))) #else -# define LILV_LOG_FUNC(fmt, arg1) +# define LILV_LOG_FUNC(fmt, arg1) #endif /** Control port value set from the command line */ typedef struct Param { - const char* sym; ///< Port symbol - float value; ///< Control value + const char* sym; ///< Port symbol + float value; ///< Control value } Param; /** Port type (only float ports are supported) */ -typedef enum { - TYPE_CONTROL, - TYPE_AUDIO -} PortType; +typedef enum { TYPE_CONTROL, TYPE_AUDIO } PortType; /** Runtime port information */ typedef struct { - const LilvPort* lilv_port; ///< Port description - PortType type; ///< Datatype - uint32_t index; ///< Port index - float value; ///< Control value (if applicable) - bool is_input; ///< True iff an input port - bool optional; ///< True iff connection optional + const LilvPort* lilv_port; ///< Port description + PortType type; ///< Datatype + uint32_t index; ///< Port index + float value; ///< Control value (if applicable) + bool is_input; ///< True iff an input port + bool optional; ///< True iff connection optional } Port; /** Application state */ typedef struct { - LilvWorld* world; - const LilvPlugin* plugin; - LilvInstance* instance; - const char* in_path; - const char* out_path; - SNDFILE* in_file; - SNDFILE* out_file; - unsigned n_params; - Param* params; - unsigned n_ports; - unsigned n_audio_in; - unsigned n_audio_out; - Port* ports; + LilvWorld* world; + const LilvPlugin* plugin; + LilvInstance* instance; + const char* in_path; + const char* out_path; + SNDFILE* in_file; + SNDFILE* out_file; + unsigned n_params; + Param* params; + unsigned n_ports; + unsigned n_audio_in; + unsigned n_audio_out; + Port* ports; } LV2Apply; -static int fatal(LV2Apply* self, int status, const char* fmt, ...); +static int +fatal(LV2Apply* self, int status, const char* fmt, ...); /** Open a sound file with error handling. */ static SNDFILE* sopen(LV2Apply* self, const char* path, int mode, SF_INFO* fmt) { - SNDFILE* file = sf_open(path, mode, fmt); - const int st = sf_error(file); - if (st) { - fatal(self, 1, "Failed to open %s (%s)\n", path, sf_error_number(st)); - return NULL; - } - return file; + SNDFILE* file = sf_open(path, mode, fmt); + const int st = sf_error(file); + if (st) { + fatal(self, 1, "Failed to open %s (%s)\n", path, sf_error_number(st)); + return NULL; + } + return file; } /** Close a sound file with error handling. */ static void sclose(const char* path, SNDFILE* file) { - int st = 0; - if (file && (st = sf_close(file))) { - fatal(NULL, 1, "Failed to close %s (%s)\n", path, sf_error_number(st)); - } + int st = 0; + if (file && (st = sf_close(file))) { + fatal(NULL, 1, "Failed to close %s (%s)\n", path, sf_error_number(st)); + } } /** @@ -106,24 +104,24 @@ sclose(const char* path, SNDFILE* file) static bool sread(SNDFILE* file, unsigned file_chans, float* buf, unsigned buf_chans) { - const sf_count_t n_read = sf_readf_float(file, buf, 1); - for (unsigned i = file_chans - 1; i < buf_chans; ++i) { - buf[i] = buf[i % file_chans]; - } - return n_read == 1; + const sf_count_t n_read = sf_readf_float(file, buf, 1); + for (unsigned i = file_chans - 1; i < buf_chans; ++i) { + buf[i] = buf[i % file_chans]; + } + return n_read == 1; } /** Clean up all resources. */ static int cleanup(int status, LV2Apply* self) { - sclose(self->in_path, self->in_file); - sclose(self->out_path, self->out_file); - lilv_instance_free(self->instance); - lilv_world_free(self->world); - free(self->ports); - free(self->params); - return status; + sclose(self->in_path, self->in_file); + sclose(self->out_path, self->out_file); + lilv_instance_free(self->instance); + lilv_world_free(self->world); + free(self->ports); + free(self->params); + return status; } /** Print a fatal error and clean up for exit. */ @@ -131,12 +129,12 @@ LILV_LOG_FUNC(3, 4) static int fatal(LV2Apply* self, int status, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - fprintf(stderr, "error: "); - vfprintf(stderr, fmt, args); - va_end(args); - return self ? cleanup(status, self) : status; + va_list args; + va_start(args, fmt); + fprintf(stderr, "error: "); + vfprintf(stderr, fmt, args); + va_end(args); + return self ? cleanup(status, self) : status; } /** @@ -145,225 +143,226 @@ fatal(LV2Apply* self, int status, const char* fmt, ...) static int create_ports(LV2Apply* self) { - LilvWorld* world = self->world; - const uint32_t n_ports = lilv_plugin_get_num_ports(self->plugin); - - self->n_ports = n_ports; - self->ports = (Port*)calloc(self->n_ports, sizeof(Port)); - - /* Get default values for all ports */ - float* values = (float*)calloc(n_ports, sizeof(float)); - lilv_plugin_get_port_ranges_float(self->plugin, NULL, NULL, values); - - LilvNode* lv2_InputPort = lilv_new_uri(world, LV2_CORE__InputPort); - LilvNode* lv2_OutputPort = lilv_new_uri(world, LV2_CORE__OutputPort); - LilvNode* lv2_AudioPort = lilv_new_uri(world, LV2_CORE__AudioPort); - LilvNode* lv2_ControlPort = lilv_new_uri(world, LV2_CORE__ControlPort); - LilvNode* lv2_connectionOptional = lilv_new_uri(world, LV2_CORE__connectionOptional); - - for (uint32_t i = 0; i < n_ports; ++i) { - Port* port = &self->ports[i]; - const LilvPort* lport = lilv_plugin_get_port_by_index(self->plugin, i); - - port->lilv_port = lport; - port->index = i; - port->value = isnan(values[i]) ? 0.0f : values[i]; - port->optional = lilv_port_has_property( - self->plugin, lport, lv2_connectionOptional); - - /* Check if port is an input or output */ - if (lilv_port_is_a(self->plugin, lport, lv2_InputPort)) { - port->is_input = true; - } else if (!lilv_port_is_a(self->plugin, lport, lv2_OutputPort) && - !port->optional) { - return fatal(self, 1, "Port %u is neither input nor output\n", i); - } - - /* Check if port is an audio or control port */ - if (lilv_port_is_a(self->plugin, lport, lv2_ControlPort)) { - port->type = TYPE_CONTROL; - } else if (lilv_port_is_a(self->plugin, lport, lv2_AudioPort)) { - port->type = TYPE_AUDIO; - if (port->is_input) { - ++self->n_audio_in; - } else { - ++self->n_audio_out; - } - } else if (!port->optional) { - return fatal(self, 1, "Port %u has unsupported type\n", i); - } - } - - lilv_node_free(lv2_connectionOptional); - lilv_node_free(lv2_ControlPort); - lilv_node_free(lv2_AudioPort); - lilv_node_free(lv2_OutputPort); - lilv_node_free(lv2_InputPort); - free(values); - - return 0; + LilvWorld* world = self->world; + const uint32_t n_ports = lilv_plugin_get_num_ports(self->plugin); + + self->n_ports = n_ports; + self->ports = (Port*)calloc(self->n_ports, sizeof(Port)); + + /* Get default values for all ports */ + float* values = (float*)calloc(n_ports, sizeof(float)); + lilv_plugin_get_port_ranges_float(self->plugin, NULL, NULL, values); + + LilvNode* lv2_InputPort = lilv_new_uri(world, LV2_CORE__InputPort); + LilvNode* lv2_OutputPort = lilv_new_uri(world, LV2_CORE__OutputPort); + LilvNode* lv2_AudioPort = lilv_new_uri(world, LV2_CORE__AudioPort); + LilvNode* lv2_ControlPort = lilv_new_uri(world, LV2_CORE__ControlPort); + LilvNode* lv2_connectionOptional = + lilv_new_uri(world, LV2_CORE__connectionOptional); + + for (uint32_t i = 0; i < n_ports; ++i) { + Port* port = &self->ports[i]; + const LilvPort* lport = lilv_plugin_get_port_by_index(self->plugin, i); + + port->lilv_port = lport; + port->index = i; + port->value = isnan(values[i]) ? 0.0f : values[i]; + port->optional = + lilv_port_has_property(self->plugin, lport, lv2_connectionOptional); + + /* Check if port is an input or output */ + if (lilv_port_is_a(self->plugin, lport, lv2_InputPort)) { + port->is_input = true; + } else if (!lilv_port_is_a(self->plugin, lport, lv2_OutputPort) && + !port->optional) { + return fatal(self, 1, "Port %u is neither input nor output\n", i); + } + + /* Check if port is an audio or control port */ + if (lilv_port_is_a(self->plugin, lport, lv2_ControlPort)) { + port->type = TYPE_CONTROL; + } else if (lilv_port_is_a(self->plugin, lport, lv2_AudioPort)) { + port->type = TYPE_AUDIO; + if (port->is_input) { + ++self->n_audio_in; + } else { + ++self->n_audio_out; + } + } else if (!port->optional) { + return fatal(self, 1, "Port %u has unsupported type\n", i); + } + } + + lilv_node_free(lv2_connectionOptional); + lilv_node_free(lv2_ControlPort); + lilv_node_free(lv2_AudioPort); + lilv_node_free(lv2_OutputPort); + lilv_node_free(lv2_InputPort); + free(values); + + return 0; } static void print_version(void) { - printf( - "lv2apply (lilv) " LILV_VERSION "\n" - "Copyright 2007-2019 David Robillard <http://drobilla.net>\n" - "License: <http://www.opensource.org/licenses/isc-license>\n" - "This is free software: you are free to change and redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law.\n"); + printf("lv2apply (lilv) " LILV_VERSION "\n" + "Copyright 2007-2019 David Robillard <http://drobilla.net>\n" + "License: <http://www.opensource.org/licenses/isc-license>\n" + "This is free software: you are free to change and redistribute it.\n" + "There is NO WARRANTY, to the extent permitted by law.\n"); } static int print_usage(int status) { - fprintf(status ? stderr : stdout, - "Usage: lv2apply [OPTION]... PLUGIN_URI\n" - "Apply an LV2 plugin to an audio file.\n\n" - " -i IN_FILE Input file\n" - " -o OUT_FILE Output file\n" - " -c SYM VAL Control value\n" - " --help Display this help and exit\n" - " --version Display version information and exit\n"); - return status; + fprintf(status ? stderr : stdout, + "Usage: lv2apply [OPTION]... PLUGIN_URI\n" + "Apply an LV2 plugin to an audio file.\n\n" + " -i IN_FILE Input file\n" + " -o OUT_FILE Output file\n" + " -c SYM VAL Control value\n" + " --help Display this help and exit\n" + " --version Display version information and exit\n"); + return status; } int main(int argc, char** argv) { - LV2Apply self = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, 0, NULL - }; - - /* Parse command line arguments */ - const char* plugin_uri = NULL; - for (int i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "--version")) { - free(self.params); - print_version(); - return 0; - } - - if (!strcmp(argv[i], "--help")) { - free(self.params); - return print_usage(0); - } - - if (!strcmp(argv[i], "-i")) { - self.in_path = argv[++i]; - } else if (!strcmp(argv[i], "-o")) { - self.out_path = argv[++i]; - } else if (!strcmp(argv[i], "-c")) { - if (argc < i + 3) { - return fatal(&self, 1, "Missing argument for -c\n"); - } - self.params = (Param*)realloc(self.params, - ++self.n_params * sizeof(Param)); - self.params[self.n_params - 1].sym = argv[++i]; - self.params[self.n_params - 1].value = atof(argv[++i]); - } else if (argv[i][0] == '-') { - free(self.params); - return print_usage(1); - } else if (i == argc - 1) { - plugin_uri = argv[i]; - } - } - - /* Check that required arguments are given */ - if (!self.in_path || !self.out_path || !plugin_uri) { - free(self.params); - return print_usage(1); - } - - /* Create world and plugin URI */ - self.world = lilv_world_new(); - LilvNode* uri = lilv_new_uri(self.world, plugin_uri); - if (!uri) { - return fatal(&self, 2, "Invalid plugin URI <%s>\n", plugin_uri); - } - - /* Discover world */ - lilv_world_load_all(self.world); - - /* Get plugin */ - const LilvPlugins* plugins = lilv_world_get_all_plugins(self.world); - const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, uri); - lilv_node_free(uri); - if (!(self.plugin = plugin)) { - return fatal(&self, 3, "Plugin <%s> not found\n", plugin_uri); - } - - /* Open input file */ - SF_INFO in_fmt = { 0, 0, 0, 0, 0, 0 }; - if (!(self.in_file = sopen(&self, self.in_path, SFM_READ, &in_fmt))) { - return 4; - } - - /* Create port structures */ - if (create_ports(&self)) { - return 5; - } - - if (self.n_audio_in == 0 || - (in_fmt.channels != (int)self.n_audio_in && in_fmt.channels != 1)) { - return fatal(&self, 6, "Unable to map %d inputs to %u ports\n", - in_fmt.channels, self.n_audio_in); - } - - /* Set control values */ - for (unsigned i = 0; i < self.n_params; ++i) { - const Param* param = &self.params[i]; - LilvNode* sym = lilv_new_string(self.world, param->sym); - const LilvPort* port = lilv_plugin_get_port_by_symbol(plugin, sym); - lilv_node_free(sym); - if (!port) { - return fatal(&self, 7, "Unknown port `%s'\n", param->sym); - } - - self.ports[lilv_port_get_index(plugin, port)].value = param->value; - } - - /* Open output file */ - SF_INFO out_fmt = in_fmt; - out_fmt.channels = self.n_audio_out; - if (!(self.out_file = sopen(&self, self.out_path, SFM_WRITE, &out_fmt))) { - free(self.ports); - return 8; - } - - /* Instantiate plugin and connect ports */ - const uint32_t n_ports = lilv_plugin_get_num_ports(plugin); - float in_buf[self.n_audio_in > 0 ? self.n_audio_in : 1]; - float out_buf[self.n_audio_out > 0 ? self.n_audio_out : 1]; - self.instance = lilv_plugin_instantiate( - self.plugin, in_fmt.samplerate, NULL); - for (uint32_t p = 0, i = 0, o = 0; p < n_ports; ++p) { - if (self.ports[p].type == TYPE_CONTROL) { - lilv_instance_connect_port(self.instance, p, &self.ports[p].value); - } else if (self.ports[p].type == TYPE_AUDIO) { - if (self.ports[p].is_input) { - lilv_instance_connect_port(self.instance, p, in_buf + i++); - } else { - lilv_instance_connect_port(self.instance, p, out_buf + o++); - } - } else { - lilv_instance_connect_port(self.instance, p, NULL); - } - } - - /* Ports are now connected to buffers in interleaved format, so we can run - a single frame at a time and avoid having to interleave buffers to - read/write from/to sndfile. */ - - lilv_instance_activate(self.instance); - while (sread(self.in_file, in_fmt.channels, in_buf, self.n_audio_in)) { - lilv_instance_run(self.instance, 1); - if (sf_writef_float(self.out_file, out_buf, 1) != 1) { - return fatal(&self, 9, "Failed to write to output file\n"); - } - } - lilv_instance_deactivate(self.instance); - - return cleanup(0, &self); + LV2Apply self = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, 0, NULL}; + + /* Parse command line arguments */ + const char* plugin_uri = NULL; + for (int i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "--version")) { + free(self.params); + print_version(); + return 0; + } + + if (!strcmp(argv[i], "--help")) { + free(self.params); + return print_usage(0); + } + + if (!strcmp(argv[i], "-i")) { + self.in_path = argv[++i]; + } else if (!strcmp(argv[i], "-o")) { + self.out_path = argv[++i]; + } else if (!strcmp(argv[i], "-c")) { + if (argc < i + 3) { + return fatal(&self, 1, "Missing argument for -c\n"); + } + self.params = + (Param*)realloc(self.params, ++self.n_params * sizeof(Param)); + self.params[self.n_params - 1].sym = argv[++i]; + self.params[self.n_params - 1].value = atof(argv[++i]); + } else if (argv[i][0] == '-') { + free(self.params); + return print_usage(1); + } else if (i == argc - 1) { + plugin_uri = argv[i]; + } + } + + /* Check that required arguments are given */ + if (!self.in_path || !self.out_path || !plugin_uri) { + free(self.params); + return print_usage(1); + } + + /* Create world and plugin URI */ + self.world = lilv_world_new(); + LilvNode* uri = lilv_new_uri(self.world, plugin_uri); + if (!uri) { + return fatal(&self, 2, "Invalid plugin URI <%s>\n", plugin_uri); + } + + /* Discover world */ + lilv_world_load_all(self.world); + + /* Get plugin */ + const LilvPlugins* plugins = lilv_world_get_all_plugins(self.world); + const LilvPlugin* plugin = lilv_plugins_get_by_uri(plugins, uri); + lilv_node_free(uri); + if (!(self.plugin = plugin)) { + return fatal(&self, 3, "Plugin <%s> not found\n", plugin_uri); + } + + /* Open input file */ + SF_INFO in_fmt = {0, 0, 0, 0, 0, 0}; + if (!(self.in_file = sopen(&self, self.in_path, SFM_READ, &in_fmt))) { + return 4; + } + + /* Create port structures */ + if (create_ports(&self)) { + return 5; + } + + if (self.n_audio_in == 0 || + (in_fmt.channels != (int)self.n_audio_in && in_fmt.channels != 1)) { + return fatal(&self, + 6, + "Unable to map %d inputs to %u ports\n", + in_fmt.channels, + self.n_audio_in); + } + + /* Set control values */ + for (unsigned i = 0; i < self.n_params; ++i) { + const Param* param = &self.params[i]; + LilvNode* sym = lilv_new_string(self.world, param->sym); + const LilvPort* port = lilv_plugin_get_port_by_symbol(plugin, sym); + lilv_node_free(sym); + if (!port) { + return fatal(&self, 7, "Unknown port `%s'\n", param->sym); + } + + self.ports[lilv_port_get_index(plugin, port)].value = param->value; + } + + /* Open output file */ + SF_INFO out_fmt = in_fmt; + out_fmt.channels = self.n_audio_out; + if (!(self.out_file = sopen(&self, self.out_path, SFM_WRITE, &out_fmt))) { + free(self.ports); + return 8; + } + + /* Instantiate plugin and connect ports */ + const uint32_t n_ports = lilv_plugin_get_num_ports(plugin); + float in_buf[self.n_audio_in > 0 ? self.n_audio_in : 1]; + float out_buf[self.n_audio_out > 0 ? self.n_audio_out : 1]; + self.instance = lilv_plugin_instantiate(self.plugin, in_fmt.samplerate, NULL); + for (uint32_t p = 0, i = 0, o = 0; p < n_ports; ++p) { + if (self.ports[p].type == TYPE_CONTROL) { + lilv_instance_connect_port(self.instance, p, &self.ports[p].value); + } else if (self.ports[p].type == TYPE_AUDIO) { + if (self.ports[p].is_input) { + lilv_instance_connect_port(self.instance, p, in_buf + i++); + } else { + lilv_instance_connect_port(self.instance, p, out_buf + o++); + } + } else { + lilv_instance_connect_port(self.instance, p, NULL); + } + } + + /* Ports are now connected to buffers in interleaved format, so we can run + a single frame at a time and avoid having to interleave buffers to + read/write from/to sndfile. */ + + lilv_instance_activate(self.instance); + while (sread(self.in_file, in_fmt.channels, in_buf, self.n_audio_in)) { + lilv_instance_run(self.instance, 1); + if (sf_writef_float(self.out_file, out_buf, 1) != 1) { + return fatal(&self, 9, "Failed to write to output file\n"); + } + } + lilv_instance_deactivate(self.instance); + + return cleanup(0, &self); } diff --git a/utils/lv2bench.c b/utils/lv2bench.c index 000f062..7365b5b 100644 --- a/utils/lv2bench.c +++ b/utils/lv2bench.c @@ -47,236 +47,238 @@ static bool full_output = false; static void print_version(void) { - printf( - "lv2bench (lilv) " LILV_VERSION "\n" - "Copyright 2012-2019 David Robillard <http://drobilla.net>\n" - "License: <http://www.opensource.org/licenses/isc-license>\n" - "This is free software: you are free to change and redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law.\n"); + printf("lv2bench (lilv) " LILV_VERSION "\n" + "Copyright 2012-2019 David Robillard <http://drobilla.net>\n" + "License: <http://www.opensource.org/licenses/isc-license>\n" + "This is free software: you are free to change and redistribute it.\n" + "There is NO WARRANTY, to the extent permitted by law.\n"); } static void print_usage(void) { - printf("lv2bench - Benchmark all installed and supported LV2 plugins.\n"); - printf("Usage: lv2bench [OPTIONS] [PLUGIN_URI]\n"); - printf("\n"); - printf(" -b BLOCK_SIZE Specify block size, in audio frames.\n"); - printf(" -f, --full Full plottable output.\n"); - printf(" -h, --help Display this help and exit.\n"); - printf(" -n FRAMES Total number of audio frames to process\n"); - printf(" --version Display version information and exit\n"); + printf("lv2bench - Benchmark all installed and supported LV2 plugins.\n"); + printf("Usage: lv2bench [OPTIONS] [PLUGIN_URI]\n"); + printf("\n"); + printf(" -b BLOCK_SIZE Specify block size, in audio frames.\n"); + printf(" -f, --full Full plottable output.\n"); + printf(" -h, --help Display this help and exit.\n"); + printf(" -n FRAMES Total number of audio frames to process\n"); + printf(" --version Display version information and exit\n"); } static double bench(const LilvPlugin* p, uint32_t sample_count, uint32_t block_size) { - URITable uri_table; - uri_table_init(&uri_table); - - LV2_URID_Map map = { &uri_table, uri_table_map }; - LV2_Feature map_feature = { LV2_URID_MAP_URI, &map }; - LV2_URID_Unmap unmap = { &uri_table, uri_table_unmap }; - LV2_Feature unmap_feature = { LV2_URID_UNMAP_URI, &unmap }; - const LV2_Feature* features[] = { &map_feature, &unmap_feature, NULL }; - - float* const buf = (float*)calloc(block_size * 2, sizeof(float)); - float* const in = buf; - float* const out = buf + block_size; - if (!buf) { - fprintf(stderr, "Out of memory\n"); - return 0.0; - } - - const size_t atom_capacity = 1024; - - LV2_Atom_Sequence seq_in = { - { sizeof(LV2_Atom_Sequence_Body), - uri_table_map(&uri_table, LV2_ATOM__Sequence) }, - { 0, 0 } }; - - LV2_Atom_Sequence* seq_out = (LV2_Atom_Sequence*)malloc( - sizeof(LV2_Atom_Sequence) + atom_capacity); - - const char* uri = lilv_node_as_string(lilv_plugin_get_uri(p)); - LilvNodes* required = lilv_plugin_get_required_features(p); - LILV_FOREACH(nodes, i, required) { - const LilvNode* feature = lilv_nodes_get(required, i); - if (!lilv_node_equals(feature, urid_map)) { - fprintf(stderr, "<%s> requires feature <%s>, skipping\n", - uri, lilv_node_as_uri(feature)); - free(seq_out); - free(buf); - uri_table_destroy(&uri_table); - return 0.0; - } - } - - LilvInstance* instance = lilv_plugin_instantiate(p, 48000.0, features); - if (!instance) { - fprintf(stderr, "Failed to instantiate <%s>\n", - lilv_node_as_uri(lilv_plugin_get_uri(p))); - free(seq_out); - free(buf); - uri_table_destroy(&uri_table); - return 0.0; - } - - const uint32_t n_ports = lilv_plugin_get_num_ports(p); - float* const mins = (float*)calloc(n_ports, sizeof(float)); - float* const maxes = (float*)calloc(n_ports, sizeof(float)); - float* const controls = (float*)calloc(n_ports, sizeof(float)); - lilv_plugin_get_port_ranges_float(p, mins, maxes, controls); - - for (uint32_t index = 0; index < n_ports; ++index) { - const LilvPort* port = lilv_plugin_get_port_by_index(p, index); - if (lilv_port_is_a(p, port, lv2_ControlPort)) { - if (isnan(controls[index])) { - if (!isnan(mins[index])) { - controls[index] = mins[index]; - } else if (!isnan(maxes[index])) { - controls[index] = maxes[index]; - } else { - controls[index] = 0.0; - } - } - lilv_instance_connect_port(instance, index, &controls[index]); - } else if (lilv_port_is_a(p, port, lv2_AudioPort) || - lilv_port_is_a(p, port, lv2_CVPort)) { - if (lilv_port_is_a(p, port, lv2_InputPort)) { - lilv_instance_connect_port(instance, index, in); - } else if (lilv_port_is_a(p, port, lv2_OutputPort)) { - lilv_instance_connect_port(instance, index, out); - } else { - fprintf(stderr, "<%s> port %u neither input nor output, skipping\n", - uri, index); - lilv_instance_free(instance); - free(seq_out); - free(buf); - free(controls); - uri_table_destroy(&uri_table); - return 0.0; - } - } else if (lilv_port_is_a(p, port, atom_AtomPort)) { - if (lilv_port_is_a(p, port, lv2_InputPort)) { - lilv_instance_connect_port(instance, index, &seq_in); - } else { - lilv_instance_connect_port(instance, index, seq_out); - } - } else { - fprintf(stderr, "<%s> port %u has unknown type, skipping\n", - uri, index); - lilv_instance_free(instance); - free(seq_out); - free(buf); - free(controls); - uri_table_destroy(&uri_table); - return 0.0; - } - } - - lilv_instance_activate(instance); - - struct timespec ts = bench_start(); - for (uint32_t i = 0; i < (sample_count / block_size); ++i) { - seq_in.atom.size = sizeof(LV2_Atom_Sequence_Body); - seq_in.atom.type = uri_table_map(&uri_table, LV2_ATOM__Sequence); - seq_out->atom.size = atom_capacity; - seq_out->atom.type = uri_table_map(&uri_table, LV2_ATOM__Chunk); - - lilv_instance_run(instance, block_size); - } - const double elapsed = bench_end(&ts); - - lilv_instance_deactivate(instance); - lilv_instance_free(instance); - free(controls); - free(maxes); - free(mins); - free(seq_out); - - uri_table_destroy(&uri_table); - - if (full_output) { - printf("%u %u ", block_size, sample_count); - } - printf("%lf %s\n", elapsed, uri); - - free(buf); - return elapsed; + URITable uri_table; + uri_table_init(&uri_table); + + LV2_URID_Map map = {&uri_table, uri_table_map}; + LV2_Feature map_feature = {LV2_URID_MAP_URI, &map}; + LV2_URID_Unmap unmap = {&uri_table, uri_table_unmap}; + LV2_Feature unmap_feature = {LV2_URID_UNMAP_URI, &unmap}; + const LV2_Feature* features[] = {&map_feature, &unmap_feature, NULL}; + + float* const buf = (float*)calloc(block_size * 2, sizeof(float)); + float* const in = buf; + float* const out = buf + block_size; + if (!buf) { + fprintf(stderr, "Out of memory\n"); + return 0.0; + } + + const size_t atom_capacity = 1024; + + LV2_Atom_Sequence seq_in = {{sizeof(LV2_Atom_Sequence_Body), + uri_table_map(&uri_table, LV2_ATOM__Sequence)}, + {0, 0}}; + + LV2_Atom_Sequence* seq_out = + (LV2_Atom_Sequence*)malloc(sizeof(LV2_Atom_Sequence) + atom_capacity); + + const char* uri = lilv_node_as_string(lilv_plugin_get_uri(p)); + LilvNodes* required = lilv_plugin_get_required_features(p); + LILV_FOREACH (nodes, i, required) { + const LilvNode* feature = lilv_nodes_get(required, i); + if (!lilv_node_equals(feature, urid_map)) { + fprintf(stderr, + "<%s> requires feature <%s>, skipping\n", + uri, + lilv_node_as_uri(feature)); + free(seq_out); + free(buf); + uri_table_destroy(&uri_table); + return 0.0; + } + } + + LilvInstance* instance = lilv_plugin_instantiate(p, 48000.0, features); + if (!instance) { + fprintf(stderr, + "Failed to instantiate <%s>\n", + lilv_node_as_uri(lilv_plugin_get_uri(p))); + free(seq_out); + free(buf); + uri_table_destroy(&uri_table); + return 0.0; + } + + const uint32_t n_ports = lilv_plugin_get_num_ports(p); + float* const mins = (float*)calloc(n_ports, sizeof(float)); + float* const maxes = (float*)calloc(n_ports, sizeof(float)); + float* const controls = (float*)calloc(n_ports, sizeof(float)); + lilv_plugin_get_port_ranges_float(p, mins, maxes, controls); + + for (uint32_t index = 0; index < n_ports; ++index) { + const LilvPort* port = lilv_plugin_get_port_by_index(p, index); + if (lilv_port_is_a(p, port, lv2_ControlPort)) { + if (isnan(controls[index])) { + if (!isnan(mins[index])) { + controls[index] = mins[index]; + } else if (!isnan(maxes[index])) { + controls[index] = maxes[index]; + } else { + controls[index] = 0.0; + } + } + lilv_instance_connect_port(instance, index, &controls[index]); + } else if (lilv_port_is_a(p, port, lv2_AudioPort) || + lilv_port_is_a(p, port, lv2_CVPort)) { + if (lilv_port_is_a(p, port, lv2_InputPort)) { + lilv_instance_connect_port(instance, index, in); + } else if (lilv_port_is_a(p, port, lv2_OutputPort)) { + lilv_instance_connect_port(instance, index, out); + } else { + fprintf(stderr, + "<%s> port %u neither input nor output, skipping\n", + uri, + index); + lilv_instance_free(instance); + free(seq_out); + free(buf); + free(controls); + uri_table_destroy(&uri_table); + return 0.0; + } + } else if (lilv_port_is_a(p, port, atom_AtomPort)) { + if (lilv_port_is_a(p, port, lv2_InputPort)) { + lilv_instance_connect_port(instance, index, &seq_in); + } else { + lilv_instance_connect_port(instance, index, seq_out); + } + } else { + fprintf(stderr, "<%s> port %u has unknown type, skipping\n", uri, index); + lilv_instance_free(instance); + free(seq_out); + free(buf); + free(controls); + uri_table_destroy(&uri_table); + return 0.0; + } + } + + lilv_instance_activate(instance); + + struct timespec ts = bench_start(); + for (uint32_t i = 0; i < (sample_count / block_size); ++i) { + seq_in.atom.size = sizeof(LV2_Atom_Sequence_Body); + seq_in.atom.type = uri_table_map(&uri_table, LV2_ATOM__Sequence); + seq_out->atom.size = atom_capacity; + seq_out->atom.type = uri_table_map(&uri_table, LV2_ATOM__Chunk); + + lilv_instance_run(instance, block_size); + } + const double elapsed = bench_end(&ts); + + lilv_instance_deactivate(instance); + lilv_instance_free(instance); + free(controls); + free(maxes); + free(mins); + free(seq_out); + + uri_table_destroy(&uri_table); + + if (full_output) { + printf("%u %u ", block_size, sample_count); + } + printf("%lf %s\n", elapsed, uri); + + free(buf); + return elapsed; } int main(int argc, char** argv) { - uint32_t block_size = 512; - uint32_t sample_count = (1 << 19); - - int a = 1; - for (; a < argc; ++a) { - if (!strcmp(argv[a], "--version")) { - print_version(); - return 0; - } - - if (!strcmp(argv[a], "--help")) { - print_usage(); - return 0; - } - - if (!strcmp(argv[a], "-f")) { - full_output = true; - } else if (!strcmp(argv[a], "-n") && (a + 1 < argc)) { - sample_count = atoi(argv[++a]); - } else if (!strcmp(argv[a], "-b") && (a + 1 < argc)) { - block_size = atoi(argv[++a]); - } else if (argv[a][0] != '-') { - break; - } else { - print_usage(); - return 1; - } - } - - const char* const plugin_uri_str = (a < argc ? argv[a++] : NULL); - - LilvWorld* world = lilv_world_new(); - lilv_world_load_all(world); - - atom_AtomPort = lilv_new_uri(world, LV2_ATOM__AtomPort); - atom_Sequence = lilv_new_uri(world, LV2_ATOM__Sequence); - lv2_AudioPort = lilv_new_uri(world, LV2_CORE__AudioPort); - lv2_CVPort = lilv_new_uri(world, LV2_CORE__CVPort); - lv2_ControlPort = lilv_new_uri(world, LV2_CORE__ControlPort); - lv2_InputPort = lilv_new_uri(world, LV2_CORE__InputPort); - lv2_OutputPort = lilv_new_uri(world, LV2_CORE__OutputPort); - urid_map = lilv_new_uri(world, LV2_URID__map); - - if (full_output) { - printf("# Block Samples Time Plugin\n"); - } - - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - if (plugin_uri_str) { - LilvNode* uri = lilv_new_uri(world, plugin_uri_str); - bench(lilv_plugins_get_by_uri(plugins, uri), sample_count, block_size); - lilv_node_free(uri); - } else { - LILV_FOREACH(plugins, i, plugins) { - bench(lilv_plugins_get(plugins, i), sample_count, block_size); - } - } - - lilv_node_free(urid_map); - lilv_node_free(lv2_OutputPort); - lilv_node_free(lv2_InputPort); - lilv_node_free(lv2_ControlPort); - lilv_node_free(lv2_CVPort); - lilv_node_free(lv2_AudioPort); - lilv_node_free(atom_Sequence); - lilv_node_free(atom_AtomPort); - - lilv_world_free(world); - - return 0; + uint32_t block_size = 512; + uint32_t sample_count = (1 << 19); + + int a = 1; + for (; a < argc; ++a) { + if (!strcmp(argv[a], "--version")) { + print_version(); + return 0; + } + + if (!strcmp(argv[a], "--help")) { + print_usage(); + return 0; + } + + if (!strcmp(argv[a], "-f")) { + full_output = true; + } else if (!strcmp(argv[a], "-n") && (a + 1 < argc)) { + sample_count = atoi(argv[++a]); + } else if (!strcmp(argv[a], "-b") && (a + 1 < argc)) { + block_size = atoi(argv[++a]); + } else if (argv[a][0] != '-') { + break; + } else { + print_usage(); + return 1; + } + } + + const char* const plugin_uri_str = (a < argc ? argv[a++] : NULL); + + LilvWorld* world = lilv_world_new(); + lilv_world_load_all(world); + + atom_AtomPort = lilv_new_uri(world, LV2_ATOM__AtomPort); + atom_Sequence = lilv_new_uri(world, LV2_ATOM__Sequence); + lv2_AudioPort = lilv_new_uri(world, LV2_CORE__AudioPort); + lv2_CVPort = lilv_new_uri(world, LV2_CORE__CVPort); + lv2_ControlPort = lilv_new_uri(world, LV2_CORE__ControlPort); + lv2_InputPort = lilv_new_uri(world, LV2_CORE__InputPort); + lv2_OutputPort = lilv_new_uri(world, LV2_CORE__OutputPort); + urid_map = lilv_new_uri(world, LV2_URID__map); + + if (full_output) { + printf("# Block Samples Time Plugin\n"); + } + + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + if (plugin_uri_str) { + LilvNode* uri = lilv_new_uri(world, plugin_uri_str); + bench(lilv_plugins_get_by_uri(plugins, uri), sample_count, block_size); + lilv_node_free(uri); + } else { + LILV_FOREACH (plugins, i, plugins) { + bench(lilv_plugins_get(plugins, i), sample_count, block_size); + } + } + + lilv_node_free(urid_map); + lilv_node_free(lv2_OutputPort); + lilv_node_free(lv2_InputPort); + lilv_node_free(lv2_ControlPort); + lilv_node_free(lv2_CVPort); + lilv_node_free(lv2_AudioPort); + lilv_node_free(atom_Sequence); + lilv_node_free(atom_AtomPort); + + lilv_world_free(world); + + return 0; } diff --git a/utils/lv2info.c b/utils/lv2info.c index f5dd621..0c79268 100644 --- a/utils/lv2info.c +++ b/utils/lv2info.c @@ -45,417 +45,412 @@ print_port(const LilvPlugin* p, float* maxes, float* defaults) { - const LilvPort* port = lilv_plugin_get_port_by_index(p, index); - - printf("\n\tPort %u:\n", index); - - if (!port) { - printf("\t\tERROR: Illegal/nonexistent port\n"); - return; - } - - bool first = true; - - const LilvNodes* classes = lilv_port_get_classes(p, port); - printf("\t\tType: "); - LILV_FOREACH(nodes, i, classes) { - const LilvNode* value = lilv_nodes_get(classes, i); - if (!first) { - printf("\n\t\t "); - } - printf("%s", lilv_node_as_uri(value)); - first = false; - } - - if (lilv_port_is_a(p, port, event_class)) { - LilvNodes* supported = lilv_port_get_value( - p, port, supports_event_pred); - if (lilv_nodes_size(supported) > 0) { - printf("\n\t\tSupported events:\n"); - LILV_FOREACH(nodes, i, supported) { - const LilvNode* value = lilv_nodes_get(supported, i); - printf("\t\t\t%s\n", lilv_node_as_uri(value)); - } - } - lilv_nodes_free(supported); - } - - LilvScalePoints* points = lilv_port_get_scale_points(p, port); - if (points) { - printf("\n\t\tScale Points:\n"); - } - LILV_FOREACH(scale_points, i, points) { - const LilvScalePoint* point = lilv_scale_points_get(points, i); - printf("\t\t\t%s = \"%s\"\n", - lilv_node_as_string(lilv_scale_point_get_value(point)), - lilv_node_as_string(lilv_scale_point_get_label(point))); - } - lilv_scale_points_free(points); - - const LilvNode* sym = lilv_port_get_symbol(p, port); - printf("\n\t\tSymbol: %s\n", lilv_node_as_string(sym)); - - LilvNode* name = lilv_port_get_name(p, port); - printf("\t\tName: %s\n", lilv_node_as_string(name)); - lilv_node_free(name); - - LilvNodes* groups = lilv_port_get_value(p, port, group_pred); - if (lilv_nodes_size(groups) > 0) { - printf("\t\tGroup: %s\n", - lilv_node_as_string(lilv_nodes_get_first(groups))); - } - lilv_nodes_free(groups); - - LilvNodes* designations = lilv_port_get_value(p, port, designation_pred); - if (lilv_nodes_size(designations) > 0) { - printf("\t\tDesignation: %s\n", - lilv_node_as_string(lilv_nodes_get_first(designations))); - } - lilv_nodes_free(designations); - - if (lilv_port_is_a(p, port, control_class)) { - if (!isnan(mins[index])) { - printf("\t\tMinimum: %f\n", mins[index]); - } - if (!isnan(maxes[index])) { - printf("\t\tMaximum: %f\n", maxes[index]); - } - if (!isnan(defaults[index])) { - printf("\t\tDefault: %f\n", defaults[index]); - } - } - - LilvNodes* properties = lilv_port_get_properties(p, port); - if (lilv_nodes_size(properties) > 0) { - printf("\t\tProperties: "); - } - first = true; - LILV_FOREACH(nodes, i, properties) { - if (!first) { - printf("\t\t "); - } - printf("%s\n", lilv_node_as_uri(lilv_nodes_get(properties, i))); - first = false; - } - if (lilv_nodes_size(properties) > 0) { - printf("\n"); - } - lilv_nodes_free(properties); + const LilvPort* port = lilv_plugin_get_port_by_index(p, index); + + printf("\n\tPort %u:\n", index); + + if (!port) { + printf("\t\tERROR: Illegal/nonexistent port\n"); + return; + } + + bool first = true; + + const LilvNodes* classes = lilv_port_get_classes(p, port); + printf("\t\tType: "); + LILV_FOREACH (nodes, i, classes) { + const LilvNode* value = lilv_nodes_get(classes, i); + if (!first) { + printf("\n\t\t "); + } + printf("%s", lilv_node_as_uri(value)); + first = false; + } + + if (lilv_port_is_a(p, port, event_class)) { + LilvNodes* supported = lilv_port_get_value(p, port, supports_event_pred); + if (lilv_nodes_size(supported) > 0) { + printf("\n\t\tSupported events:\n"); + LILV_FOREACH (nodes, i, supported) { + const LilvNode* value = lilv_nodes_get(supported, i); + printf("\t\t\t%s\n", lilv_node_as_uri(value)); + } + } + lilv_nodes_free(supported); + } + + LilvScalePoints* points = lilv_port_get_scale_points(p, port); + if (points) { + printf("\n\t\tScale Points:\n"); + } + LILV_FOREACH (scale_points, i, points) { + const LilvScalePoint* point = lilv_scale_points_get(points, i); + printf("\t\t\t%s = \"%s\"\n", + lilv_node_as_string(lilv_scale_point_get_value(point)), + lilv_node_as_string(lilv_scale_point_get_label(point))); + } + lilv_scale_points_free(points); + + const LilvNode* sym = lilv_port_get_symbol(p, port); + printf("\n\t\tSymbol: %s\n", lilv_node_as_string(sym)); + + LilvNode* name = lilv_port_get_name(p, port); + printf("\t\tName: %s\n", lilv_node_as_string(name)); + lilv_node_free(name); + + LilvNodes* groups = lilv_port_get_value(p, port, group_pred); + if (lilv_nodes_size(groups) > 0) { + printf("\t\tGroup: %s\n", + lilv_node_as_string(lilv_nodes_get_first(groups))); + } + lilv_nodes_free(groups); + + LilvNodes* designations = lilv_port_get_value(p, port, designation_pred); + if (lilv_nodes_size(designations) > 0) { + printf("\t\tDesignation: %s\n", + lilv_node_as_string(lilv_nodes_get_first(designations))); + } + lilv_nodes_free(designations); + + if (lilv_port_is_a(p, port, control_class)) { + if (!isnan(mins[index])) { + printf("\t\tMinimum: %f\n", mins[index]); + } + if (!isnan(maxes[index])) { + printf("\t\tMaximum: %f\n", maxes[index]); + } + if (!isnan(defaults[index])) { + printf("\t\tDefault: %f\n", defaults[index]); + } + } + + LilvNodes* properties = lilv_port_get_properties(p, port); + if (lilv_nodes_size(properties) > 0) { + printf("\t\tProperties: "); + } + first = true; + LILV_FOREACH (nodes, i, properties) { + if (!first) { + printf("\t\t "); + } + printf("%s\n", lilv_node_as_uri(lilv_nodes_get(properties, i))); + first = false; + } + if (lilv_nodes_size(properties) > 0) { + printf("\n"); + } + lilv_nodes_free(properties); } static void -print_plugin(LilvWorld* world, - const LilvPlugin* p) +print_plugin(LilvWorld* world, const LilvPlugin* p) { - LilvNode* val = NULL; - - printf("%s\n\n", lilv_node_as_uri(lilv_plugin_get_uri(p))); - - val = lilv_plugin_get_name(p); - if (val) { - printf("\tName: %s\n", lilv_node_as_string(val)); - lilv_node_free(val); - } - - const LilvPluginClass* pclass = lilv_plugin_get_class(p); - const LilvNode* class_label = lilv_plugin_class_get_label(pclass); - if (class_label) { - printf("\tClass: %s\n", lilv_node_as_string(class_label)); - } - - val = lilv_plugin_get_author_name(p); - if (val) { - printf("\tAuthor: %s\n", lilv_node_as_string(val)); - lilv_node_free(val); - } - - val = lilv_plugin_get_author_email(p); - if (val) { - printf("\tAuthor Email: %s\n", lilv_node_as_uri(val)); - lilv_node_free(val); - } - - val = lilv_plugin_get_author_homepage(p); - if (val) { - printf("\tAuthor Homepage: %s\n", lilv_node_as_uri(val)); - lilv_node_free(val); - } - - if (lilv_plugin_has_latency(p)) { - uint32_t latency_port = lilv_plugin_get_latency_port_index(p); - printf("\tHas latency: yes, reported by port %u\n", latency_port); - } else { - printf("\tHas latency: no\n"); - } - - printf("\tBundle: %s\n", - lilv_node_as_uri(lilv_plugin_get_bundle_uri(p))); - - const LilvNode* binary_uri = lilv_plugin_get_library_uri(p); - if (binary_uri) { - printf("\tBinary: %s\n", - lilv_node_as_uri(lilv_plugin_get_library_uri(p))); - } - - LilvUIs* uis = lilv_plugin_get_uis(p); - if (lilv_nodes_size(uis) > 0) { - printf("\tUIs:\n"); - LILV_FOREACH(uis, i, uis) { - const LilvUI* ui = lilv_uis_get(uis, i); - printf("\t\t%s\n", lilv_node_as_uri(lilv_ui_get_uri(ui))); - - const char* binary = lilv_node_as_uri(lilv_ui_get_binary_uri(ui)); - - const LilvNodes* types = lilv_ui_get_classes(ui); - LILV_FOREACH(nodes, t, types) { - printf("\t\t\tClass: %s\n", - lilv_node_as_uri(lilv_nodes_get(types, t))); - } - - if (binary) { - printf("\t\t\tBinary: %s\n", binary); - } - - printf("\t\t\tBundle: %s\n", - lilv_node_as_uri(lilv_ui_get_bundle_uri(ui))); - } - } - lilv_uis_free(uis); - - printf("\tData URIs: "); - const LilvNodes* data_uris = lilv_plugin_get_data_uris(p); - bool first = true; - LILV_FOREACH(nodes, i, data_uris) { - if (!first) { - printf("\n\t "); - } - printf("%s", lilv_node_as_uri(lilv_nodes_get(data_uris, i))); - first = false; - } - printf("\n"); - - /* Required Features */ - - LilvNodes* features = lilv_plugin_get_required_features(p); - if (features) { - printf("\tRequired Features: "); - } - first = true; - LILV_FOREACH(nodes, i, features) { - if (!first) { - printf("\n\t "); - } - printf("%s", lilv_node_as_uri(lilv_nodes_get(features, i))); - first = false; - } - if (features) { - printf("\n"); - } - lilv_nodes_free(features); - - /* Optional Features */ - - features = lilv_plugin_get_optional_features(p); - if (features) { - printf("\tOptional Features: "); - } - first = true; - LILV_FOREACH(nodes, i, features) { - if (!first) { - printf("\n\t "); - } - printf("%s", lilv_node_as_uri(lilv_nodes_get(features, i))); - first = false; - } - if (features) { - printf("\n"); - } - lilv_nodes_free(features); - - /* Extension Data */ - - LilvNodes* data = lilv_plugin_get_extension_data(p); - if (data) { - printf("\tExtension Data: "); - } - first = true; - LILV_FOREACH(nodes, i, data) { - if (!first) { - printf("\n\t "); - } - printf("%s", lilv_node_as_uri(lilv_nodes_get(data, i))); - first = false; - } - if (data) { - printf("\n"); - } - lilv_nodes_free(data); - - /* Presets */ - - LilvNodes* presets = lilv_plugin_get_related(p, preset_class); - if (presets) { - printf("\tPresets: \n"); - } - LILV_FOREACH(nodes, i, presets) { - const LilvNode* preset = lilv_nodes_get(presets, i); - lilv_world_load_resource(world, preset); - LilvNodes* titles = lilv_world_find_nodes( - world, preset, label_pred, NULL); - if (titles) { - const LilvNode* title = lilv_nodes_get_first(titles); - printf("\t %s\n", lilv_node_as_string(title)); - lilv_nodes_free(titles); - } else { - fprintf(stderr, "Preset <%s> has no rdfs:label\n", - lilv_node_as_string(lilv_nodes_get(presets, i))); - } - } - lilv_nodes_free(presets); - - /* Ports */ - - const uint32_t num_ports = lilv_plugin_get_num_ports(p); - float* mins = (float*)calloc(num_ports, sizeof(float)); - float* maxes = (float*)calloc(num_ports, sizeof(float)); - float* defaults = (float*)calloc(num_ports, sizeof(float)); - lilv_plugin_get_port_ranges_float(p, mins, maxes, defaults); - - for (uint32_t i = 0; i < num_ports; ++i) { - print_port(p, i, mins, maxes, defaults); - } - - free(mins); - free(maxes); - free(defaults); + LilvNode* val = NULL; + + printf("%s\n\n", lilv_node_as_uri(lilv_plugin_get_uri(p))); + + val = lilv_plugin_get_name(p); + if (val) { + printf("\tName: %s\n", lilv_node_as_string(val)); + lilv_node_free(val); + } + + const LilvPluginClass* pclass = lilv_plugin_get_class(p); + const LilvNode* class_label = lilv_plugin_class_get_label(pclass); + if (class_label) { + printf("\tClass: %s\n", lilv_node_as_string(class_label)); + } + + val = lilv_plugin_get_author_name(p); + if (val) { + printf("\tAuthor: %s\n", lilv_node_as_string(val)); + lilv_node_free(val); + } + + val = lilv_plugin_get_author_email(p); + if (val) { + printf("\tAuthor Email: %s\n", lilv_node_as_uri(val)); + lilv_node_free(val); + } + + val = lilv_plugin_get_author_homepage(p); + if (val) { + printf("\tAuthor Homepage: %s\n", lilv_node_as_uri(val)); + lilv_node_free(val); + } + + if (lilv_plugin_has_latency(p)) { + uint32_t latency_port = lilv_plugin_get_latency_port_index(p); + printf("\tHas latency: yes, reported by port %u\n", latency_port); + } else { + printf("\tHas latency: no\n"); + } + + printf("\tBundle: %s\n", + lilv_node_as_uri(lilv_plugin_get_bundle_uri(p))); + + const LilvNode* binary_uri = lilv_plugin_get_library_uri(p); + if (binary_uri) { + printf("\tBinary: %s\n", + lilv_node_as_uri(lilv_plugin_get_library_uri(p))); + } + + LilvUIs* uis = lilv_plugin_get_uis(p); + if (lilv_nodes_size(uis) > 0) { + printf("\tUIs:\n"); + LILV_FOREACH (uis, i, uis) { + const LilvUI* ui = lilv_uis_get(uis, i); + printf("\t\t%s\n", lilv_node_as_uri(lilv_ui_get_uri(ui))); + + const char* binary = lilv_node_as_uri(lilv_ui_get_binary_uri(ui)); + + const LilvNodes* types = lilv_ui_get_classes(ui); + LILV_FOREACH (nodes, t, types) { + printf("\t\t\tClass: %s\n", + lilv_node_as_uri(lilv_nodes_get(types, t))); + } + + if (binary) { + printf("\t\t\tBinary: %s\n", binary); + } + + printf("\t\t\tBundle: %s\n", + lilv_node_as_uri(lilv_ui_get_bundle_uri(ui))); + } + } + lilv_uis_free(uis); + + printf("\tData URIs: "); + const LilvNodes* data_uris = lilv_plugin_get_data_uris(p); + bool first = true; + LILV_FOREACH (nodes, i, data_uris) { + if (!first) { + printf("\n\t "); + } + printf("%s", lilv_node_as_uri(lilv_nodes_get(data_uris, i))); + first = false; + } + printf("\n"); + + /* Required Features */ + + LilvNodes* features = lilv_plugin_get_required_features(p); + if (features) { + printf("\tRequired Features: "); + } + first = true; + LILV_FOREACH (nodes, i, features) { + if (!first) { + printf("\n\t "); + } + printf("%s", lilv_node_as_uri(lilv_nodes_get(features, i))); + first = false; + } + if (features) { + printf("\n"); + } + lilv_nodes_free(features); + + /* Optional Features */ + + features = lilv_plugin_get_optional_features(p); + if (features) { + printf("\tOptional Features: "); + } + first = true; + LILV_FOREACH (nodes, i, features) { + if (!first) { + printf("\n\t "); + } + printf("%s", lilv_node_as_uri(lilv_nodes_get(features, i))); + first = false; + } + if (features) { + printf("\n"); + } + lilv_nodes_free(features); + + /* Extension Data */ + + LilvNodes* data = lilv_plugin_get_extension_data(p); + if (data) { + printf("\tExtension Data: "); + } + first = true; + LILV_FOREACH (nodes, i, data) { + if (!first) { + printf("\n\t "); + } + printf("%s", lilv_node_as_uri(lilv_nodes_get(data, i))); + first = false; + } + if (data) { + printf("\n"); + } + lilv_nodes_free(data); + + /* Presets */ + + LilvNodes* presets = lilv_plugin_get_related(p, preset_class); + if (presets) { + printf("\tPresets: \n"); + } + LILV_FOREACH (nodes, i, presets) { + const LilvNode* preset = lilv_nodes_get(presets, i); + lilv_world_load_resource(world, preset); + LilvNodes* titles = lilv_world_find_nodes(world, preset, label_pred, NULL); + if (titles) { + const LilvNode* title = lilv_nodes_get_first(titles); + printf("\t %s\n", lilv_node_as_string(title)); + lilv_nodes_free(titles); + } else { + fprintf(stderr, + "Preset <%s> has no rdfs:label\n", + lilv_node_as_string(lilv_nodes_get(presets, i))); + } + } + lilv_nodes_free(presets); + + /* Ports */ + + const uint32_t num_ports = lilv_plugin_get_num_ports(p); + float* mins = (float*)calloc(num_ports, sizeof(float)); + float* maxes = (float*)calloc(num_ports, sizeof(float)); + float* defaults = (float*)calloc(num_ports, sizeof(float)); + lilv_plugin_get_port_ranges_float(p, mins, maxes, defaults); + + for (uint32_t i = 0; i < num_ports; ++i) { + print_port(p, i, mins, maxes, defaults); + } + + free(mins); + free(maxes); + free(defaults); } static void print_version(void) { - printf( - "lv2info (lilv) " LILV_VERSION "\n" - "Copyright 2007-2019 David Robillard <http://drobilla.net>\n" - "License: <http://www.opensource.org/licenses/isc-license>\n" - "This is free software: you are free to change and redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law.\n"); + printf("lv2info (lilv) " LILV_VERSION "\n" + "Copyright 2007-2019 David Robillard <http://drobilla.net>\n" + "License: <http://www.opensource.org/licenses/isc-license>\n" + "This is free software: you are free to change and redistribute it.\n" + "There is NO WARRANTY, to the extent permitted by law.\n"); } static void print_usage(void) { - printf( - "Usage: lv2info [OPTION]... PLUGIN_URI\n" - "Print information about an installed LV2 plugin.\n\n" - " -p FILE Write Turtle description of plugin to FILE\n" - " -m FILE Add record of plugin to manifest FILE\n" - " --help Display this help and exit\n" - " --version Display version information and exit\n\n" - "For -p and -m, Turtle files are appended to (not overwritten),\n" - "and @prefix directives are only written if the file was empty.\n" - "This allows several plugins to be added to a single file.\n"); + printf("Usage: lv2info [OPTION]... PLUGIN_URI\n" + "Print information about an installed LV2 plugin.\n\n" + " -p FILE Write Turtle description of plugin to FILE\n" + " -m FILE Add record of plugin to manifest FILE\n" + " --help Display this help and exit\n" + " --version Display version information and exit\n\n" + "For -p and -m, Turtle files are appended to (not overwritten),\n" + "and @prefix directives are only written if the file was empty.\n" + "This allows several plugins to be added to a single file.\n"); } int main(int argc, char** argv) { - if (argc == 1) { - print_usage(); - return 1; - } - - const char* plugin_file = NULL; - const char* manifest_file = NULL; - const char* plugin_uri = NULL; - for (int i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "--version")) { - print_version(); - return 0; - } - - if (!strcmp(argv[i], "--help")) { - print_usage(); - return 0; - } - - if (!strcmp(argv[i], "-p")) { - plugin_file = argv[++i]; - } else if (!strcmp(argv[i], "-m")) { - manifest_file = argv[++i]; - } else if (argv[i][0] == '-') { - print_usage(); - return 1; - } else if (i == argc - 1) { - plugin_uri = argv[i]; - } - } - - int ret = 0; - - LilvWorld* world = lilv_world_new(); - lilv_world_load_all(world); - - LilvNode* uri = lilv_new_uri(world, plugin_uri); - if (!uri) { - fprintf(stderr, "Invalid plugin URI\n"); - lilv_world_free(world); - return 1; - } - - applies_to_pred = lilv_new_uri(world, LV2_CORE__appliesTo); - control_class = lilv_new_uri(world, LILV_URI_CONTROL_PORT); - event_class = lilv_new_uri(world, LILV_URI_EVENT_PORT); - group_pred = lilv_new_uri(world, LV2_PORT_GROUPS__group); - label_pred = lilv_new_uri(world, LILV_NS_RDFS "label"); - preset_class = lilv_new_uri(world, LV2_PRESETS__Preset); - designation_pred = lilv_new_uri(world, LV2_CORE__designation); - supports_event_pred = lilv_new_uri(world, LV2_EVENT__supportsEvent); - - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - const LilvPlugin* p = lilv_plugins_get_by_uri(plugins, uri); - - if (p && plugin_file) { - LilvNode* base = lilv_new_file_uri(world, NULL, plugin_file); - - FILE* plugin_fd = fopen(plugin_file, "a"); - if (plugin_fd) { - lilv_plugin_write_description(world, p, base, plugin_fd); - fclose(plugin_fd); - } else { - fprintf(stderr, "error: Failed to open %s\n", plugin_file); - } - - if (manifest_file) { - FILE* manifest_fd = fopen(manifest_file, "a"); - if (manifest_fd) { - lilv_plugin_write_manifest_entry( - world, p, base, manifest_fd, plugin_file); - fclose(manifest_fd); - } else { - fprintf(stderr, "error: Failed to open %s\n", manifest_file); - } - } - lilv_node_free(base); - } else if (p) { - print_plugin(world, p); - } else { - fprintf(stderr, "Plugin not found.\n"); - } - - ret = (p != NULL ? 0 : -1); - - lilv_node_free(uri); - - lilv_node_free(supports_event_pred); - lilv_node_free(designation_pred); - lilv_node_free(preset_class); - lilv_node_free(label_pred); - lilv_node_free(group_pred); - lilv_node_free(event_class); - lilv_node_free(control_class); - lilv_node_free(applies_to_pred); - - lilv_world_free(world); - return ret; + if (argc == 1) { + print_usage(); + return 1; + } + + const char* plugin_file = NULL; + const char* manifest_file = NULL; + const char* plugin_uri = NULL; + for (int i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "--version")) { + print_version(); + return 0; + } + + if (!strcmp(argv[i], "--help")) { + print_usage(); + return 0; + } + + if (!strcmp(argv[i], "-p")) { + plugin_file = argv[++i]; + } else if (!strcmp(argv[i], "-m")) { + manifest_file = argv[++i]; + } else if (argv[i][0] == '-') { + print_usage(); + return 1; + } else if (i == argc - 1) { + plugin_uri = argv[i]; + } + } + + int ret = 0; + + LilvWorld* world = lilv_world_new(); + lilv_world_load_all(world); + + LilvNode* uri = lilv_new_uri(world, plugin_uri); + if (!uri) { + fprintf(stderr, "Invalid plugin URI\n"); + lilv_world_free(world); + return 1; + } + + applies_to_pred = lilv_new_uri(world, LV2_CORE__appliesTo); + control_class = lilv_new_uri(world, LILV_URI_CONTROL_PORT); + event_class = lilv_new_uri(world, LILV_URI_EVENT_PORT); + group_pred = lilv_new_uri(world, LV2_PORT_GROUPS__group); + label_pred = lilv_new_uri(world, LILV_NS_RDFS "label"); + preset_class = lilv_new_uri(world, LV2_PRESETS__Preset); + designation_pred = lilv_new_uri(world, LV2_CORE__designation); + supports_event_pred = lilv_new_uri(world, LV2_EVENT__supportsEvent); + + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugin* p = lilv_plugins_get_by_uri(plugins, uri); + + if (p && plugin_file) { + LilvNode* base = lilv_new_file_uri(world, NULL, plugin_file); + + FILE* plugin_fd = fopen(plugin_file, "a"); + if (plugin_fd) { + lilv_plugin_write_description(world, p, base, plugin_fd); + fclose(plugin_fd); + } else { + fprintf(stderr, "error: Failed to open %s\n", plugin_file); + } + + if (manifest_file) { + FILE* manifest_fd = fopen(manifest_file, "a"); + if (manifest_fd) { + lilv_plugin_write_manifest_entry( + world, p, base, manifest_fd, plugin_file); + fclose(manifest_fd); + } else { + fprintf(stderr, "error: Failed to open %s\n", manifest_file); + } + } + lilv_node_free(base); + } else if (p) { + print_plugin(world, p); + } else { + fprintf(stderr, "Plugin not found.\n"); + } + + ret = (p != NULL ? 0 : -1); + + lilv_node_free(uri); + + lilv_node_free(supports_event_pred); + lilv_node_free(designation_pred); + lilv_node_free(preset_class); + lilv_node_free(label_pred); + lilv_node_free(group_pred); + lilv_node_free(event_class); + lilv_node_free(control_class); + lilv_node_free(applies_to_pred); + + lilv_world_free(world); + return ret; } - diff --git a/utils/lv2ls.c b/utils/lv2ls.c index 90ae1eb..e5df2b3 100644 --- a/utils/lv2ls.c +++ b/utils/lv2ls.c @@ -25,70 +25,70 @@ static void list_plugins(const LilvPlugins* list, bool show_names) { - LILV_FOREACH(plugins, i, list) { - const LilvPlugin* p = lilv_plugins_get(list, i); - if (show_names) { - LilvNode* n = lilv_plugin_get_name(p); - printf("%s\n", lilv_node_as_string(n)); - lilv_node_free(n); - } else { - printf("%s\n", lilv_node_as_uri(lilv_plugin_get_uri(p))); - } - } + LILV_FOREACH (plugins, i, list) { + const LilvPlugin* p = lilv_plugins_get(list, i); + if (show_names) { + LilvNode* n = lilv_plugin_get_name(p); + printf("%s\n", lilv_node_as_string(n)); + lilv_node_free(n); + } else { + printf("%s\n", lilv_node_as_uri(lilv_plugin_get_uri(p))); + } + } } static void print_version(void) { - printf( - "lv2ls (lilv) " LILV_VERSION "\n" - "Copyright 2007-2019 David Robillard <http://drobilla.net>\n" - "License: <http://www.opensource.org/licenses/isc-license>\n" - "This is free software: you are free to change and redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law.\n"); + printf("lv2ls (lilv) " LILV_VERSION "\n" + "Copyright 2007-2019 David Robillard <http://drobilla.net>\n" + "License: <http://www.opensource.org/licenses/isc-license>\n" + "This is free software: you are free to change and redistribute it.\n" + "There is NO WARRANTY, to the extent permitted by law.\n"); } static void print_usage(void) { - printf("Usage: lv2ls [OPTION]...\n"); - printf("List all installed LV2 plugins.\n"); - printf("\n"); - printf(" -n, --names Show names instead of URIs\n"); - printf(" --help Display this help and exit\n"); - printf(" --version Display version information and exit\n"); - printf("\n"); - printf("The environment variable LV2_PATH can be used to control where\n"); - printf("this (and all other lilv based LV2 hosts) will search for plugins.\n"); + printf("Usage: lv2ls [OPTION]...\n"); + printf("List all installed LV2 plugins.\n"); + printf("\n"); + printf(" -n, --names Show names instead of URIs\n"); + printf(" --help Display this help and exit\n"); + printf(" --version Display version information and exit\n"); + printf("\n"); + printf("The environment variable LV2_PATH can be used to control where\n"); + printf( + "this (and all other lilv based LV2 hosts) will search for plugins.\n"); } int main(int argc, char** argv) { - bool show_names = false; - for (int i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "--names") || !strcmp(argv[i], "-n")) { - show_names = true; - } else if (!strcmp(argv[i], "--version")) { - print_version(); - return 0; - } else if (!strcmp(argv[i], "--help")) { - print_usage(); - return 0; - } else { - print_usage(); - return 1; - } - } + bool show_names = false; + for (int i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "--names") || !strcmp(argv[i], "-n")) { + show_names = true; + } else if (!strcmp(argv[i], "--version")) { + print_version(); + return 0; + } else if (!strcmp(argv[i], "--help")) { + print_usage(); + return 0; + } else { + print_usage(); + return 1; + } + } - LilvWorld* world = lilv_world_new(); - lilv_world_load_all(world); + LilvWorld* world = lilv_world_new(); + lilv_world_load_all(world); - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); + const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - list_plugins(plugins, show_names); + list_plugins(plugins, show_names); - lilv_world_free(world); + lilv_world_free(world); - return 0; + return 0; } diff --git a/utils/uri_table.h b/utils/uri_table.h index 70635a3..78d3916 100644 --- a/utils/uri_table.h +++ b/utils/uri_table.h @@ -29,54 +29,52 @@ #include <string.h> typedef struct { - char** uris; - size_t n_uris; + char** uris; + size_t n_uris; } URITable; static void uri_table_init(URITable* table) { - table->uris = NULL; - table->n_uris = 0; + table->uris = NULL; + table->n_uris = 0; } static void uri_table_destroy(URITable* table) { - for (size_t i = 0; i < table->n_uris; ++i) { - free(table->uris[i]); - } + for (size_t i = 0; i < table->n_uris; ++i) { + free(table->uris[i]); + } - free(table->uris); + free(table->uris); } static LV2_URID -uri_table_map(LV2_URID_Map_Handle handle, - const char* uri) +uri_table_map(LV2_URID_Map_Handle handle, const char* uri) { - URITable* table = (URITable*)handle; - for (size_t i = 0; i < table->n_uris; ++i) { - if (!strcmp(table->uris[i], uri)) { - return i + 1; - } - } + URITable* table = (URITable*)handle; + for (size_t i = 0; i < table->n_uris; ++i) { + if (!strcmp(table->uris[i], uri)) { + return i + 1; + } + } - const size_t len = strlen(uri); - table->uris = (char**)realloc(table->uris, ++table->n_uris * sizeof(char*)); - table->uris[table->n_uris - 1] = (char*)malloc(len + 1); - memcpy(table->uris[table->n_uris - 1], uri, len + 1); - return table->n_uris; + const size_t len = strlen(uri); + table->uris = (char**)realloc(table->uris, ++table->n_uris * sizeof(char*)); + table->uris[table->n_uris - 1] = (char*)malloc(len + 1); + memcpy(table->uris[table->n_uris - 1], uri, len + 1); + return table->n_uris; } static const char* -uri_table_unmap(LV2_URID_Map_Handle handle, - LV2_URID urid) +uri_table_unmap(LV2_URID_Map_Handle handle, LV2_URID urid) { - URITable* table = (URITable*)handle; - if (urid > 0 && urid <= table->n_uris) { - return table->uris[urid - 1]; - } - return NULL; + URITable* table = (URITable*)handle; + if (urid > 0 && urid <= table->n_uris) { + return table->uris[urid - 1]; + } + return NULL; } -#endif /* URI_TABLE_H */ +#endif /* URI_TABLE_H */ |