summaryrefslogtreecommitdiffstats
path: root/src/world.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/world.c')
-rw-r--r--src/world.c1946
1 files changed, 965 insertions, 981 deletions
diff --git a/src/world.c b/src/world.c
index 7095a6e..b0ef24d 100644
--- a/src/world.c
+++ b/src/world.c
@@ -1,35 +1,20 @@
-/*
- Copyright 2007-2019 David Robillard <http://drobilla.net>
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-#include "filesystem.h"
-#include "lilv_config.h"
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#include "lilv_config.h" // IWYU pragma: keep
#include "lilv_internal.h"
#include "lilv/lilv.h"
#include "serd/serd.h"
#include "sord/sord.h"
-#include "zix/common.h"
+#include "zix/filesystem.h"
#include "zix/tree.h"
#include "lv2/core/lv2.h"
#include "lv2/presets/presets.h"
#ifdef LILV_DYN_MANIFEST
-# include "lv2/dynmanifest/dynmanifest.h"
-# include <dlfcn.h>
+# include "lv2/dynmanifest/dynmanifest.h"
#endif
#include <assert.h>
@@ -42,169 +27,178 @@
static int
lilv_world_drop_graph(LilvWorld* world, const SordNode* graph);
+static int
+lilv_lib_compare(const void* a, const void* b, const void* user_data);
+
+static void
+destroy_node(void* const ptr, const void* const user_data)
+{
+ (void)user_data;
+ lilv_node_free((LilvNode*)ptr);
+}
+
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->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->loaded_files =
+ zix_tree_new(NULL, false, lilv_resource_node_cmp, NULL, destroy_node, NULL);
- world->libs = zix_tree_new(false, lilv_lib_compare, NULL, NULL);
+ world->libs = zix_tree_new(NULL, false, lilv_lib_compare, NULL, 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,26 +207,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;
- } else if (!predicate) {
- LILV_ERROR("Missing required predicate\n");
- return NULL;
- } else if (!lilv_node_is_uri(predicate)) {
- LILV_ERRORF("Predicate `%s' is not a URI\n",
- sord_node_get_string(predicate->node));
- return NULL;
- } else 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*
@@ -241,34 +241,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*
@@ -277,7 +277,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
@@ -286,7 +286,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
@@ -295,11 +295,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*
@@ -310,15 +310,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*
@@ -327,37 +327,31 @@ 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);
-}
-
-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);
+ return lilv_nodes_from_stream_objects(
+ world,
+ lilv_world_query_internal(world, subject, predicate, object),
+ (object == NULL) ? SORD_OBJECT : SORD_SUBJECT);
}
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)
+lilv_header_compare_by_uri(const void* a, const void* b, const 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));
+ (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));
}
/**
@@ -367,35 +361,39 @@ lilv_header_compare_by_uri(const void* a, const void* b, void* user_data)
handle the case where the same library is loaded with different bundles, and
consequently different contents (mainly plugins).
*/
-int
-lilv_lib_compare(const void* a, const void* b, void* user_data)
+static int
+lilv_lib_compare(const void* a, const void* b, const 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);
+ (void)user_data;
+
+ const LilvLib* const lib_a = (const LilvLib*)a;
+ const LilvLib* const lib_b = (const LilvLib*)b;
+
+ const 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
@@ -403,28 +401,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
@@ -434,86 +429,82 @@ 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);
- }
-
+ (void)dynmanifest;
+
+ 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
+static 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
@@ -522,161 +513,173 @@ 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);
+
+#else // LILV_DYN_MANIFEST
+ (void)world;
+ (void)bundle_node;
+ (void)manifest;
+#endif
}
#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;
+ // Get the string and length of the given bundle URI
+ size_t bundle_uri_length = 0U;
+ const char* const bundle_uri_string =
+ (const char*)sord_node_get_string_counted(bundle_uri->node,
+ &bundle_uri_length);
+ if (!bundle_uri_length) {
+ return NULL;
+ }
+
+ // Build the manifest URI by inserting a separating "/" if necessary
+ const char last = bundle_uri_string[bundle_uri_length - 1U];
+ char* const manifest_uri_string =
+ (last == '/') ? lilv_strjoin(bundle_uri_string, "manifest.ttl", NULL)
+ : lilv_strjoin(bundle_uri_string, "/", "manifest.ttl", NULL);
+
+ // Make a node from the manifeset URI to return
+ LilvNode* const manifest = lilv_new_uri(world, manifest_uri_string);
+ free(manifest_uri_string);
+ return manifest;
}
static SordModel*
@@ -684,308 +687,301 @@ 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);
+ if (!manifest) {
+ return;
+ }
+
+ // 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 && 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) {
+ zix_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`.
@@ -994,277 +990,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
- } else 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;
}