From 3871d9c9b29ac79ec5d9f046be08166313cc1bb8 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Sat, 28 Mar 2020 02:11:20 +0100 Subject: [PATCH] Let the parser identify the origin of a failed #include --- src/sfizz/parser/Parser.cpp | 24 ++++++++++++++++-------- src/sfizz/parser/Parser.h | 4 +++- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/sfizz/parser/Parser.cpp b/src/sfizz/parser/Parser.cpp index 0442081a..5994f51f 100644 --- a/src/sfizz/parser/Parser.cpp +++ b/src/sfizz/parser/Parser.cpp @@ -49,7 +49,7 @@ void Parser::parseVirtualFile(const fs::path& path, std::unique_ptr read if (_listener) _listener->onParseBegin(); - includeNewFile(path, std::move(reader)); + includeNewFile(path, std::move(reader), {}); processTopLevel(); flushCurrentHeader(); @@ -57,7 +57,7 @@ void Parser::parseVirtualFile(const fs::path& path, std::unique_ptr read _listener->onParseEnd(); } -void Parser::includeNewFile(const fs::path& path, std::unique_ptr reader) +void Parser::includeNewFile(const fs::path& path, std::unique_ptr reader, const SourceRange& includeStmtRange) { fs::path fullPath = (path.empty() || path.is_absolute()) ? path : _originalDirectory / path; @@ -69,10 +69,17 @@ void Parser::includeNewFile(const fs::path& path, std::unique_ptr reader return; } + auto makeErrorRange = [&]() -> SourceRange { + if (!includeStmtRange) { + SourceLocation loc; + loc.filePath = std::make_shared(fullPath); + return {loc, loc}; + } + return includeStmtRange; + }; + if (_included.size() == _maxIncludeDepth) { - SourceLocation loc; - loc.filePath = std::make_shared(fullPath); - emitError({ loc, loc }, "Exceeded maximum include depth (" + std::to_string(_maxIncludeDepth) + ")"); + emitError(makeErrorRange(), "Exceeded maximum include depth (" + std::to_string(_maxIncludeDepth) + ")"); return; } @@ -80,7 +87,7 @@ void Parser::includeNewFile(const fs::path& path, std::unique_ptr reader auto fileReader = absl::make_unique(fullPath); if (fileReader->hasError()) { SourceLocation loc = fileReader->location(); - emitError({ loc, loc }, "Cannot open file for reading: " + fullPath.string()); + emitError(makeErrorRange(), "Cannot open file for reading: " + fullPath.string()); return; } reader = std::move(fileReader); @@ -159,15 +166,16 @@ void Parser::processDirective() valid = reader.extractExactChar('"'); } + SourceLocation end = reader.location(); + if (!valid) { - SourceLocation end = reader.location(); emitError({ start, end }, "Expected \"file.sfz\" after #include."); recover(); return; } std::replace(path.begin(), path.end(), '\\', '/'); - includeNewFile(path); + includeNewFile(path, nullptr, { start, end }); } else { SourceLocation end = reader.location(); diff --git a/src/sfizz/parser/Parser.h b/src/sfizz/parser/Parser.h index 56b3d7ca..4e89b402 100644 --- a/src/sfizz/parser/Parser.h +++ b/src/sfizz/parser/Parser.h @@ -63,7 +63,7 @@ public: void setListener(Listener* listener) noexcept { _listener = listener; } private: - void includeNewFile(const fs::path& path, std::unique_ptr reader = nullptr); + void includeNewFile(const fs::path& path, std::unique_ptr reader, const SourceRange& includeStmtRange); void processTopLevel(); void processDirective(); void processHeader(); @@ -122,6 +122,7 @@ struct SourceLocation { std::shared_ptr filePath; size_t lineNumber = 0; size_t columnNumber = 0; + explicit operator bool() const noexcept { return filePath != nullptr; } }; /** @@ -130,6 +131,7 @@ struct SourceLocation { struct SourceRange { SourceLocation start; SourceLocation end; + explicit operator bool() const noexcept { return bool(start) && bool(end); } }; } // namespace sfz