summaryrefslogtreecommitdiffstats
path: root/src/Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Parser.cpp')
-rw-r--r--src/Parser.cpp104
1 files changed, 60 insertions, 44 deletions
diff --git a/src/Parser.cpp b/src/Parser.cpp
index 5f9ae6e1..61495c9f 100644
--- a/src/Parser.cpp
+++ b/src/Parser.cpp
@@ -279,35 +279,32 @@ parse_block(Ingen::World* world,
Sord::URI(*world->rdf_world(), uris.ingen_prototype)
};
- std::string type_uri;
- for (const Sord::URI& prototype : prototype_predicates) {
- for (Sord::Iter p = model.find(subject, prototype, Sord::Node()); !p.end(); ++p) {
- const std::string prot_uri = relative_uri(
- base_uri, p.get_object().to_string(), false);
- if (serd_uri_string_has_scheme((const uint8_t*)prot_uri.c_str())) {
- /* Ignore prototypes that are relative to this bundle, they are
- blocks (probably from copy and paste), but we want files or
- LV2 plugins here. */
- type_uri = prot_uri;
- break;
- }
+ // Get prototype
+ Sord::Node prototype;
+ for (const Sord::URI& pred : prototype_predicates) {
+ prototype = model.get(subject, pred, Sord::Node());
+ if (prototype.is_valid()) {
+ break;
}
}
- if (type_uri.empty()) {
+ if (!prototype.is_valid()) {
world->log().error(
fmt("Block %1% (%2%) missing mandatory lv2:prototype\n") %
subject.to_string() % path);
return boost::optional<Raul::Path>();
}
- if (!serd_uri_string_has_scheme((const uint8_t*)type_uri.c_str())) {
+ const uint8_t* type_uri = (const uint8_t*)prototype.to_string().c_str();
+ if (!serd_uri_string_has_scheme(type_uri) ||
+ !strncmp((const char*)type_uri, "file:", 5)) {
+ // Prototype is a file, subgraph
SerdURI base_uri_parts;
serd_uri_parse((const uint8_t*)base_uri.c_str(), &base_uri_parts);
SerdURI ignored;
SerdNode sub_uri = serd_node_new_uri_from_string(
- (const uint8_t*)type_uri.c_str(),
+ type_uri,
&base_uri_parts,
&ignored);
@@ -328,9 +325,10 @@ parse_block(Ingen::World* world,
path.parent(), Raul::Symbol(path.symbol()));
parse_graph(world, target, model, base_uri,
- subject, Resource::Graph::DEFAULT,
+ subject, Resource::Graph::EXTERNAL,
path.parent(), Raul::Symbol(path.symbol()));
} else {
+ // Prototype is non-file URI, plugin
Resource::Properties props = get_properties(
world, model, subject, Resource::Graph::DEFAULT);
props.insert(make_pair(uris.rdf_type,
@@ -385,6 +383,41 @@ parse_graph(Ingen::World* world,
Resource::Properties props = get_properties(world, model, subject_node, ctx);
target->put(Node::path_to_uri(graph_path), props, ctx);
+ // For each port on this graph
+ typedef std::map<uint32_t, PortRecord> PortRecords;
+ PortRecords ports;
+ for (Sord::Iter p = model.find(graph, lv2_port, nil); !p.end(); ++p) {
+ Sord::Node port = p.get_object();
+
+ // Get all properties
+ uint32_t index = 0;
+ boost::optional<PortRecord> port_record = get_port(
+ world, model, port, ctx, graph_path, &index);
+ if (!port_record) {
+ world->log().error(fmt("Invalid port %1%\n") % port);
+ return boost::optional<Raul::Path>();
+ }
+
+ // Store port information in ports map
+ if (ports.find(index) == ports.end()) {
+ ports[index] = *port_record;
+ } else {
+ world->log().error(fmt("Ignored port %1% with duplicate index %2%\n")
+ % port % index);
+ }
+ }
+
+ // Create ports in order by index
+ for (const auto& p : ports) {
+ target->put(Node::path_to_uri(p.second.first),
+ p.second.second,
+ ctx);
+ }
+
+ if (ctx != Resource::Graph::INTERNAL) {
+ return graph_path; // Not parsing graph internals, finished now
+ }
+
// For each block in this graph
for (Sord::Iter n = model.find(subject_node, ingen_block, nil); !n.end(); ++n) {
Sord::Node node = n.get_object();
@@ -399,9 +432,16 @@ parse_graph(Ingen::World* world,
for (Sord::Iter p = model.find(node, lv2_port, nil); !p.end(); ++p) {
Sord::Node port = p.get_object();
+ Resource::Graph subctx = Resource::Graph::DEFAULT;
+ if (!model.find(node,
+ Sord::URI(*world->rdf_world(), uris.rdf_type),
+ Sord::URI(*world->rdf_world(), uris.ingen_Graph)).end()) {
+ subctx = Resource::Graph::EXTERNAL;
+ }
+
// Get all properties
boost::optional<PortRecord> port_record = get_port(
- world, model, port, ctx, block_path, NULL);
+ world, model, port, subctx, block_path, NULL);
if (!port_record) {
world->log().error(fmt("Invalid port %1%\n") % port);
return boost::optional<Raul::Path>();
@@ -409,36 +449,12 @@ parse_graph(Ingen::World* world,
// Create port and/or set all port properties
target->put(Node::path_to_uri(port_record->first),
- port_record->second);
+ port_record->second,
+ subctx);
}
}
- // For each port on this graph
- typedef std::map<uint32_t, PortRecord> PortRecords;
- PortRecords ports;
- for (Sord::Iter p = model.find(graph, lv2_port, nil); !p.end(); ++p) {
- Sord::Node port = p.get_object();
-
- // Get all properties
- uint32_t index = 0;
- boost::optional<PortRecord> port_record = get_port(
- world, model, port, ctx, graph_path, &index);
- if (!port_record) {
- world->log().error(fmt("Invalid port %1%\n") % port);
- return boost::optional<Raul::Path>();
- }
-
- // Store port information in ports map
- ports[index] = *port_record;
- }
-
- // Create ports in order by index
- for (const auto& p : ports) {
- target->put(Node::path_to_uri(p.second.first),
- p.second.second,
- ctx);
- }
-
+ // Now that all ports and blocks exist, create arcs inside graph
parse_arcs(world, target, model, base_uri, subject_node, graph_path);
return graph_path;