diff --git a/src/RawTemplater/Templating/Templater.cpp b/src/RawTemplater/Templating/Templater.cpp index 58081582..91ebc12a 100644 --- a/src/RawTemplater/Templating/Templater.cpp +++ b/src/RawTemplater/Templating/Templater.cpp @@ -170,6 +170,7 @@ namespace templating m_filename(std::move(filename)), m_output_directory(outputDirectory), m_first_line(true), + m_skip_pass(false), m_write_output_to_file(false) { fs::path filenamePath(m_filename); @@ -187,7 +188,7 @@ namespace templating for (const auto& activeVariation : m_active_variations) activeVariation->Apply(m_current_pass.m_defines_proxy.get()); - while (!m_current_pass.m_stream->Eof()) + while (!m_skip_pass && !m_current_pass.m_stream->Eof()) { auto nextLine = m_current_pass.m_stream->NextLine(); @@ -211,6 +212,9 @@ namespace templating } } + if (m_skip_pass) + return true; + if (!m_write_output_to_file) { if (!OpenOutputStream()) @@ -305,6 +309,18 @@ namespace templating return true; } + bool SkipPass() override + { + if (m_write_output_to_file) + { + std::cerr << "Cannot skip when already writing to file\n"; + return false; + } + + m_skip_pass = true; + return true; + } + private: bool OpenOutputStream() { @@ -333,6 +349,7 @@ namespace templating const fs::path m_output_directory; bool m_first_line; + bool m_skip_pass; bool m_write_output_to_file; std::ofstream m_output_stream; std::ostringstream m_output_cache; diff --git a/src/RawTemplater/Templating/TemplatingStreamProxy.cpp b/src/RawTemplater/Templating/TemplatingStreamProxy.cpp index 1f50ffb4..64337c57 100644 --- a/src/RawTemplater/Templating/TemplatingStreamProxy.cpp +++ b/src/RawTemplater/Templating/TemplatingStreamProxy.cpp @@ -122,6 +122,22 @@ bool TemplatingStreamProxy::MatchFilenameDirective(const ParserLine& line, const return true; } +bool TemplatingStreamProxy::MatchSkipDirective(const ParserLine& line, const unsigned directiveStartPosition, const unsigned directiveEndPosition) const +{ + auto currentPosition = directiveStartPosition; + + if (directiveEndPosition - directiveStartPosition != std::char_traits::length(SKIP_DIRECTIVE) + || !MatchString(line, currentPosition, SKIP_DIRECTIVE, std::char_traits::length(SKIP_DIRECTIVE))) + { + return false; + } + + if (!m_templater_control->SkipPass()) + throw ParsingException(TokenPos(*line.m_filename, line.m_line_number, 1), "skip directive failed"); + + return true; +} + bool TemplatingStreamProxy::MatchDirectives(const ParserLine& line) const { unsigned directiveStartPos, directiveEndPos; @@ -133,7 +149,8 @@ bool TemplatingStreamProxy::MatchDirectives(const ParserLine& line) const return MatchSwitchDirective(line, directiveStartPos, directiveEndPos) || MatchOptionsDirective(line, directiveStartPos, directiveEndPos) - || MatchFilenameDirective(line, directiveStartPos, directiveEndPos); + || MatchFilenameDirective(line, directiveStartPos, directiveEndPos) + || MatchSkipDirective(line, directiveStartPos, directiveEndPos); } ParserLine TemplatingStreamProxy::NextLine() diff --git a/src/RawTemplater/Templating/TemplatingStreamProxy.h b/src/RawTemplater/Templating/TemplatingStreamProxy.h index d885d53b..36676dc1 100644 --- a/src/RawTemplater/Templating/TemplatingStreamProxy.h +++ b/src/RawTemplater/Templating/TemplatingStreamProxy.h @@ -21,6 +21,7 @@ namespace templating virtual bool AddSwitch(std::string switchName) = 0; virtual bool AddOptions(std::string optionsName, std::vector optionValues) = 0; virtual bool SetFileName(const std::string& fileName) = 0; + virtual bool SkipPass() = 0; }; class TemplatingStreamProxy final : public AbstractDirectiveStreamProxy @@ -40,10 +41,12 @@ namespace templating static constexpr const char* SWITCH_DIRECTIVE = "switch"; static constexpr const char* OPTIONS_DIRECTIVE = "options"; static constexpr const char* FILENAME_DIRECTIVE = "filename"; + static constexpr const char* SKIP_DIRECTIVE = "skip"; _NODISCARD bool MatchSwitchDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition) const; _NODISCARD bool MatchOptionsDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition) const; _NODISCARD bool MatchFilenameDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition) const; + _NODISCARD bool MatchSkipDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition) const; _NODISCARD bool MatchDirectives(const ParserLine& line) const; IParserLineStream* const m_stream;