diff options
-rw-r--r-- | lilv/lilv.h | 23 | ||||
-rw-r--r-- | src/plugin.c | 119 | ||||
-rw-r--r-- | utils/lv2info.c | 81 | ||||
-rw-r--r-- | wscript | 2 |
4 files changed, 197 insertions, 28 deletions
diff --git a/lilv/lilv.h b/lilv/lilv.h index bbf64de..fccec60 100644 --- a/lilv/lilv.h +++ b/lilv/lilv.h @@ -24,6 +24,7 @@ #include <stdbool.h> #include <stddef.h> #include <stdint.h> +#include <stdio.h> #include "lv2/lv2plug.in/ns/lv2core/lv2.h" @@ -52,6 +53,7 @@ extern "C" { #define LILV_NS_FOAF "http://xmlns.com/foaf/0.1/" #define LILV_NS_LILV "http://drobilla.net/ns/lilv#" #define LILV_NS_LV2 "http://lv2plug.in/ns/lv2core#" +#define LILV_NS_OWL "http://www.w3.org/2002/07/owl#" #define LILV_NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#" #define LILV_NS_RDFS "http://www.w3.org/2000/01/rdf-schema#" #define LILV_NS_XSD "http://www.w3.org/2001/XMLSchema#" @@ -900,6 +902,27 @@ bool lilv_plugin_is_replaced(const LilvPlugin* plugin); /** + Write the Turtle description of @c plugin to @c file. + + This function is particularly useful for porting plugins in conjunction with + an LV2 bridge such as NASPRO. +*/ +LILV_API +void +lilv_plugin_write_description(LilvWorld* world, + const LilvPlugin* plugin, + const LilvNode* base_uri, + FILE* plugin_file); + +LILV_API +void +lilv_plugin_write_manifest_entry(LilvWorld* world, + const LilvPlugin* plugin, + const LilvNode* base_uri, + FILE* manifest_file, + const char* plugin_file_path); + +/** @} @name Port @{ diff --git a/src/plugin.c b/src/plugin.c index 09820fc..f7adb18 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -18,6 +18,7 @@ #include <assert.h> #include <math.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -793,3 +794,121 @@ lilv_plugin_get_uis(const LilvPlugin* p) return NULL; } } + +static size_t +file_sink(const void* buf, size_t len, void* stream) +{ + FILE* file = (FILE*)stream; + return fwrite(buf, 1, len, file); +} + +static SerdEnv* +new_lv2_env(const SerdNode* base) +{ + SerdEnv* env = serd_env_new(base); + +#define USTR(s) ((const uint8_t*)s) + serd_env_set_prefix_from_strings(env, USTR("doap"), USTR(LILV_NS_DOAP)); + serd_env_set_prefix_from_strings(env, USTR("foaf"), USTR(LILV_NS_FOAF)); + serd_env_set_prefix_from_strings(env, USTR("lv2"), USTR(LILV_NS_LV2)); + serd_env_set_prefix_from_strings(env, USTR("owl"), USTR(LILV_NS_OWL)); + serd_env_set_prefix_from_strings(env, USTR("rdf"), USTR(LILV_NS_RDF)); + serd_env_set_prefix_from_strings(env, USTR("rdfs"), USTR(LILV_NS_RDFS)); + serd_env_set_prefix_from_strings(env, USTR("xsd"), USTR(LILV_NS_XSD)); + + return env; +} + +static void +maybe_write_prefixes(SerdWriter* writer, SerdEnv* env, FILE* file) +{ + fseek(file, 0, SEEK_END); + if (ftell(file) == 0) { + serd_env_foreach( + env, (SerdPrefixSink)serd_writer_set_prefix, writer); + } else { + fprintf(file, "\n"); + } +} + +LILV_API +void +lilv_plugin_write_description(LilvWorld* world, + const LilvPlugin* plugin, + const LilvNode* base_uri, + FILE* plugin_file) +{ + const LilvNode* subject = lilv_plugin_get_uri(plugin); + const uint32_t num_ports = lilv_plugin_get_num_ports(plugin); + const SerdNode* base = sord_node_to_serd_node(base_uri->val.uri_val); + SerdEnv* env = new_lv2_env(base); + + SerdWriter* writer = serd_writer_new( + SERD_TURTLE, + SERD_STYLE_ABBREVIATED|SERD_STYLE_CURIED, + env, + NULL, + file_sink, + plugin_file); + + // Write prefixes if this is a new file + maybe_write_prefixes(writer, env, plugin_file); + + // Write plugin description + SordIter* iter = lilv_world_query_internal( + world, subject->val.uri_val, NULL, NULL); + sord_write_iter(iter, writer); + + // Write port descriptions + for (uint32_t i = 0; i < num_ports; ++i) { + const LilvPort* port = plugin->ports[i]; + SordIter* iter = lilv_world_query_internal( + world, port->node, NULL, NULL); + sord_write_iter(iter, writer); + } + + serd_writer_free(writer); + serd_env_free(env); +} + +LILV_API +void +lilv_plugin_write_manifest_entry(LilvWorld* world, + const LilvPlugin* plugin, + const LilvNode* base_uri, + FILE* manifest_file, + const char* plugin_file_path) +{ + const LilvNode* subject = lilv_plugin_get_uri(plugin); + const SerdNode* base = sord_node_to_serd_node(base_uri->val.uri_val); + SerdEnv* env = new_lv2_env(base); + + SerdWriter* writer = serd_writer_new( + SERD_TURTLE, + SERD_STYLE_ABBREVIATED|SERD_STYLE_CURIED, + env, + NULL, + file_sink, + manifest_file); + + // Write prefixes if this is a new file + maybe_write_prefixes(writer, env, manifest_file); + + // Write manifest entry + serd_writer_write_statement( + writer, 0, NULL, + sord_node_to_serd_node(subject->val.uri_val), + sord_node_to_serd_node(plugin->world->rdf_a_node), + sord_node_to_serd_node(plugin->world->lv2_plugin_node), 0, 0); + + const SerdNode file_node = serd_node_from_string( + SERD_URI, (const uint8_t*)plugin_file_path); + serd_writer_write_statement( + writer, 0, NULL, + sord_node_to_serd_node(subject->val.uri_val), + sord_node_to_serd_node(plugin->world->rdfs_seealso_node), + &file_node, 0, 0); + + serd_writer_free(writer); + serd_env_free(env); +} diff --git a/utils/lv2info.c b/utils/lv2info.c index e833a16..1f3eb91 100644 --- a/utils/lv2info.c +++ b/utils/lv2info.c @@ -312,15 +312,50 @@ print_version(void) void print_usage(void) { - printf("Usage: lv2info PLUGIN_URI\n"); - printf("Show information about an installed LV2 plugin.\n"); + printf( + "Usage: lv2info [OPTIONS] PLUGIN_URI\n" + "Show information about an installed LV2 plugin.\n\n" + " -p FILE Write Turtle description of plugin to FILE\n" + " -m FILE Add record of plugin to manifest FILE\n" + " --help Display this help and exit\n" + " --version Output version information and exit\n\n" + "For -p and -m, Turtle files are appended to (not overwritten),\n" + "and @prefix directives are only written if the file was empty.\n" + "This allows several plugins to be added to a single file.\n"); } int main(int argc, char** argv) { + if (argc == 1) { + print_usage(); + return 1; + } + + const char* plugin_file = NULL; + const char* manifest_file = NULL; + const char* plugin_uri = NULL; + for (int i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "--version")) { + print_version(); + return 0; + } else if (!strcmp(argv[i], "--help")) { + print_usage(); + return 0; + } else if (!strcmp(argv[i], "-p")) { + plugin_file = argv[++i]; + } else if (!strcmp(argv[i], "-m")) { + manifest_file = argv[++i]; + } else if (argv[i][0] == '-') { + print_usage(); + return 1; + } else if (i == argc - 1) { + plugin_uri = argv[i]; + } + } + int ret = 0; - setlocale (LC_ALL, ""); + setlocale(LC_ALL, ""); LilvWorld* world = lilv_world_new(); lilv_world_load_all(world); @@ -338,32 +373,25 @@ main(int argc, char** argv) title_pred = lilv_new_uri(world, NS_DC "title"); supports_event_pred = lilv_new_uri(world, NS_EV "supportsEvent"); - if (argc != 2) { - print_usage(); - ret = 1; - goto done; - } - - if (!strcmp(argv[1], "--version")) { - print_version(); - ret = 0; - goto done; - } else if (!strcmp(argv[1], "--help")) { - print_usage(); - ret = 0; - goto done; - } else if (argv[1][0] == '-') { - print_usage(); - ret = 2; - goto done; - } - const LilvPlugins* plugins = lilv_world_get_all_plugins(world); - LilvNode* uri = lilv_new_uri(world, argv[1]); + LilvNode* uri = lilv_new_uri(world, plugin_uri); + const LilvPlugin* p = lilv_plugins_get_by_uri(plugins, uri); - const LilvPlugin* p = lilv_plugins_get_by_uri(plugins, uri); + if (p && plugin_file) { + LilvNode* base = lilv_new_uri(world, plugin_file); - if (p) { + FILE* plugin_fd = fopen(plugin_file, "a"); + lilv_plugin_write_description(world, p, base, plugin_fd); + fclose(plugin_fd); + + if (manifest_file) { + FILE* manifest_fd = fopen(manifest_file, "a"); + lilv_plugin_write_manifest_entry( + world, p, base, manifest_fd, plugin_file); + fclose(manifest_fd); + } + lilv_node_free(base); + } else if (p) { print_plugin(world, p); } else { fprintf(stderr, "Plugin not found.\n"); @@ -373,7 +401,6 @@ main(int argc, char** argv) lilv_node_free(uri); -done: lilv_node_free(title_pred); lilv_node_free(role_pred); lilv_node_free(preset_pred); @@ -8,7 +8,7 @@ import waflib.Options as Options import waflib.Logs as Logs # Version of this package (even if built as a child) -LILV_VERSION = '0.4.4' +LILV_VERSION = '0.5.0' LILV_MAJOR_VERSION = '0' # Library version (UNIX style major, minor, micro) |