summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lilv/lilv.h23
-rw-r--r--src/plugin.c119
-rw-r--r--utils/lv2info.c81
-rw-r--r--wscript2
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);
diff --git a/wscript b/wscript
index f6b8929..4016de7 100644
--- a/wscript
+++ b/wscript
@@ -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)