mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
Restructure StreamProxies to use common basis for matching directives
This commit is contained in:
parent
e277de4517
commit
efa39a8ac3
@ -0,0 +1,111 @@
|
||||
#include "AbstractDirectiveStreamProxy.h"
|
||||
|
||||
TokenPos AbstractDirectiveStreamProxy::CreatePos(const ParserLine& line, const unsigned position)
|
||||
{
|
||||
return TokenPos(line.m_filename.get(), line.m_line_number, static_cast<int>(position + 1));
|
||||
}
|
||||
|
||||
bool AbstractDirectiveStreamProxy::SkipWhitespace(const ParserLine& line, unsigned& position)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
if (position >= line.m_line.size())
|
||||
return false;
|
||||
|
||||
if (isspace(line.m_line[position]))
|
||||
position++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AbstractDirectiveStreamProxy::ExtractInteger(const ParserLine& line, unsigned& position, int& value)
|
||||
{
|
||||
if (position >= line.m_line.size())
|
||||
return false;
|
||||
|
||||
const auto* startPosition = &line.m_line[position];
|
||||
char* endPosition;
|
||||
value = strtol(startPosition, &endPosition, 0);
|
||||
const auto len = endPosition - startPosition;
|
||||
|
||||
if(len > 0)
|
||||
{
|
||||
position += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractDirectiveStreamProxy::ExtractIdentifier(const ParserLine& line, unsigned& position)
|
||||
{
|
||||
auto firstChar = true;
|
||||
while (true)
|
||||
{
|
||||
if (position >= line.m_line.size())
|
||||
return !firstChar;
|
||||
|
||||
const auto c = line.m_line[position];
|
||||
if (isalpha(c)
|
||||
|| c == '_'
|
||||
|| firstChar && isdigit(c))
|
||||
{
|
||||
position++;
|
||||
}
|
||||
else
|
||||
return !firstChar;
|
||||
|
||||
firstChar = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool AbstractDirectiveStreamProxy::MatchCharacter(const ParserLine& line, unsigned& position, char c)
|
||||
{
|
||||
if (position < line.m_line.size() && line.m_line[position] == c)
|
||||
{
|
||||
position++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractDirectiveStreamProxy::MatchNextCharacter(const ParserLine& line, unsigned& position, char c)
|
||||
{
|
||||
return SkipWhitespace(line, position) && MatchCharacter(line, position, c);
|
||||
}
|
||||
|
||||
bool AbstractDirectiveStreamProxy::MatchString(const ParserLine& line, unsigned& position, const char* str, unsigned len)
|
||||
{
|
||||
if (line.m_line.compare(position, len, str) == 0)
|
||||
{
|
||||
position += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractDirectiveStreamProxy::MatchNextString(const ParserLine& line, unsigned& position, const char* str, unsigned len)
|
||||
{
|
||||
return SkipWhitespace(line, position) && MatchString(line, position, str, len);
|
||||
}
|
||||
|
||||
bool AbstractDirectiveStreamProxy::FindDirective(const ParserLine& line, unsigned& directivePosition)
|
||||
{
|
||||
directivePosition = 0;
|
||||
for (; directivePosition < line.m_line.size(); directivePosition++)
|
||||
{
|
||||
const auto c = line.m_line[directivePosition];
|
||||
|
||||
if (isspace(c))
|
||||
continue;
|
||||
|
||||
return c == '#';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/IParserLineStream.h"
|
||||
#include "Parsing/TokenPos.h"
|
||||
|
||||
class AbstractDirectiveStreamProxy : public IParserLineStream
|
||||
{
|
||||
protected:
|
||||
AbstractDirectiveStreamProxy() = default;
|
||||
|
||||
static TokenPos CreatePos(const ParserLine& line, unsigned position);
|
||||
|
||||
static bool SkipWhitespace(const ParserLine& line, unsigned& position);
|
||||
static bool ExtractInteger(const ParserLine& line, unsigned& position, int& value);
|
||||
static bool ExtractIdentifier(const ParserLine& line, unsigned& position);
|
||||
static bool MatchCharacter(const ParserLine& line, unsigned& position, char c);
|
||||
static bool MatchNextCharacter(const ParserLine& line, unsigned& position, char c);
|
||||
static bool MatchString(const ParserLine& line, unsigned& position, const char* str, unsigned len);
|
||||
static bool MatchNextString(const ParserLine& line, unsigned& position, const char* str, unsigned len);
|
||||
|
||||
static bool FindDirective(const ParserLine& line, unsigned& directivePosition);
|
||||
};
|
@ -11,67 +11,37 @@ DefinesStreamProxy::DefinesStreamProxy(IParserLineStream* stream)
|
||||
{
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::FindDirective(const ParserLine& line, unsigned& directivePosition)
|
||||
bool DefinesStreamProxy::MatchDefineDirective(const ParserLine& line, unsigned directivePosition)
|
||||
{
|
||||
directivePosition = 0;
|
||||
for (; directivePosition < line.m_line.size(); directivePosition++)
|
||||
{
|
||||
const auto c = line.m_line[directivePosition];
|
||||
|
||||
if (isspace(c))
|
||||
continue;
|
||||
|
||||
return c == '#';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool DefinesStreamProxy::MatchDefineDirective(const ParserLine& line, const unsigned directivePosition)
|
||||
{
|
||||
constexpr auto directiveLength = std::char_traits<char>::length(DEFINE_DIRECTIVE);
|
||||
if (line.m_line.compare(directivePosition + 1, directiveLength, DEFINE_DIRECTIVE) != 0)
|
||||
if (!MatchString(line, directivePosition, DEFINE_DIRECTIVE, std::char_traits<char>::length(DEFINE_DIRECTIVE)))
|
||||
return false;
|
||||
|
||||
const auto nameStartPos = directivePosition + directiveLength + 1;
|
||||
auto nameEndPos = nameStartPos;
|
||||
for (; nameEndPos < line.m_line.size(); nameEndPos++)
|
||||
{
|
||||
if (isspace(line.m_line[nameEndPos]))
|
||||
break;
|
||||
}
|
||||
const auto nameStartPos = directivePosition;
|
||||
if (!ExtractIdentifier(line, directivePosition))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot ifdef without a name.");
|
||||
|
||||
if (nameStartPos == nameEndPos)
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, static_cast<int>(nameStartPos + 1)), "Defines need a name.");
|
||||
|
||||
const auto name = line.m_line.substr(nameStartPos, nameEndPos - nameStartPos);
|
||||
const auto name = line.m_line.substr(nameStartPos, directivePosition - nameStartPos);
|
||||
std::string value;
|
||||
if (nameEndPos < line.m_line.size())
|
||||
value = line.m_line.substr(nameEndPos + 1);
|
||||
if (directivePosition < line.m_line.size())
|
||||
value = line.m_line.substr(directivePosition + 1);
|
||||
m_defines[name] = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::MatchUndefDirective(const ParserLine& line, const unsigned directivePosition)
|
||||
bool DefinesStreamProxy::MatchUndefDirective(const ParserLine& line, unsigned directivePosition)
|
||||
{
|
||||
constexpr auto directiveLength = std::char_traits<char>::length(UNDEF_DIRECTIVE);
|
||||
if (line.m_line.compare(directivePosition + 1, directiveLength, UNDEF_DIRECTIVE) != 0)
|
||||
if (!MatchString(line, directivePosition, UNDEF_DIRECTIVE, std::char_traits<char>::length(UNDEF_DIRECTIVE)))
|
||||
return false;
|
||||
|
||||
const auto nameStartPos = directivePosition + directiveLength + 1;
|
||||
auto nameEndPos = nameStartPos;
|
||||
for (; nameEndPos < line.m_line.size(); nameEndPos++)
|
||||
{
|
||||
if (isspace(line.m_line[nameEndPos]))
|
||||
break;
|
||||
}
|
||||
if (!SkipWhitespace(line, directivePosition))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot undef without a name.");
|
||||
|
||||
if (nameStartPos == nameEndPos)
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, static_cast<int>(nameStartPos + 1)), "Cannot undef without a name.");
|
||||
const auto nameStartPos = directivePosition;
|
||||
if (!ExtractIdentifier(line, directivePosition))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot ifdef without a name.");
|
||||
|
||||
const auto name = line.m_line.substr(nameStartPos, nameEndPos - nameStartPos);
|
||||
const auto name = line.m_line.substr(nameStartPos, directivePosition - nameStartPos);
|
||||
const auto entry = m_defines.find(name);
|
||||
|
||||
if (entry != m_defines.end())
|
||||
@ -80,18 +50,14 @@ bool DefinesStreamProxy::MatchUndefDirective(const ParserLine& line, const unsig
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::MatchIfdefDirective(const ParserLine& line, const unsigned directivePosition)
|
||||
bool DefinesStreamProxy::MatchIfdefDirective(const ParserLine& line, unsigned directivePosition)
|
||||
{
|
||||
constexpr auto directiveLengthIfdef = std::char_traits<char>::length(IFDEF_DIRECTIVE);
|
||||
constexpr auto directiveLengthIfndef = std::char_traits<char>::length(IFNDEF_DIRECTIVE);
|
||||
|
||||
auto len = directiveLengthIfdef;
|
||||
auto reverse = false;
|
||||
if (line.m_line.compare(directivePosition + 1, directiveLengthIfdef, IFDEF_DIRECTIVE) != 0)
|
||||
if(!MatchString(line, directivePosition, IFDEF_DIRECTIVE, std::char_traits<char>::length(IFDEF_DIRECTIVE)))
|
||||
{
|
||||
if (line.m_line.compare(directivePosition + 1, directiveLengthIfndef, IFNDEF_DIRECTIVE) != 0)
|
||||
if (!MatchString(line, directivePosition, IFNDEF_DIRECTIVE, std::char_traits<char>::length(IFNDEF_DIRECTIVE)))
|
||||
return false;
|
||||
len = directiveLengthIfndef;
|
||||
|
||||
reverse = true;
|
||||
}
|
||||
|
||||
@ -101,18 +67,14 @@ bool DefinesStreamProxy::MatchIfdefDirective(const ParserLine& line, const unsig
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto nameStartPos = directivePosition + len + 1;
|
||||
auto nameEndPos = nameStartPos;
|
||||
for (; nameEndPos < line.m_line.size(); nameEndPos++)
|
||||
{
|
||||
if (isspace(line.m_line[nameEndPos]))
|
||||
break;
|
||||
}
|
||||
if (!SkipWhitespace(line, directivePosition))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot ifdef without a name.");
|
||||
|
||||
if (nameStartPos == nameEndPos)
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, static_cast<int>(nameStartPos + 1)), "Cannot ifdef without a name.");
|
||||
const auto nameStartPos = directivePosition;
|
||||
if(!ExtractIdentifier(line, directivePosition))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot ifdef without a name.");
|
||||
|
||||
const auto name = line.m_line.substr(nameStartPos, nameEndPos - nameStartPos);
|
||||
const auto name = line.m_line.substr(nameStartPos, directivePosition - nameStartPos);
|
||||
const auto entry = m_defines.find(name);
|
||||
|
||||
if (entry != m_defines.end())
|
||||
@ -123,10 +85,9 @@ bool DefinesStreamProxy::MatchIfdefDirective(const ParserLine& line, const unsig
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::MatchElseDirective(const ParserLine& line, const unsigned directivePosition)
|
||||
bool DefinesStreamProxy::MatchElseDirective(const ParserLine& line, unsigned directivePosition)
|
||||
{
|
||||
constexpr auto directiveLength = std::char_traits<char>::length(ELSE_DIRECTIVE);
|
||||
if (line.m_line.compare(directivePosition + 1, directiveLength, ELSE_DIRECTIVE) != 0)
|
||||
if (!MatchString(line, directivePosition, ELSE_DIRECTIVE, std::char_traits<char>::length(ELSE_DIRECTIVE)))
|
||||
return false;
|
||||
|
||||
if (m_ignore_depth > 0)
|
||||
@ -135,15 +96,14 @@ bool DefinesStreamProxy::MatchElseDirective(const ParserLine& line, const unsign
|
||||
if (!m_modes.empty())
|
||||
m_modes.top() = !m_modes.top();
|
||||
else
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, static_cast<int>(directivePosition + 1)), "Cannot use else without ifdef");
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot use else without ifdef");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::MatchEndifDirective(const ParserLine& line, const unsigned directivePosition)
|
||||
bool DefinesStreamProxy::MatchEndifDirective(const ParserLine& line, unsigned directivePosition)
|
||||
{
|
||||
constexpr auto directiveLength = std::char_traits<char>::length(ENDIF_DIRECTIVE);
|
||||
if (line.m_line.compare(directivePosition + 1, directiveLength, ENDIF_DIRECTIVE) != 0)
|
||||
if (!MatchString(line, directivePosition, ENDIF_DIRECTIVE, std::char_traits<char>::length(ENDIF_DIRECTIVE)))
|
||||
return false;
|
||||
|
||||
if (m_ignore_depth > 0)
|
||||
@ -155,7 +115,7 @@ bool DefinesStreamProxy::MatchEndifDirective(const ParserLine& line, const unsig
|
||||
if (!m_modes.empty())
|
||||
m_modes.pop();
|
||||
else
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, static_cast<int>(directivePosition + 1)), "Cannot use endif without ifdef");
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot use endif without ifdef");
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -167,9 +127,16 @@ bool DefinesStreamProxy::MatchDirectives(const ParserLine& line)
|
||||
if (!FindDirective(line, directivePos))
|
||||
return false;
|
||||
|
||||
return MatchDefineDirective(line, directivePos)
|
||||
|| MatchUndefDirective(line, directivePos)
|
||||
|| MatchIfdefDirective(line, directivePos)
|
||||
directivePos++;
|
||||
|
||||
if(m_modes.empty() || m_modes.top() == true)
|
||||
{
|
||||
if (MatchDefineDirective(line, directivePos)
|
||||
|| MatchUndefDirective(line, directivePos))
|
||||
return true;
|
||||
}
|
||||
|
||||
return MatchIfdefDirective(line, directivePos)
|
||||
|| MatchElseDirective(line, directivePos)
|
||||
|| MatchEndifDirective(line, directivePos);
|
||||
}
|
||||
|
@ -3,9 +3,10 @@
|
||||
#include <unordered_map>
|
||||
#include <stack>
|
||||
|
||||
#include "AbstractDirectiveStreamProxy.h"
|
||||
#include "Parsing/IParserLineStream.h"
|
||||
|
||||
class DefinesStreamProxy final : public IParserLineStream
|
||||
class DefinesStreamProxy final : public AbstractDirectiveStreamProxy
|
||||
{
|
||||
static constexpr const char* DEFINE_DIRECTIVE = "define ";
|
||||
static constexpr const char* UNDEF_DIRECTIVE = "undef ";
|
||||
@ -14,12 +15,11 @@ class DefinesStreamProxy final : public IParserLineStream
|
||||
static constexpr const char* ELSE_DIRECTIVE = "else";
|
||||
static constexpr const char* ENDIF_DIRECTIVE = "endif";
|
||||
|
||||
std::unordered_map<std::string, std::string> m_defines;
|
||||
IParserLineStream* const m_stream;
|
||||
std::unordered_map<std::string, std::string> m_defines;
|
||||
std::stack<bool> m_modes;
|
||||
unsigned m_ignore_depth;
|
||||
|
||||
_NODISCARD static bool FindDirective(const ParserLine& line, unsigned& directivePosition);
|
||||
_NODISCARD bool MatchDefineDirective(const ParserLine& line, unsigned directivePosition);
|
||||
_NODISCARD bool MatchUndefDirective(const ParserLine& line, unsigned directivePosition);
|
||||
_NODISCARD bool MatchIfdefDirective(const ParserLine& line, unsigned directivePosition);
|
||||
|
@ -20,7 +20,7 @@ bool IncludingStreamProxy::ExtractIncludeFilename(const ParserLine& line, const
|
||||
while (isspace(line.m_line[currentPos]))
|
||||
{
|
||||
if (currentPos++ >= line.m_line.size())
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, currentPos), INCLUDE_QUOTES_ERROR);
|
||||
throw ParsingException(CreatePos(line, currentPos - 1), INCLUDE_QUOTES_ERROR);
|
||||
}
|
||||
|
||||
if (line.m_line[currentPos] == '"')
|
||||
@ -28,7 +28,7 @@ bool IncludingStreamProxy::ExtractIncludeFilename(const ParserLine& line, const
|
||||
else if (line.m_line[currentPos] == '<')
|
||||
isDoubleQuotes = false;
|
||||
else
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, currentPos), INCLUDE_QUOTES_ERROR);
|
||||
throw ParsingException(CreatePos(line, currentPos - 1), INCLUDE_QUOTES_ERROR);
|
||||
|
||||
filenameStartPosition = ++currentPos;
|
||||
filenameEndPosition = 0;
|
||||
@ -40,7 +40,7 @@ bool IncludingStreamProxy::ExtractIncludeFilename(const ParserLine& line, const
|
||||
if (c == '"')
|
||||
{
|
||||
if (!isDoubleQuotes)
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, currentPos), "");
|
||||
throw ParsingException(CreatePos(line, currentPos - 1), "");
|
||||
filenameEndPosition = currentPos;
|
||||
return true;
|
||||
}
|
||||
@ -48,7 +48,7 @@ bool IncludingStreamProxy::ExtractIncludeFilename(const ParserLine& line, const
|
||||
if (c == '>')
|
||||
{
|
||||
if (isDoubleQuotes)
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, currentPos), INCLUDE_QUOTES_ERROR);
|
||||
throw ParsingException(CreatePos(line, currentPos - 1), INCLUDE_QUOTES_ERROR);
|
||||
filenameEndPosition = currentPos;
|
||||
return true;
|
||||
}
|
||||
@ -57,20 +57,18 @@ bool IncludingStreamProxy::ExtractIncludeFilename(const ParserLine& line, const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IncludingStreamProxy::MatchIncludeDirective(const ParserLine& line, const unsigned directivePosition) const
|
||||
bool IncludingStreamProxy::MatchIncludeDirective(const ParserLine& line, unsigned directivePosition) const
|
||||
{
|
||||
constexpr auto directiveLength = std::char_traits<char>::length(INCLUDE_DIRECTIVE);
|
||||
if (line.m_line.compare(directivePosition + 1, directiveLength, INCLUDE_DIRECTIVE) != 0)
|
||||
if (!MatchString(line, directivePosition, INCLUDE_DIRECTIVE, std::char_traits<char>::length(INCLUDE_DIRECTIVE)))
|
||||
return false;
|
||||
|
||||
const auto currentPos = directivePosition + directiveLength + 1;
|
||||
unsigned filenameStart, filenameEnd;
|
||||
|
||||
if (!ExtractIncludeFilename(line, currentPos, filenameStart, filenameEnd))
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, currentPos), INCLUDE_QUOTES_ERROR);
|
||||
if (!ExtractIncludeFilename(line, directivePosition, filenameStart, filenameEnd))
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, directivePosition), INCLUDE_QUOTES_ERROR);
|
||||
|
||||
if (filenameEnd <= filenameStart)
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, currentPos), "No filename specified");
|
||||
throw ParsingException(CreatePos(line, directivePosition), "No filename specified");
|
||||
|
||||
const auto filename = line.m_line.substr(filenameStart, filenameEnd - filenameStart);
|
||||
|
||||
@ -78,16 +76,15 @@ bool IncludingStreamProxy::MatchIncludeDirective(const ParserLine& line, const u
|
||||
{
|
||||
std::ostringstream errorStr;
|
||||
errorStr << "Could not include file \"" << filename << "\"";
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, currentPos), errorStr.str());
|
||||
throw ParsingException(CreatePos(line, directivePosition), errorStr.str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncludingStreamProxy::MatchPragmaOnceDirective(const ParserLine& line, const unsigned directivePosition)
|
||||
bool IncludingStreamProxy::MatchPragmaOnceDirective(const ParserLine& line, unsigned directivePosition)
|
||||
{
|
||||
constexpr auto directiveLength = std::char_traits<char>::length(PRAGMA_ONCE_DIRECTIVE);
|
||||
if (line.m_line.compare(directivePosition + 1, directiveLength, PRAGMA_ONCE_DIRECTIVE) != 0)
|
||||
if(!MatchString(line, directivePosition, PRAGMA_ONCE_DIRECTIVE, std::char_traits<char>::length(PRAGMA_ONCE_DIRECTIVE)))
|
||||
return false;
|
||||
|
||||
const auto absolutePath = absolute(fs::path(line.m_filename.get()));
|
||||
@ -102,22 +99,6 @@ bool IncludingStreamProxy::MatchPragmaOnceDirective(const ParserLine& line, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncludingStreamProxy::FindDirective(const ParserLine& line, unsigned& directivePosition)
|
||||
{
|
||||
directivePosition = 0;
|
||||
for (; directivePosition < line.m_line.size(); directivePosition++)
|
||||
{
|
||||
const auto c = line.m_line[directivePosition];
|
||||
|
||||
if (isspace(c))
|
||||
continue;
|
||||
|
||||
return c == '#';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IncludingStreamProxy::MatchDirectives(const ParserLine& line)
|
||||
{
|
||||
unsigned directivePos;
|
||||
@ -125,6 +106,7 @@ bool IncludingStreamProxy::MatchDirectives(const ParserLine& line)
|
||||
if (!FindDirective(line, directivePos))
|
||||
return false;
|
||||
|
||||
directivePos++;
|
||||
return MatchIncludeDirective(line, directivePos)
|
||||
|| MatchPragmaOnceDirective(line, directivePos);
|
||||
}
|
||||
|
@ -2,9 +2,10 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "AbstractDirectiveStreamProxy.h"
|
||||
#include "Parsing/IParserLineStream.h"
|
||||
|
||||
class IncludingStreamProxy final : public IParserLineStream
|
||||
class IncludingStreamProxy final : public AbstractDirectiveStreamProxy
|
||||
{
|
||||
static constexpr const char* INCLUDE_QUOTES_ERROR = "Invalid include directive. Expected \"\" or <>";
|
||||
static constexpr const char* INCLUDE_DIRECTIVE = "include ";
|
||||
@ -13,11 +14,9 @@ class IncludingStreamProxy final : public IParserLineStream
|
||||
IParserLineStream* const m_stream;
|
||||
std::set<std::string> m_included_files;
|
||||
|
||||
|
||||
_NODISCARD static bool ExtractIncludeFilename(const ParserLine& line, unsigned includeDirectivePosition, unsigned& filenameStartPosition, unsigned& filenameEndPosition);
|
||||
_NODISCARD bool MatchIncludeDirective(const ParserLine& line, unsigned directivePosition) const;
|
||||
_NODISCARD bool MatchPragmaOnceDirective(const ParserLine& line, unsigned directivePosition);
|
||||
_NODISCARD static bool FindDirective(const ParserLine& line, unsigned& directivePosition);
|
||||
_NODISCARD bool MatchDirectives(const ParserLine& line);
|
||||
|
||||
public:
|
||||
|
@ -294,4 +294,48 @@ namespace test::parsing::impl::defines_stream_proxy
|
||||
|
||||
REQUIRE(proxy.Eof());
|
||||
}
|
||||
|
||||
TEST_CASE("DefinesStreamProxy: Ensure defines in disabled block are ignored", "[parsing][parsingstream]")
|
||||
{
|
||||
const std::vector<std::string> lines
|
||||
{
|
||||
"#ifdef LOLO",
|
||||
"#define hello world",
|
||||
"#endif",
|
||||
"hello"
|
||||
};
|
||||
|
||||
MockParserLineStream mockStream(lines);
|
||||
DefinesStreamProxy proxy(&mockStream);
|
||||
|
||||
ExpectLine(&proxy, 1, "");
|
||||
ExpectLine(&proxy, 2, "");
|
||||
ExpectLine(&proxy, 3, "");
|
||||
ExpectLine(&proxy, 4, "hello");
|
||||
|
||||
REQUIRE(proxy.Eof());
|
||||
}
|
||||
|
||||
TEST_CASE("DefinesStreamProxy: Ensure undefs in disabled block are ignored", "[parsing][parsingstream]")
|
||||
{
|
||||
const std::vector<std::string> lines
|
||||
{
|
||||
"#define hello world",
|
||||
"#ifdef LOLO",
|
||||
"#undef hello",
|
||||
"#endif",
|
||||
"hello"
|
||||
};
|
||||
|
||||
MockParserLineStream mockStream(lines);
|
||||
DefinesStreamProxy proxy(&mockStream);
|
||||
|
||||
ExpectLine(&proxy, 1, "");
|
||||
ExpectLine(&proxy, 2, "");
|
||||
ExpectLine(&proxy, 3, "");
|
||||
ExpectLine(&proxy, 4, "");
|
||||
ExpectLine(&proxy, 5, "world");
|
||||
|
||||
REQUIRE(proxy.Eof());
|
||||
}
|
||||
}
|
@ -13,7 +13,6 @@ class MockLexer final : public ILexer<TokenType>
|
||||
static_assert(std::is_base_of<IParserValue, TokenType>::value);
|
||||
|
||||
std::vector<TokenType> m_tokens;
|
||||
//std::vector<HeaderParserValue> m_tokens;
|
||||
TokenType m_eof;
|
||||
int m_pop_count;
|
||||
|
||||
@ -58,4 +57,9 @@ public:
|
||||
{
|
||||
return m_pop_count;
|
||||
}
|
||||
|
||||
_NODISCARD ParserLine GetLineForPos(const TokenPos& pos) const override
|
||||
{
|
||||
return ParserLine();
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user