summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/parser/ParserScope.cpp21
-rw-r--r--src/core/parser/ParserScope.hpp4
-rw-r--r--src/core/resource/ResourceRequest.cpp10
-rw-r--r--src/formats/osml/OsmlParser.cpp12
4 files changed, 39 insertions, 8 deletions
diff --git a/src/core/parser/ParserScope.cpp b/src/core/parser/ParserScope.cpp
index ce3dc94..b0a4945 100644
--- a/src/core/parser/ParserScope.cpp
+++ b/src/core/parser/ParserScope.cpp
@@ -21,6 +21,7 @@
#include <core/common/VariantWriter.hpp>
#include <core/model/Domain.hpp>
#include <core/model/Typesystem.hpp>
+#include <core/model/RootNode.hpp>
#include "ParserScope.hpp"
@@ -233,6 +234,13 @@ void ParserScope::pop()
}
flags.resize(newLen);
+ // Whenever a RootNode is popped from the stack, we have to perform deferred
+ // resolution -- however, postpone issuing error messages
+ if (nodes.back()->isa(&RttiTypes::RootNode)) {
+ Logger logger;
+ performDeferredResolution(logger, true);
+ }
+
// Remove the element from the stack
nodes.pop_back();
}
@@ -424,7 +432,7 @@ bool ParserScope::resolveTypeWithValue(const std::string &name,
resultCallback);
}
-bool ParserScope::performDeferredResolution(Logger &logger)
+bool ParserScope::performDeferredResolution(Logger &logger, bool postpone)
{
// Repeat the resolution process as long as something has changed in the
// last iteration (resolving a node may cause other nodes to be resolvable).
@@ -446,8 +454,9 @@ bool ParserScope::performDeferredResolution(Logger &logger)
// Abort if nothing has changed in the last iteration
if (!hasChange) {
// In a last step, clear the "awaitingResolution" list to allow
- // cyclical dependencies to be resolved
- if (!awaitingResolution.empty()) {
+ // cyclical dependencies to be resolved -- if the postpone flag
+ // is set, do not do this
+ if (!awaitingResolution.empty() && !postpone) {
awaitingResolution.clear();
} else {
break;
@@ -460,6 +469,12 @@ bool ParserScope::performDeferredResolution(Logger &logger)
return true;
}
+ // If the postpone flag is set to true, we'll abort here -- this function
+ // will be called again later
+ if (postpone) {
+ return false;
+ }
+
// Output error messages for all elements for which resolution did not
// succeed.
for (auto &failed : deferred) {
diff --git a/src/core/parser/ParserScope.hpp b/src/core/parser/ParserScope.hpp
index 185b845..24af6b8 100644
--- a/src/core/parser/ParserScope.hpp
+++ b/src/core/parser/ParserScope.hpp
@@ -797,8 +797,10 @@ public:
* pending deferred resolutions is cleared after this function has run.
*
* @param logger is the logger instance into which errors should be logged.
+ * @param postpone if set to true, postpones issuing any error messages and
+ * waits for node resolution.
*/
- bool performDeferredResolution(Logger &logger);
+ bool performDeferredResolution(Logger &logger, bool postpone = false);
};
}
diff --git a/src/core/resource/ResourceRequest.cpp b/src/core/resource/ResourceRequest.cpp
index 357f413..5e5bff3 100644
--- a/src/core/resource/ResourceRequest.cpp
+++ b/src/core/resource/ResourceRequest.cpp
@@ -152,6 +152,10 @@ bool ResourceRequest::deduce(Registry &registry, Logger &logger)
{
bool ok = true;
+ // Check whether all node types are supported here -- this is indicated by
+ // supportedTypes containing the extremely general "Node" type.
+ bool supportsAllNodes = supportedTypes.count(&RttiTypes::Node) > 0U;
+
// Make sure the given file name is not empty
if (path.empty()) {
logger.error("Filename may not be empty");
@@ -227,7 +231,8 @@ bool ResourceRequest::deduce(Registry &registry, Logger &logger)
logger.error(std::string("Cannot parse files of type \"") +
mimetype + std::string("\""));
ok = false;
- } else if (!Rtti::setIsOneOf(supportedTypes, parserTypes)) {
+ } else if (!supportsAllNodes &&
+ !Rtti::setIsOneOf(supportedTypes, parserTypes)) {
logger.error(std::string("Resource of type \"") + mimetype +
std::string("\" cannot be included here!"));
ok = false;
@@ -245,8 +250,7 @@ bool ResourceRequest::deduce(Registry &registry, Logger &logger)
std::string("\" cannot be included here"));
ok = false;
}
- } else if (supportedTypes.size() != 1 ||
- *supportedTypes.begin() != &RttiTypes::Node) {
+ } else if (!supportsAllNodes) {
logger.warning(std::string(
"Ambiguous resource relationship, consider "
"specifying one of ") +
diff --git a/src/formats/osml/OsmlParser.cpp b/src/formats/osml/OsmlParser.cpp
index c77da09..a24f091 100644
--- a/src/formats/osml/OsmlParser.cpp
+++ b/src/formats/osml/OsmlParser.cpp
@@ -17,9 +17,13 @@
*/
#include <core/common/Logger.hpp>
+
+#include <core/model/Document.hpp>
+
#include <core/parser/stack/GenericParserStates.hpp>
#include <core/parser/stack/Stack.hpp>
#include <core/parser/ParserContext.hpp>
+#include <core/parser/ParserScope.hpp>
#include "OsmlParser.hpp"
#include "OsmlStreamParser.hpp"
@@ -40,6 +44,11 @@ private:
Logger &logger;
/**
+ * Reference at the parser context.
+ */
+ ParserContext &ctx;
+
+ /**
* OsmlStreamParser instance responsible for converting the input stream
* into a series of osml events that are relayed to the Stack class.
*/
@@ -62,6 +71,7 @@ public:
*/
OsmlParserImplementation(CharReader &reader, ParserContext &ctx)
: logger(ctx.getLogger()),
+ ctx(ctx),
parser(reader, logger),
stack(ctx, GenericParserStates)
{
@@ -73,7 +83,7 @@ public:
void parse()
{
// Flag set to true if a "document" element needs to be created
- bool needsDocument = true;
+ bool needsDocument = ctx.getScope().select<Document>() == nullptr;
while (true) {
OsmlStreamParser::State state = parser.parse();
logger.setDefaultLocation(parser.getLocation());