summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--lilv/lilv.h7
-rw-r--r--src/collections.c19
-rw-r--r--src/plugin.c41
-rw-r--r--src/world.c27
5 files changed, 54 insertions, 41 deletions
diff --git a/NEWS b/NEWS
index 6460882..90f05a8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,6 @@
lilv (0.15.0) unstable;
+ * Add lilv_nodes_merge().
* Support atom:supports in lilv_port_supports_event().
* Add va_list variant of lilv_plugin_get_num_ports_of_class().
* Correctly depend on serd at build time (fix compilation in odd cases)
diff --git a/lilv/lilv.h b/lilv/lilv.h
index 5ef5e59..1d05883 100644
--- a/lilv/lilv.h
+++ b/lilv/lilv.h
@@ -465,6 +465,13 @@ LILV_API
bool
lilv_nodes_contains(const LilvNodes* values, const LilvNode* value);
+/**
+ Return a new LilvNodes that contains all nodes from both @p a and @p b.
+*/
+LILV_API
+LilvNodes*
+lilv_nodes_merge(const LilvNodes* a, const LilvNodes* b);
+
/* Plugins */
LILV_API
diff --git a/src/collections.c b/src/collections.c
index f7a035a..a4ac744 100644
--- a/src/collections.c
+++ b/src/collections.c
@@ -143,6 +143,25 @@ lilv_nodes_contains(const LilvNodes* list, const LilvNode* value)
return false;
}
+LILV_API
+LilvNodes*
+lilv_nodes_merge(const LilvNodes* a, const LilvNodes* b)
+{
+ 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, b)
+ zix_tree_insert((ZixTree*)result,
+ lilv_node_duplicate(lilv_nodes_get(b, i)),
+ NULL);
+
+ return result;
+}
+
/* Iterator */
#define LILV_COLLECTION_IMPL(prefix, CT, ET) \
diff --git a/src/plugin.c b/src/plugin.c
index 9912112..c284d98 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -680,13 +680,17 @@ bool
lilv_plugin_has_feature(const LilvPlugin* p,
const LilvNode* feature)
{
- LilvNodes* features = lilv_plugin_get_supported_features(p);
+ const SordNode* predicates[] = { p->world->uris.lv2_requiredFeature,
+ p->world->uris.lv2_optionalFeature,
+ NULL };
- const bool ret = (features && feature
- && lilv_nodes_contains(features, feature));
-
- lilv_nodes_free(features);
- return ret;
+ for (const SordNode** pred = predicates; *pred; ++pred) {
+ if (lilv_world_ask_internal(
+ p->world, p->plugin_uri->node, *pred, feature->node)) {
+ return true;
+ }
+ }
+ return false;
}
LILV_API
@@ -695,20 +699,9 @@ lilv_plugin_get_supported_features(const LilvPlugin* p)
{
LilvNodes* optional = lilv_plugin_get_optional_features(p);
LilvNodes* required = lilv_plugin_get_required_features(p);
- LilvNodes* result = lilv_nodes_new();
-
- LILV_FOREACH(nodes, i, optional)
- zix_tree_insert((ZixTree*)result,
- lilv_node_duplicate(lilv_nodes_get(optional, i)),
- NULL);
- LILV_FOREACH(nodes, i, required)
- zix_tree_insert((ZixTree*)result,
- lilv_node_duplicate(lilv_nodes_get(required, i)),
- NULL);
-
+ LilvNodes* result = lilv_nodes_merge(optional, required);
lilv_nodes_free(optional);
lilv_nodes_free(required);
-
return result;
}
@@ -716,16 +709,20 @@ LILV_API
LilvNodes*
lilv_plugin_get_optional_features(const LilvPlugin* p)
{
- return lilv_plugin_get_value_internal(
- p, p->world->uris.lv2_optionalFeature);
+ return lilv_world_query_values_internal(p->world,
+ p->plugin_uri->node,
+ p->world->uris.lv2_optionalFeature,
+ NULL);
}
LILV_API
LilvNodes*
lilv_plugin_get_required_features(const LilvPlugin* p)
{
- return lilv_plugin_get_value_internal(
- p, p->world->uris.lv2_requiredFeature);
+ return lilv_world_query_values_internal(p->world,
+ p->plugin_uri->node,
+ p->world->uris.lv2_requiredFeature,
+ NULL);
}
LILV_API
diff --git a/src/world.c b/src/world.c
index afa3422..121f59c 100644
--- a/src/world.c
+++ b/src/world.c
@@ -185,31 +185,20 @@ lilv_world_find_nodes(LilvWorld* world,
LILV_ERRORF("Subject `%s' is not a resource\n",
sord_node_get_string(subject->node));
return NULL;
- }
- if (!lilv_node_is_uri(predicate)) {
+ } else 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) {
+ } else if (!subject && !object) {
LILV_ERROR("Both subject and object are NULL\n");
return NULL;
}
-
- SordNode* const subject_node = subject
- ? sord_node_copy(subject->node)
- : NULL;
-
- SordNode* const object_node = object
- ? sord_node_copy(object->node)
- : NULL;
-
- LilvNodes* ret = lilv_world_query_values_internal(
- world, subject_node, predicate->node, object_node);
-
- sord_node_free(world->world, subject_node);
- sord_node_free(world->world, object_node);
- return ret;
+
+ return lilv_world_query_values_internal(
+ world,
+ subject ? subject->node : NULL,
+ predicate->node,
+ object ? object->node : NULL);
}
SordIter*