From 25d13653ede7fdda4f08cd1e57c73a3c186a7b50 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 19 Feb 2007 06:10:38 +0000 Subject: Fixed doap:license typo in lv2.ttl. Added stronger plugin validation. Plugged memory leaks. Aded list filtering by arbitrary function pointer. git-svn-id: http://svn.drobilla.net/lad/slv2@318 a436a847-0d15-0410-975c-d299462d15a1 --- src/plugin.c | 88 ++++++++++++++++++++++++++++++++++++------------- src/pluginlist.c | 99 ++++++++++++++++++++++++++++++++------------------------ src/query.c | 7 ++-- src/stringlist.c | 4 +-- 4 files changed, 129 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/plugin.c b/src/plugin.c index 8918fa3..64452bb 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -29,14 +29,20 @@ #include "private_types.h" +// FIXME: ew +rasqal_query_results* +slv2_plugin_query(SLV2Plugin plugin, + const char* sparql_str); + + SLV2Plugin slv2_plugin_duplicate(SLV2Plugin p) { assert(p); struct _Plugin* result = malloc(sizeof(struct _Plugin)); - result->plugin_uri = p->plugin_uri; - result->bundle_url = p->bundle_url; - result->lib_uri = p->lib_uri; + result->plugin_uri = strdup(p->plugin_uri); + result->bundle_url = strdup(p->bundle_url); + result->lib_uri = strdup(p->lib_uri); result->data_uris = slv2_strings_new(); for (unsigned i=0; i < slv2_strings_size(p->data_uris); ++i) @@ -45,6 +51,17 @@ slv2_plugin_duplicate(SLV2Plugin p) } +void +slv2_plugin_free(SLV2Plugin p) +{ + free(p->plugin_uri); + free(p->bundle_url); + free(p->lib_uri); + slv2_strings_free(p->data_uris); + free(p); +} + + const char* slv2_plugin_get_uri(SLV2Plugin p) { @@ -72,33 +89,60 @@ slv2_plugin_get_library_uri(SLV2Plugin p) bool slv2_plugin_verify(SLV2Plugin plugin) { - // FIXME: finish this (properly) - - size_t num_values = 0; - - SLV2Strings prop = slv2_plugin_get_value(plugin, "doap:name"); - if (prop) { - num_values = slv2_strings_size(prop); - slv2_strings_free(prop); + char* query_str = + "SELECT DISTINCT ?type ?name ?license ?port WHERE {\n" + "plugin: a ?type ;\n" + "doap:name ?name ;\n" + "doap:license ?license ;\n" + "lv2:port [ lv2:index ?port ] .\n}"; + + rasqal_query_results* results = slv2_plugin_query(plugin, query_str); + + bool has_type = false; + bool has_name = false; + bool has_license = false; + bool has_port = false; + + while (!rasqal_query_results_finished(results)) { + rasqal_literal* literal = rasqal_query_results_get_binding_value(results, 0); + const char* const type = (const char*)rasqal_literal_as_string(literal); + literal = rasqal_query_results_get_binding_value(results, 1); + const char* const name = (const char*)rasqal_literal_as_string(literal); + rasqal_literal* license = rasqal_query_results_get_binding_value(results, 2); + rasqal_literal* port = rasqal_query_results_get_binding_value(results, 3); + + if (!strcmp(type, "http://lv2plug.in/ontology#Plugin")) + has_type = true; + + if (name) + has_name = true; + + if (license) + has_license = true; + + if (port) + has_port = true; + + rasqal_query_results_next(results); } - if (num_values < 1) - return false; -/* - prop = slv2_plugin_get_value(plugin, "doap:license"); - num_values = prop->num_values; - free(prop); - if (num_values < 1) + + free(query_str); + rasqal_free_query_results(results); + + if ( ! (has_type && has_name && has_license && has_port) ) { + fprintf(stderr, "Invalid LV2 Plugin %s:\n", slv2_plugin_get_uri(plugin)); return false; -*/ - return true; + } else { + return true; + } } char* slv2_plugin_get_name(SLV2Plugin plugin) { - char* result = NULL; - SLV2Strings prop = slv2_plugin_get_value(plugin, "doap:name"); + char* result = NULL; + SLV2Strings prop = slv2_plugin_get_value(plugin, "doap:name"); // FIXME: guaranteed to be the untagged one? if (prop && slv2_strings_size(prop) >= 1) diff --git a/src/pluginlist.c b/src/pluginlist.c index a6a2a97..9dcb33c 100644 --- a/src/pluginlist.c +++ b/src/pluginlist.c @@ -18,6 +18,7 @@ #define _XOPEN_SOURCE 500 #include +#include #include #include #include @@ -47,34 +48,46 @@ slv2_plugin_new() } -struct _PluginList* +SLV2Plugins slv2_plugins_new() { - struct _PluginList* result = malloc(sizeof(struct _PluginList)); - result->num_plugins = 0; - result->plugins = NULL; - return result; + return raptor_new_sequence((void (*)(void*))&slv2_plugin_free, NULL); } void slv2_plugins_free(SLV2Plugins list) { - list->num_plugins = 0; - free(list->plugins); - free(list); + raptor_free_sequence(list); +} + + +void +slv2_plugins_filter(SLV2Plugins dest, SLV2Plugins source, bool (*include)(SLV2Plugin)) +{ + assert(dest); + + for (int i=0; i < raptor_sequence_size(source); ++i) { + SLV2Plugin p = raptor_sequence_get_at(source, i); + if (include(p)) + raptor_sequence_push(dest, slv2_plugin_duplicate(p)); + } } void slv2_plugins_load_all(SLV2Plugins list) { - assert(list != NULL); + /* FIXME: this is much slower than it should be in many ways.. */ + + assert(list); char* slv2_path = getenv("LV2_PATH"); + SLV2Plugins load_list = slv2_plugins_new(); + if (slv2_path) { - slv2_plugins_load_path(list, slv2_path); + slv2_plugins_load_path(load_list, slv2_path); } else { const char* const home = getenv("HOME"); const char* const suffix = "/.lv2:/usr/local/lib/lv2:usr/lib/lv2"; @@ -83,13 +96,17 @@ slv2_plugins_load_all(SLV2Plugins list) fprintf(stderr, "$LV2_PATH is unset. Using default path %s\n", slv2_path); /* pass 1: find all plugins */ - slv2_plugins_load_path(list, slv2_path); + slv2_plugins_load_path(load_list, slv2_path); /* pass 2: find all data files for plugins */ - slv2_plugins_load_path(list, slv2_path); + slv2_plugins_load_path(load_list, slv2_path); free(slv2_path); } + + /* insert only valid plugins into list */ + slv2_plugins_filter(list, load_list, slv2_plugin_verify); + slv2_plugins_free(load_list); } @@ -97,9 +114,11 @@ slv2_plugins_load_all(SLV2Plugins list) * This is called twice on each bundle in the discovery process, which is (much) less * efficient than it could be.... */ void -slv2_plugins_load_bundle(SLV2Plugins list, - const char* bundle_base_url) +slv2_plugins_load_bundle(SLV2Plugins list, + const char* bundle_base_url) { + assert(list); + unsigned char* manifest_url = malloc( (strlen((char*)bundle_base_url) + strlen("manifest.ttl") + 2) * sizeof(unsigned char)); memcpy(manifest_url, bundle_base_url, strlen((char*)bundle_base_url)+1 * sizeof(unsigned char)); @@ -135,13 +154,7 @@ slv2_plugins_load_bundle(SLV2Plugins list, new_plugin->bundle_url = strdup(bundle_base_url); raptor_sequence_push(new_plugin->data_uris, strdup((const char*)manifest_url)); - /* And add it to the list - * Yes, this is disgusting, but it doesn't seem there's a way to know - * how many matches there are before iterating over them.. */ - list->num_plugins++; - list->plugins = realloc(list->plugins, - list->num_plugins * sizeof(struct _Plugin*)); - list->plugins[list->num_plugins-1] = new_plugin; + raptor_sequence_push(list, new_plugin); } @@ -195,7 +208,6 @@ slv2_plugins_load_bundle(SLV2Plugins list, rasqal_free_query_results(results); rasqal_free_query(rq); - raptor_free_uri(base_url); free(manifest_url); @@ -208,6 +220,8 @@ slv2_plugins_load_bundle(SLV2Plugins list, void slv2_plugins_load_dir(SLV2Plugins list, const char* dir) { + assert(list); + DIR* pdir = opendir(dir); if (!pdir) return; @@ -229,6 +243,7 @@ slv2_plugins_load_dir(SLV2Plugins list, const char* dir) } free(bundle_path); + free(bundle_url); } closedir(pdir); @@ -236,12 +251,13 @@ slv2_plugins_load_dir(SLV2Plugins list, const char* dir) void -slv2_plugins_load_path(SLV2Plugins list, - const char* lv2_path) +slv2_plugins_load_path(SLV2Plugins list, + const char* lv2_path) { - char* path = slv2_strjoin(lv2_path, ":", NULL); + assert(list); - char* dir = path; // Pointer into path + char* path = slv2_strjoin(lv2_path, ":", NULL); + char* dir = path; // Pointer into path // Go through string replacing ':' with '\0', using the substring, // then replacing it with 'X' and moving on. i.e. strtok on crack. @@ -262,22 +278,19 @@ slv2_plugins_load_path(SLV2Plugins list, unsigned -slv2_plugins_size(const SLV2Plugins list) +slv2_plugins_size(SLV2Plugins list) { - assert(list != NULL); - return list->num_plugins; + return raptor_sequence_size(list); } SLV2Plugin -slv2_plugins_get_by_uri(const SLV2Plugins list, const char* uri) +slv2_plugins_get_by_uri(SLV2Plugins list, const char* uri) { - if (list->num_plugins > 0) { - assert(list->plugins != NULL); - - for (unsigned i=0; i < list->num_plugins; ++i) - if (!strcmp((char*)list->plugins[i]->plugin_uri, (char*)uri)) - return list->plugins[i]; + for (int i=0; i < raptor_sequence_size(list); ++i) { + SLV2Plugin p = raptor_sequence_get_at(list, i); + if (!strcmp(p->plugin_uri, uri)) + return p; } return NULL; @@ -285,13 +298,13 @@ slv2_plugins_get_by_uri(const SLV2Plugins list, const char* uri) SLV2Plugin -slv2_plugins_get_at(const SLV2Plugins list, unsigned index) -{ - if (list->num_plugins == 0) +slv2_plugins_get_at(SLV2Plugins list, unsigned index) +{ + assert(list); + + if (index > INT_MAX) return NULL; - - assert(list->plugins != NULL); - - return (index < list->num_plugins) ? list->plugins[index] : NULL; + else + return (SLV2Plugin)raptor_sequence_get_at(list, (int)index); } diff --git a/src/query.c b/src/query.c index b671ac8..4d259f2 100644 --- a/src/query.c +++ b/src/query.c @@ -134,15 +134,18 @@ slv2_plugin_query(SLV2Plugin plugin, raptor_uri* file_uri = raptor_new_uri((const unsigned char*)file_uri_str); rasqal_query_add_data_graph(rq, file_uri, NULL, RASQAL_DATA_GRAPH_BACKGROUND); + raptor_free_uri(file_uri); } rasqal_query_results* results = rasqal_query_execute(rq); - assert(results); rasqal_free_query(rq); raptor_free_uri(base_uri); - // FIXME: results leaked? + free(header); + free(query_str); + + // FIXME: results leaked internally in places? return results; /* diff --git a/src/stringlist.c b/src/stringlist.c index 930454f..2233e7e 100644 --- a/src/stringlist.c +++ b/src/stringlist.c @@ -55,10 +55,10 @@ slv2_strings_get_at(SLV2Strings list, unsigned index) bool -slv2_strings_contains(SLV2Strings list, const char* uri) +slv2_strings_contains(SLV2Strings list, const char* str) { for (unsigned i=0; i < slv2_strings_size(list); ++i) - if (!strcmp(slv2_strings_get_at(list, i), uri)) + if (!strcmp(slv2_strings_get_at(list, i), str)) return true; return false; -- cgit v1.2.1