From 6ee9dd106eb168a91111e5b0dd247b5d14eb86f1 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Sat, 28 Mar 2020 02:44:06 +0100 Subject: [PATCH] Add proper support of external #define --- src/sfizz/parser/Parser.cpp | 25 ++++++++++++++++++------- src/sfizz/parser/Parser.h | 10 +++++++--- tests/ParsingT.cpp | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/sfizz/parser/Parser.cpp b/src/sfizz/parser/Parser.cpp index 5994f51f..eb3c496d 100644 --- a/src/sfizz/parser/Parser.cpp +++ b/src/sfizz/parser/Parser.cpp @@ -18,20 +18,26 @@ Parser::~Parser() { } -void Parser::addDefinition(absl::string_view id, absl::string_view value) -{ - _definitions[id] = std::string(value); -} - void Parser::reset() { _pathsIncluded.clear(); + _currentDefinitions = _externalDefinitions; _currentHeader.reset(); _currentOpcodes.clear(); _errorCount = 0; _warningCount = 0; } +void Parser::addExternalDefinition(absl::string_view id, absl::string_view value) +{ + _externalDefinitions[id] = std::string(value); +} + +void Parser::clearExternalDefinitions() +{ + _externalDefinitions.clear(); +} + void Parser::parseFile(const fs::path& path) { parseVirtualFile(path, nullptr); @@ -97,6 +103,11 @@ void Parser::includeNewFile(const fs::path& path, std::unique_ptr reader _included.push_back(std::move(reader)); } +void Parser::addDefinition(absl::string_view id, absl::string_view value) +{ + _currentDefinitions[id] = std::string(value); +} + void Parser::processTopLevel() { while (!_included.empty()) { @@ -404,8 +415,8 @@ std::string Parser::expandDollarVars(const SourceRange& range, absl::string_view continue; } - auto it = _definitions.find(name); - if (it == _definitions.end()) { + auto it = _currentDefinitions.find(name); + if (it == _currentDefinitions.end()) { emitWarning(range, "The variable `" + name + "` is not defined."); continue; } diff --git a/src/sfizz/parser/Parser.h b/src/sfizz/parser/Parser.h index 4e89b402..4f6a071d 100644 --- a/src/sfizz/parser/Parser.h +++ b/src/sfizz/parser/Parser.h @@ -27,7 +27,9 @@ public: Parser(); ~Parser(); - void addDefinition(absl::string_view id, absl::string_view value); + void addExternalDefinition(absl::string_view id, absl::string_view value); + void clearExternalDefinitions(); + void parseFile(const fs::path& path); void parseString(const fs::path& path, absl::string_view sfzView); void parseVirtualFile(const fs::path& path, std::unique_ptr reader); @@ -41,7 +43,7 @@ public: typedef absl::flat_hash_map DefinitionSet; const IncludeFileSet& getIncludedFiles() const noexcept { return _pathsIncluded; } - const DefinitionSet& getDefines() const noexcept { return _definitions; } + const DefinitionSet& getDefines() const noexcept { return _currentDefinitions; } size_t getErrorCount() const noexcept { return _errorCount; } size_t getWarningCount() const noexcept { return _warningCount; } @@ -64,6 +66,7 @@ public: private: void includeNewFile(const fs::path& path, std::unique_ptr reader, const SourceRange& includeStmtRange); + void addDefinition(absl::string_view id, absl::string_view value); void processTopLevel(); void processDirective(); void processHeader(); @@ -96,7 +99,7 @@ private: Listener* _listener = nullptr; fs::path _originalDirectory { fs::current_path() }; - DefinitionSet _definitions; + DefinitionSet _externalDefinitions; // a current list of files included, last one at the back std::vector> _included; @@ -105,6 +108,7 @@ private: size_t _maxIncludeDepth = 32; bool _recursiveIncludeGuardEnabled = false; IncludeFileSet _pathsIncluded; + DefinitionSet _currentDefinitions; // parsing state absl::optional _currentHeader; diff --git a/tests/ParsingT.cpp b/tests/ParsingT.cpp index 5d35a1a9..7a51263c 100644 --- a/tests/ParsingT.cpp +++ b/tests/ParsingT.cpp @@ -415,3 +415,36 @@ TEST_CASE("[Parsing] Headers (new parser)") REQUIRE(mock.fullBlockMembers == expectedMembers); } } + +TEST_CASE("[Parsing] External definitions") +{ + sfz::Parser parser; + ParsingMocker mock; + parser.setListener(&mock); + parser.addExternalDefinition("foo", "abc"); + parser.addExternalDefinition("bar", "123"); + parser.parseString("/externalDefinitions.sfz", +R"(
+param1=$foo +param2=$bar)"); + std::vector> expectedMembers = { + {{"param1", "abc"}, {"param2", "123"}} + }; + std::vector expectedHeaders = { + "header" + }; + std::vector expectedOpcodes; + + for (auto& members: expectedMembers) + for (auto& opcode: members) + expectedOpcodes.push_back(opcode); + + REQUIRE(mock.beginnings == 1); + REQUIRE(mock.endings == 1); + REQUIRE(mock.errors.empty()); + REQUIRE(mock.warnings.empty()); + REQUIRE(mock.opcodes == expectedOpcodes); + REQUIRE(mock.headers == expectedHeaders); + REQUIRE(mock.fullBlockHeaders == expectedHeaders); + REQUIRE(mock.fullBlockMembers == expectedMembers); +}