Let the parser identify the origin of a failed #include
This commit is contained in:
parent
ba23ed810a
commit
3871d9c9b2
2 changed files with 19 additions and 9 deletions
|
|
@ -49,7 +49,7 @@ void Parser::parseVirtualFile(const fs::path& path, std::unique_ptr<Reader> read
|
||||||
if (_listener)
|
if (_listener)
|
||||||
_listener->onParseBegin();
|
_listener->onParseBegin();
|
||||||
|
|
||||||
includeNewFile(path, std::move(reader));
|
includeNewFile(path, std::move(reader), {});
|
||||||
processTopLevel();
|
processTopLevel();
|
||||||
flushCurrentHeader();
|
flushCurrentHeader();
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ void Parser::parseVirtualFile(const fs::path& path, std::unique_ptr<Reader> read
|
||||||
_listener->onParseEnd();
|
_listener->onParseEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::includeNewFile(const fs::path& path, std::unique_ptr<Reader> reader)
|
void Parser::includeNewFile(const fs::path& path, std::unique_ptr<Reader> reader, const SourceRange& includeStmtRange)
|
||||||
{
|
{
|
||||||
fs::path fullPath =
|
fs::path fullPath =
|
||||||
(path.empty() || path.is_absolute()) ? path : _originalDirectory / path;
|
(path.empty() || path.is_absolute()) ? path : _originalDirectory / path;
|
||||||
|
|
@ -69,10 +69,17 @@ void Parser::includeNewFile(const fs::path& path, std::unique_ptr<Reader> reader
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto makeErrorRange = [&]() -> SourceRange {
|
||||||
|
if (!includeStmtRange) {
|
||||||
|
SourceLocation loc;
|
||||||
|
loc.filePath = std::make_shared<fs::path>(fullPath);
|
||||||
|
return {loc, loc};
|
||||||
|
}
|
||||||
|
return includeStmtRange;
|
||||||
|
};
|
||||||
|
|
||||||
if (_included.size() == _maxIncludeDepth) {
|
if (_included.size() == _maxIncludeDepth) {
|
||||||
SourceLocation loc;
|
emitError(makeErrorRange(), "Exceeded maximum include depth (" + std::to_string(_maxIncludeDepth) + ")");
|
||||||
loc.filePath = std::make_shared<fs::path>(fullPath);
|
|
||||||
emitError({ loc, loc }, "Exceeded maximum include depth (" + std::to_string(_maxIncludeDepth) + ")");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +87,7 @@ void Parser::includeNewFile(const fs::path& path, std::unique_ptr<Reader> reader
|
||||||
auto fileReader = absl::make_unique<FileReader>(fullPath);
|
auto fileReader = absl::make_unique<FileReader>(fullPath);
|
||||||
if (fileReader->hasError()) {
|
if (fileReader->hasError()) {
|
||||||
SourceLocation loc = fileReader->location();
|
SourceLocation loc = fileReader->location();
|
||||||
emitError({ loc, loc }, "Cannot open file for reading: " + fullPath.string());
|
emitError(makeErrorRange(), "Cannot open file for reading: " + fullPath.string());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reader = std::move(fileReader);
|
reader = std::move(fileReader);
|
||||||
|
|
@ -159,15 +166,16 @@ void Parser::processDirective()
|
||||||
valid = reader.extractExactChar('"');
|
valid = reader.extractExactChar('"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SourceLocation end = reader.location();
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
SourceLocation end = reader.location();
|
|
||||||
emitError({ start, end }, "Expected \"file.sfz\" after #include.");
|
emitError({ start, end }, "Expected \"file.sfz\" after #include.");
|
||||||
recover();
|
recover();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::replace(path.begin(), path.end(), '\\', '/');
|
std::replace(path.begin(), path.end(), '\\', '/');
|
||||||
includeNewFile(path);
|
includeNewFile(path, nullptr, { start, end });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SourceLocation end = reader.location();
|
SourceLocation end = reader.location();
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ public:
|
||||||
void setListener(Listener* listener) noexcept { _listener = listener; }
|
void setListener(Listener* listener) noexcept { _listener = listener; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void includeNewFile(const fs::path& path, std::unique_ptr<Reader> reader = nullptr);
|
void includeNewFile(const fs::path& path, std::unique_ptr<Reader> reader, const SourceRange& includeStmtRange);
|
||||||
void processTopLevel();
|
void processTopLevel();
|
||||||
void processDirective();
|
void processDirective();
|
||||||
void processHeader();
|
void processHeader();
|
||||||
|
|
@ -122,6 +122,7 @@ struct SourceLocation {
|
||||||
std::shared_ptr<fs::path> filePath;
|
std::shared_ptr<fs::path> filePath;
|
||||||
size_t lineNumber = 0;
|
size_t lineNumber = 0;
|
||||||
size_t columnNumber = 0;
|
size_t columnNumber = 0;
|
||||||
|
explicit operator bool() const noexcept { return filePath != nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -130,6 +131,7 @@ struct SourceLocation {
|
||||||
struct SourceRange {
|
struct SourceRange {
|
||||||
SourceLocation start;
|
SourceLocation start;
|
||||||
SourceLocation end;
|
SourceLocation end;
|
||||||
|
explicit operator bool() const noexcept { return bool(start) && bool(end); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sfz
|
} // namespace sfz
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue