summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2014-07-12 19:46:57 +0000
committerDavid Robillard <d@drobilla.net>2014-07-12 19:46:57 +0000
commitdf38c9eddd81db74174647fd5cca89f7a6de1257 (patch)
tree924f0181b42b80114bcddad9a4e46db8b4637f26
parent19681c50a2da2e368122ed33bf9fda0ae81f3f76 (diff)
downloadlilv-df38c9eddd81db74174647fd5cca89f7a6de1257.tar.gz
lilv-df38c9eddd81db74174647fd5cca89f7a6de1257.tar.bz2
lilv-df38c9eddd81db74174647fd5cca89f7a6de1257.zip
Fix issues with lilv_plugin_get_author_name and friends (thanks Filipe Coelho) (fix #976).
Improve test coverage. Fix several minor memory leaks. git-svn-id: http://svn.drobilla.net/lad/trunk/lilv@5406 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--NEWS11
-rw-r--r--src/plugin.c37
-rw-r--r--test/lilv_test.c262
3 files changed, 292 insertions, 18 deletions
diff --git a/NEWS b/NEWS
index ba8c527..a00db45 100644
--- a/NEWS
+++ b/NEWS
@@ -2,15 +2,18 @@ lilv (0.19.0) unstable;
* Don't load files multiple times if they are listed as rdfs:seeAlso for
several plugins
- * Fix minor memory leak in test suite
* Call lv2_lib_descriptor separately for different bundle paths
(fix loading several dynamic plugins like Ingen at once)
* Tolerate calling lilv_node_as_uri or lilv_node_as_blank on NULL
- * Add convenient lilv_new_file_uri for creating file URIs.
+ * Add convenient lilv_new_file_uri for creating file URIs
* Fix use of lv2info -m and -p options to write plugin data
- (useful for porting plugins bridges with NASPRO).
+ (useful for porting plugins bridges with NASPRO)
+ * Fix issues with lilv_plugin_get_author_name and friends
+ (thanks Filipe Coelho)
+ * Fix several minor memory leaks
+ * Improve test coverage
- -- David Robillard <d@drobilla.net> Mon, 05 May 2014 17:00:36 +0200
+ -- David Robillard <d@drobilla.net> Sat, 12 Jul 2014 15:45:00 -0400
lilv (0.18.0) stable;
diff --git a/src/plugin.c b/src/plugin.c
index cc1bdba..2f9e5b8 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -161,8 +161,10 @@ lilv_plugin_load(LilvPlugin* p)
sord_add(p->world->model, quad);
}
+ sord_iter_free(statements);
lilv_node_free(prototype);
}
+ sord_iter_free(prototypes);
// Parse all the plugin's data files into RDF model
LILV_FOREACH(nodes, i, p->data_uris) {
@@ -833,6 +835,7 @@ lilv_plugin_get_project(const LilvPlugin* p)
sord_node_free(p->world->world, lv2_project);
if (sord_iter_end(projects)) {
+ sord_iter_free(projects);
return NULL;
}
@@ -856,11 +859,12 @@ lilv_plugin_get_author(const LilvPlugin* p)
doap_maintainer,
NULL);
- sord_node_free(p->world->world, doap_maintainer);
-
if (sord_iter_end(maintainers)) {
+ sord_iter_free(maintainers);
+
LilvNode* project = lilv_plugin_get_project(p);
if (!project) {
+ sord_node_free(p->world->world, doap_maintainer);
return NULL;
}
@@ -869,9 +873,14 @@ lilv_plugin_get_author(const LilvPlugin* p)
project->node,
doap_maintainer,
NULL);
+
+ lilv_node_free(project);
}
+ sord_node_free(p->world->world, doap_maintainer);
+
if (sord_iter_end(maintainers)) {
+ sord_iter_free(maintainers);
return NULL;
}
@@ -887,9 +896,11 @@ lilv_plugin_get_author_name(const LilvPlugin* plugin)
{
const SordNode* author = lilv_plugin_get_author(plugin);
if (author) {
- return lilv_plugin_get_one(
- plugin, author, sord_new_uri(
- plugin->world->world, NS_FOAF "name"));
+ SordWorld* sworld = plugin->world->world;
+ SordNode* foaf_name = sord_new_uri(sworld, NS_FOAF "name");
+ LilvNode* ret = lilv_plugin_get_one(plugin, author, foaf_name);
+ sord_node_free(sworld, foaf_name);
+ return ret;
}
return NULL;
}
@@ -900,9 +911,11 @@ lilv_plugin_get_author_email(const LilvPlugin* plugin)
{
const SordNode* author = lilv_plugin_get_author(plugin);
if (author) {
- return lilv_plugin_get_one(
- plugin, author, sord_new_uri(
- plugin->world->world, NS_FOAF "mbox"));
+ SordWorld* sworld = plugin->world->world;
+ SordNode* foaf_mbox = sord_new_uri(sworld, NS_FOAF "mbox");
+ LilvNode* ret = lilv_plugin_get_one(plugin, author, foaf_mbox);
+ sord_node_free(sworld, foaf_mbox);
+ return ret;
}
return NULL;
}
@@ -913,9 +926,11 @@ lilv_plugin_get_author_homepage(const LilvPlugin* plugin)
{
const SordNode* author = lilv_plugin_get_author(plugin);
if (author) {
- return lilv_plugin_get_one(
- plugin, author, sord_new_uri(
- plugin->world->world, NS_FOAF "homepage"));
+ SordWorld* sworld = plugin->world->world;
+ SordNode* foaf_homepage = sord_new_uri(sworld, NS_FOAF "homepage");
+ LilvNode* ret = lilv_plugin_get_one(plugin, author, foaf_homepage);
+ sord_node_free(sworld, foaf_homepage);
+ return ret;
}
return NULL;
}
diff --git a/test/lilv_test.c b/test/lilv_test.c
index 3727c47..ea12013 100644
--- a/test/lilv_test.c
+++ b/test/lilv_test.c
@@ -1,5 +1,5 @@
/*
- Copyright 2007-2011 David Robillard <http://drobilla.net>
+ Copyright 2007-2014 David Robillard <http://drobilla.net>
Copyright 2008 Krzysztof Foltman
Permission to use, copy, modify, and/or distribute this software for any
@@ -41,6 +41,7 @@
#include "lilv/lilv.h"
#include "../src/lilv_internal.h"
+#include "lv2/lv2plug.in/ns/ext/presets/presets.h"
#include "lv2/lv2plug.in/ns/ext/state/state.h"
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
@@ -179,9 +180,10 @@ struct TestCase {
#define PREFIX_RDFS "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"
#define PREFIX_FOAF "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n"
#define PREFIX_DOAP "@prefix doap: <http://usefulinc.com/ns/doap#> .\n"
+#define PREFIX_PSET "@prefix pset: <http://lv2plug.in/ns/ext/presets#> .\n"
#define MANIFEST_PREFIXES PREFIX_LINE PREFIX_LV2 PREFIX_RDFS
-#define BUNDLE_PREFIXES PREFIX_ATOM PREFIX_LINE PREFIX_LV2 PREFIX_RDF PREFIX_RDFS PREFIX_FOAF PREFIX_DOAP
+#define BUNDLE_PREFIXES PREFIX_ATOM PREFIX_LINE PREFIX_LV2 PREFIX_RDF PREFIX_RDFS PREFIX_FOAF PREFIX_DOAP PREFIX_PSET
#define PLUGIN_NAME(name) "doap:name \"" name "\""
#define LICENSE_GPL "doap:license <http://usefulinc.com/doap/licenses/gpl>"
@@ -585,12 +587,18 @@ test_plugin(void)
klass_uri));
lilv_node_free(rdf_type);
+ TEST_ASSERT(!lilv_plugin_is_replaced(plug));
+ TEST_ASSERT(!lilv_plugin_get_related(plug, NULL));
+
const LilvNode* plug_bundle_uri = lilv_plugin_get_bundle_uri(plug);
TEST_ASSERT(!strcmp(lilv_node_as_string(plug_bundle_uri), bundle_dir_uri));
const LilvNodes* data_uris = lilv_plugin_get_data_uris(plug);
TEST_ASSERT(lilv_nodes_size(data_uris) == 2);
+ LilvNode* project = lilv_plugin_get_project(plug);
+ TEST_ASSERT(!project);
+
char* manifest_uri = (char*)malloc(TEST_PATH_MAX);
char* data_uri = (char*)malloc(TEST_PATH_MAX);
snprintf(manifest_uri, TEST_PATH_MAX, "%s%s",
@@ -759,6 +767,249 @@ test_plugin(void)
/*****************************************************************************/
static int
+test_project(void)
+{
+ if (!start_bundle(MANIFEST_PREFIXES
+ ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
+ BUNDLE_PREFIXES
+ ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
+ PLUGIN_NAME("Test plugin with project") " ; "
+ LICENSE_GPL " ; "
+ "lv2:project [ "
+ " doap:maintainer [ "
+ " foaf:name \"David Robillard\" ; "
+ " foaf:homepage <http://drobilla.net> ; foaf:mbox <mailto:d@drobilla.net> ] ; "
+ "] ; "
+ "lv2:port [ "
+ " a lv2:ControlPort ; a lv2:InputPort ; "
+ " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
+ " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
+ "] , [ "
+ " a lv2:ControlPort ; a lv2:InputPort ; "
+ " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
+ " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
+ "] , [ "
+ " a lv2:ControlPort ; a lv2:OutputPort ; "
+ " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
+ " lv2:portProperty lv2:reportsLatency ; "
+ " lv2:designation lv2:latency "
+ "] . \n"
+ ":thing doap:name \"Something else\" .\n"))
+ return 0;
+
+ init_uris();
+ const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
+ const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
+ TEST_ASSERT(plug);
+
+ LilvNode* author_name = lilv_plugin_get_author_name(plug);
+ TEST_ASSERT(!strcmp(lilv_node_as_string(author_name), "David Robillard"));
+ lilv_node_free(author_name);
+
+ LilvNode* author_email = lilv_plugin_get_author_email(plug);
+ TEST_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);
+ TEST_ASSERT(!strcmp(lilv_node_as_string(author_homepage), "http://drobilla.net"));
+ lilv_node_free(author_homepage);
+
+ cleanup_uris();
+ return 1;
+}
+
+/*****************************************************************************/
+
+static int
+test_no_author(void)
+{
+ if (!start_bundle(MANIFEST_PREFIXES
+ ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
+ BUNDLE_PREFIXES
+ ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
+ PLUGIN_NAME("Test plugin with project") " ; "
+ LICENSE_GPL " ; "
+ "lv2:port [ "
+ " a lv2:ControlPort ; a lv2:InputPort ; "
+ " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
+ " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
+ "] , [ "
+ " a lv2:ControlPort ; a lv2:InputPort ; "
+ " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
+ " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
+ "] , [ "
+ " a lv2:ControlPort ; a lv2:OutputPort ; "
+ " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
+ " lv2:portProperty lv2:reportsLatency ; "
+ " lv2:designation lv2:latency "
+ "] . \n"
+ ":thing doap:name \"Something else\" .\n"))
+ return 0;
+
+ init_uris();
+ const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
+ const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
+ TEST_ASSERT(plug);
+
+ LilvNode* author_name = lilv_plugin_get_author_name(plug);
+ TEST_ASSERT(!author_name);
+
+ LilvNode* author_email = lilv_plugin_get_author_email(plug);
+ TEST_ASSERT(!author_email);
+
+ LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug);
+ TEST_ASSERT(!author_homepage);
+
+ cleanup_uris();
+ return 1;
+}
+
+/*****************************************************************************/
+
+static int
+test_project_no_author(void)
+{
+ if (!start_bundle(MANIFEST_PREFIXES
+ ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
+ BUNDLE_PREFIXES
+ ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
+ PLUGIN_NAME("Test plugin with project") " ; "
+ LICENSE_GPL " ; "
+ "lv2:project [ "
+ " doap:name \"Fake project\" ;"
+ "] ; "
+ "lv2:port [ "
+ " a lv2:ControlPort ; a lv2:InputPort ; "
+ " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
+ " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
+ "] , [ "
+ " a lv2:ControlPort ; a lv2:InputPort ; "
+ " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
+ " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
+ "] , [ "
+ " a lv2:ControlPort ; a lv2:OutputPort ; "
+ " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
+ " lv2:portProperty lv2:reportsLatency ; "
+ " lv2:designation lv2:latency "
+ "] . \n"
+ ":thing doap:name \"Something else\" .\n"))
+ return 0;
+
+ init_uris();
+ const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
+ const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
+ TEST_ASSERT(plug);
+
+ LilvNode* author_name = lilv_plugin_get_author_name(plug);
+ TEST_ASSERT(!author_name);
+
+ LilvNode* author_email = lilv_plugin_get_author_email(plug);
+ TEST_ASSERT(!author_email);
+
+ LilvNode* author_homepage = lilv_plugin_get_author_homepage(plug);
+ TEST_ASSERT(!author_homepage);
+
+ cleanup_uris();
+ return 1;
+}
+
+/*****************************************************************************/
+
+static int
+test_preset(void)
+{
+ if (!start_bundle(MANIFEST_PREFIXES
+ ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; rdfs:seeAlso <plugin.ttl> .\n",
+ BUNDLE_PREFIXES
+ ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; "
+ PLUGIN_NAME("Test plugin with project") " ; "
+ LICENSE_GPL " ; "
+ "lv2:project [ "
+ " doap:name \"Fake project\" ;"
+ "] ; "
+ "lv2:port [ "
+ " a lv2:ControlPort ; a lv2:InputPort ; "
+ " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
+ " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
+ "] , [ "
+ " a lv2:ControlPort ; a lv2:InputPort ; "
+ " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
+ " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
+ "] , [ "
+ " a lv2:ControlPort ; a lv2:OutputPort ; "
+ " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
+ " lv2:portProperty lv2:reportsLatency ; "
+ " lv2:designation lv2:latency "
+ "] . \n"
+ "<http://example.org/preset> a pset:Preset ;"
+ " lv2:appliesTo :plug ;"
+ " rdfs:label \"some preset\" .\n"))
+ return 0;
+
+ init_uris();
+ const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
+ const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
+ TEST_ASSERT(plug);
+
+ LilvNode* pset_Preset = lilv_new_uri(world, LV2_PRESETS__Preset);
+ LilvNodes* related = lilv_plugin_get_related(plug, pset_Preset);
+
+ TEST_ASSERT(lilv_nodes_size(related) == 1);
+
+ lilv_node_free(pset_Preset);
+ lilv_nodes_free(related);
+ cleanup_uris();
+ return 1;
+}
+
+/*****************************************************************************/
+
+static int
+test_prototype(void)
+{
+ if (!start_bundle(MANIFEST_PREFIXES
+ ":prot a lv2:PluginBase ; rdfs:seeAlso <plugin.ttl> .\n"
+ ":plug a lv2:Plugin ; lv2:binary <foo" SHLIB_EXT "> ; lv2:prototype :prot .\n",
+ BUNDLE_PREFIXES
+ ":prot a lv2:Plugin ; a lv2:CompressorPlugin ; "
+ PLUGIN_NAME("Test plugin with project") " ; "
+ LICENSE_GPL " ; "
+ "lv2:project [ "
+ " doap:name \"Fake project\" ;"
+ "] ; "
+ "lv2:port [ "
+ " a lv2:ControlPort ; a lv2:InputPort ; "
+ " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; "
+ " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 "
+ "] , [ "
+ " a lv2:ControlPort ; a lv2:InputPort ; "
+ " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; "
+ " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 "
+ "] , [ "
+ " a lv2:ControlPort ; a lv2:OutputPort ; "
+ " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; "
+ " lv2:portProperty lv2:reportsLatency ; "
+ " lv2:designation lv2:latency "
+ "] . \n"
+ ":plug doap:name \"Instance\" .\n"))
+ return 0;
+
+ init_uris();
+ const LilvPlugins* plugins = lilv_world_get_all_plugins(world);
+ const LilvPlugin* plug = lilv_plugins_get_by_uri(plugins, plugin_uri_value);
+ TEST_ASSERT(plug);
+
+ LilvNode* name = lilv_plugin_get_name(plug);
+ TEST_ASSERT(!strcmp(lilv_node_as_string(name), "Instance"));
+ lilv_node_free(name);
+
+ cleanup_uris();
+ return 1;
+}
+
+/*****************************************************************************/
+
+static int
test_port(void)
{
if (!start_bundle(MANIFEST_PREFIXES
@@ -1286,7 +1537,7 @@ test_state(void)
// Check that we can't restore the NULL string (and it doesn't crash)
LilvState* bad_state = lilv_state_new_from_string(world, &map, NULL);
TEST_ASSERT(!bad_state);
-
+
// Save state to a string
char* state1_str = lilv_state_to_string(
world, &map, &unmap, state, "http://example.org/state1", NULL);
@@ -1611,6 +1862,11 @@ static struct TestCase tests[] = {
TEST_CASE(lv2_path),
TEST_CASE(classes),
TEST_CASE(plugin),
+ TEST_CASE(project),
+ TEST_CASE(no_author),
+ TEST_CASE(project_no_author),
+ TEST_CASE(preset),
+ TEST_CASE(prototype),
TEST_CASE(port),
TEST_CASE(ui),
TEST_CASE(bad_port_symbol),