mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
Properly handle tabs in pragma directives and other precompiler statements
This commit is contained in:
parent
be4e489118
commit
e19f526d8b
@ -94,17 +94,29 @@ bool AbstractDirectiveStreamProxy::MatchNextString(const ParserLine& line, unsig
|
||||
return SkipWhitespace(line, position) && MatchString(line, position, str, len);
|
||||
}
|
||||
|
||||
bool AbstractDirectiveStreamProxy::FindDirective(const ParserLine& line, unsigned& directivePosition)
|
||||
bool AbstractDirectiveStreamProxy::FindDirective(const ParserLine& line, unsigned& directiveStartPosition, unsigned& directiveEndPos)
|
||||
{
|
||||
directivePosition = 0;
|
||||
for (; directivePosition < line.m_line.size(); directivePosition++)
|
||||
directiveStartPosition = 0;
|
||||
for (; directiveStartPosition < line.m_line.size(); directiveStartPosition++)
|
||||
{
|
||||
const auto c = line.m_line[directivePosition];
|
||||
const auto c = line.m_line[directiveStartPosition];
|
||||
|
||||
if (isspace(c))
|
||||
continue;
|
||||
|
||||
return c == '#';
|
||||
if (c != '#')
|
||||
continue;
|
||||
|
||||
directiveEndPos = directiveStartPosition + 1;
|
||||
for(; directiveEndPos < line.m_line.size(); directiveEndPos++)
|
||||
{
|
||||
const auto c2 = line.m_line[directiveEndPos];
|
||||
|
||||
if (isspace(c2))
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -18,5 +18,5 @@ protected:
|
||||
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);
|
||||
static bool FindDirective(const ParserLine& line, unsigned& directiveStartPosition, unsigned& directiveEndPos);
|
||||
};
|
||||
|
@ -157,22 +157,30 @@ std::vector<std::string> DefinesStreamProxy::MatchDefineParameters(const ParserL
|
||||
return parameters;
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::MatchDefineDirective(const ParserLine& line, unsigned directivePosition)
|
||||
bool DefinesStreamProxy::MatchDefineDirective(const ParserLine& line, const unsigned directiveStartPosition, const unsigned directiveEndPosition)
|
||||
{
|
||||
if (!MatchString(line, directivePosition, DEFINE_DIRECTIVE, std::char_traits<char>::length(DEFINE_DIRECTIVE)))
|
||||
auto currentPos = directiveStartPosition;
|
||||
|
||||
if (directiveEndPosition - directiveStartPosition != std::char_traits<char>::length(DEFINE_DIRECTIVE)
|
||||
|| !MatchString(line, currentPos, DEFINE_DIRECTIVE, std::char_traits<char>::length(DEFINE_DIRECTIVE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto nameStartPos = directivePosition;
|
||||
if (!ExtractIdentifier(line, directivePosition))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot ifdef without a name.");
|
||||
if (!SkipWhitespace(line, currentPos))
|
||||
throw ParsingException(CreatePos(line, currentPos), "Cannot define without a name.");
|
||||
|
||||
const auto name = line.m_line.substr(nameStartPos, directivePosition - nameStartPos);
|
||||
const auto nameStartPos = currentPos;
|
||||
if (!ExtractIdentifier(line, currentPos))
|
||||
throw ParsingException(CreatePos(line, currentPos), "Cannot define without a name.");
|
||||
|
||||
const auto parameters = MatchDefineParameters(line, directivePosition);
|
||||
const auto name = line.m_line.substr(nameStartPos, currentPos - nameStartPos);
|
||||
|
||||
const auto parameters = MatchDefineParameters(line, currentPos);
|
||||
|
||||
std::string value;
|
||||
if (directivePosition < line.m_line.size())
|
||||
value = line.m_line.substr(directivePosition + 1);
|
||||
if (currentPos < line.m_line.size())
|
||||
value = line.m_line.substr(currentPos + 1);
|
||||
|
||||
Define define(name, value);
|
||||
define.IdentifyParameters(parameters);
|
||||
@ -181,19 +189,24 @@ bool DefinesStreamProxy::MatchDefineDirective(const ParserLine& line, unsigned d
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::MatchUndefDirective(const ParserLine& line, unsigned directivePosition)
|
||||
bool DefinesStreamProxy::MatchUndefDirective(const ParserLine& line, const unsigned directiveStartPosition, const unsigned directiveEndPosition)
|
||||
{
|
||||
if (!MatchString(line, directivePosition, UNDEF_DIRECTIVE, std::char_traits<char>::length(UNDEF_DIRECTIVE)))
|
||||
auto currentPos = directiveStartPosition;
|
||||
|
||||
if (directiveEndPosition - directiveStartPosition != std::char_traits<char>::length(UNDEF_DIRECTIVE)
|
||||
|| !MatchString(line, currentPos, UNDEF_DIRECTIVE, std::char_traits<char>::length(UNDEF_DIRECTIVE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SkipWhitespace(line, directivePosition))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot undef without a name.");
|
||||
if (!SkipWhitespace(line, currentPos))
|
||||
throw ParsingException(CreatePos(line, currentPos), "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 nameStartPos = currentPos;
|
||||
if (!ExtractIdentifier(line, currentPos))
|
||||
throw ParsingException(CreatePos(line, currentPos), "Cannot undef without a name.");
|
||||
|
||||
const auto name = line.m_line.substr(nameStartPos, directivePosition - nameStartPos);
|
||||
const auto name = line.m_line.substr(nameStartPos, currentPos - nameStartPos);
|
||||
const auto entry = m_defines.find(name);
|
||||
|
||||
if (entry != m_defines.end())
|
||||
@ -202,13 +215,19 @@ bool DefinesStreamProxy::MatchUndefDirective(const ParserLine& line, unsigned di
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::MatchIfdefDirective(const ParserLine& line, unsigned directivePosition)
|
||||
bool DefinesStreamProxy::MatchIfdefDirective(const ParserLine& line, const unsigned directiveStartPosition, const unsigned directiveEndPosition)
|
||||
{
|
||||
auto currentPos = directiveStartPosition;
|
||||
|
||||
auto reverse = false;
|
||||
if (!MatchString(line, directivePosition, IFDEF_DIRECTIVE, std::char_traits<char>::length(IFDEF_DIRECTIVE)))
|
||||
if (directiveEndPosition - directiveStartPosition != std::char_traits<char>::length(IFDEF_DIRECTIVE)
|
||||
|| !MatchString(line, currentPos, IFDEF_DIRECTIVE, std::char_traits<char>::length(IFDEF_DIRECTIVE)))
|
||||
{
|
||||
if (directiveEndPosition - directiveStartPosition != std::char_traits<char>::length(IFNDEF_DIRECTIVE)
|
||||
|| !MatchString(line, currentPos, IFNDEF_DIRECTIVE, std::char_traits<char>::length(IFNDEF_DIRECTIVE)))
|
||||
{
|
||||
if (!MatchString(line, directivePosition, IFNDEF_DIRECTIVE, std::char_traits<char>::length(IFNDEF_DIRECTIVE)))
|
||||
return false;
|
||||
}
|
||||
|
||||
reverse = true;
|
||||
}
|
||||
@ -219,14 +238,14 @@ bool DefinesStreamProxy::MatchIfdefDirective(const ParserLine& line, unsigned di
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!SkipWhitespace(line, directivePosition))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot ifdef without a name.");
|
||||
if (!SkipWhitespace(line, currentPos))
|
||||
throw ParsingException(CreatePos(line, currentPos), "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 nameStartPos = currentPos;
|
||||
if (!ExtractIdentifier(line, currentPos))
|
||||
throw ParsingException(CreatePos(line, currentPos), "Cannot ifdef without a name.");
|
||||
|
||||
const auto name = line.m_line.substr(nameStartPos, directivePosition - nameStartPos);
|
||||
const auto name = line.m_line.substr(nameStartPos, currentPos - nameStartPos);
|
||||
const auto entry = m_defines.find(name);
|
||||
|
||||
if (entry != m_defines.end())
|
||||
@ -237,10 +256,15 @@ bool DefinesStreamProxy::MatchIfdefDirective(const ParserLine& line, unsigned di
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::MatchElseDirective(const ParserLine& line, unsigned directivePosition)
|
||||
bool DefinesStreamProxy::MatchElseDirective(const ParserLine& line, const unsigned directiveStartPosition, const unsigned directiveEndPosition)
|
||||
{
|
||||
if (!MatchString(line, directivePosition, ELSE_DIRECTIVE, std::char_traits<char>::length(ELSE_DIRECTIVE)))
|
||||
auto currentPos = directiveStartPosition;
|
||||
|
||||
if (directiveEndPosition - directiveStartPosition != std::char_traits<char>::length(ELSE_DIRECTIVE)
|
||||
|| !MatchString(line, currentPos, ELSE_DIRECTIVE, std::char_traits<char>::length(ELSE_DIRECTIVE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_ignore_depth > 0)
|
||||
return true;
|
||||
@ -248,15 +272,20 @@ bool DefinesStreamProxy::MatchElseDirective(const ParserLine& line, unsigned dir
|
||||
if (!m_modes.empty())
|
||||
m_modes.top() = !m_modes.top();
|
||||
else
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot use else without ifdef");
|
||||
throw ParsingException(CreatePos(line, currentPos), "Cannot use else without ifdef");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::MatchEndifDirective(const ParserLine& line, unsigned directivePosition)
|
||||
bool DefinesStreamProxy::MatchEndifDirective(const ParserLine& line, const unsigned directiveStartPosition, const unsigned directiveEndPosition)
|
||||
{
|
||||
if (!MatchString(line, directivePosition, ENDIF_DIRECTIVE, std::char_traits<char>::length(ENDIF_DIRECTIVE)))
|
||||
auto currentPos = directiveStartPosition;
|
||||
|
||||
if (directiveEndPosition - directiveStartPosition != std::char_traits<char>::length(ENDIF_DIRECTIVE)
|
||||
|| !MatchString(line, currentPos, ENDIF_DIRECTIVE, std::char_traits<char>::length(ENDIF_DIRECTIVE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_ignore_depth > 0)
|
||||
{
|
||||
@ -267,30 +296,31 @@ bool DefinesStreamProxy::MatchEndifDirective(const ParserLine& line, unsigned di
|
||||
if (!m_modes.empty())
|
||||
m_modes.pop();
|
||||
else
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Cannot use endif without ifdef");
|
||||
throw ParsingException(CreatePos(line, currentPos), "Cannot use endif without ifdef");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::MatchDirectives(const ParserLine& line)
|
||||
{
|
||||
unsigned directivePos;
|
||||
unsigned directiveStartPos;
|
||||
unsigned directiveEndPos;
|
||||
|
||||
if (!FindDirective(line, directivePos))
|
||||
if (!FindDirective(line, directiveStartPos, directiveEndPos))
|
||||
return false;
|
||||
|
||||
directivePos++;
|
||||
directiveStartPos++;
|
||||
|
||||
if (m_modes.empty() || m_modes.top() == true)
|
||||
{
|
||||
if (MatchDefineDirective(line, directivePos)
|
||||
|| MatchUndefDirective(line, directivePos))
|
||||
if (MatchDefineDirective(line, directiveStartPos, directiveEndPos)
|
||||
|| MatchUndefDirective(line, directiveStartPos, directiveEndPos))
|
||||
return true;
|
||||
}
|
||||
|
||||
return MatchIfdefDirective(line, directivePos)
|
||||
|| MatchElseDirective(line, directivePos)
|
||||
|| MatchEndifDirective(line, directivePos);
|
||||
return MatchIfdefDirective(line, directiveStartPos, directiveEndPos)
|
||||
|| MatchElseDirective(line, directiveStartPos, directiveEndPos)
|
||||
|| MatchEndifDirective(line, directiveStartPos, directiveEndPos);
|
||||
}
|
||||
|
||||
bool DefinesStreamProxy::FindDefineForWord(const ParserLine& line, const unsigned wordStart, const unsigned wordEnd, Define*& value)
|
||||
@ -427,7 +457,8 @@ void DefinesStreamProxy::ExpandDefines(ParserLine& line)
|
||||
}
|
||||
|
||||
defineIterations++;
|
||||
} while (usesDefines);
|
||||
}
|
||||
while (usesDefines);
|
||||
}
|
||||
|
||||
void DefinesStreamProxy::AddDefine(Define define)
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
class DefinesStreamProxy final : public AbstractDirectiveStreamProxy
|
||||
{
|
||||
static constexpr const char* DEFINE_DIRECTIVE = "define ";
|
||||
static constexpr const char* UNDEF_DIRECTIVE = "undef ";
|
||||
static constexpr const char* IFDEF_DIRECTIVE = "ifdef ";
|
||||
static constexpr const char* IFNDEF_DIRECTIVE = "ifndef ";
|
||||
static constexpr const char* DEFINE_DIRECTIVE = "define";
|
||||
static constexpr const char* UNDEF_DIRECTIVE = "undef";
|
||||
static constexpr const char* IFDEF_DIRECTIVE = "ifdef";
|
||||
static constexpr const char* IFNDEF_DIRECTIVE = "ifndef";
|
||||
static constexpr const char* ELSE_DIRECTIVE = "else";
|
||||
static constexpr const char* ENDIF_DIRECTIVE = "endif";
|
||||
|
||||
@ -48,11 +48,11 @@ private:
|
||||
unsigned m_ignore_depth;
|
||||
|
||||
static std::vector<std::string> MatchDefineParameters(const ParserLine& line, unsigned& parameterPosition);
|
||||
_NODISCARD bool MatchDefineDirective(const ParserLine& line, unsigned directivePosition);
|
||||
_NODISCARD bool MatchUndefDirective(const ParserLine& line, unsigned directivePosition);
|
||||
_NODISCARD bool MatchIfdefDirective(const ParserLine& line, unsigned directivePosition);
|
||||
_NODISCARD bool MatchElseDirective(const ParserLine& line, unsigned directivePosition);
|
||||
_NODISCARD bool MatchEndifDirective(const ParserLine& line, unsigned directivePosition);
|
||||
_NODISCARD bool MatchDefineDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition);
|
||||
_NODISCARD bool MatchUndefDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition);
|
||||
_NODISCARD bool MatchIfdefDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition);
|
||||
_NODISCARD bool MatchElseDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition);
|
||||
_NODISCARD bool MatchEndifDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition);
|
||||
_NODISCARD bool MatchDirectives(const ParserLine& line);
|
||||
|
||||
static void ExtractParametersFromDefineUsage(const ParserLine& line, unsigned parameterStart, unsigned& parameterEnd, std::vector<std::string>& parameterValues);
|
||||
|
@ -57,18 +57,23 @@ bool IncludingStreamProxy::ExtractIncludeFilename(const ParserLine& line, const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IncludingStreamProxy::MatchIncludeDirective(const ParserLine& line, unsigned directivePosition) const
|
||||
bool IncludingStreamProxy::MatchIncludeDirective(const ParserLine& line, const unsigned directiveStartPos, const unsigned directiveEndPos) const
|
||||
{
|
||||
if (!MatchString(line, directivePosition, INCLUDE_DIRECTIVE, std::char_traits<char>::length(INCLUDE_DIRECTIVE)))
|
||||
auto currentPos = directiveStartPos;
|
||||
|
||||
if (directiveEndPos - directiveStartPos != std::char_traits<char>::length(INCLUDE_DIRECTIVE)
|
||||
|| !MatchString(line, currentPos, INCLUDE_DIRECTIVE, std::char_traits<char>::length(INCLUDE_DIRECTIVE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned filenameStart, filenameEnd;
|
||||
|
||||
if (!ExtractIncludeFilename(line, directivePosition, filenameStart, filenameEnd))
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, static_cast<int>(directivePosition)), INCLUDE_QUOTES_ERROR);
|
||||
if (!ExtractIncludeFilename(line, currentPos, filenameStart, filenameEnd))
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, static_cast<int>(currentPos)), INCLUDE_QUOTES_ERROR);
|
||||
|
||||
if (filenameEnd <= filenameStart)
|
||||
throw ParsingException(CreatePos(line, directivePosition), "No filename specified");
|
||||
throw ParsingException(CreatePos(line, currentPos), "No filename specified");
|
||||
|
||||
const auto filename = line.m_line.substr(filenameStart, filenameEnd - filenameStart);
|
||||
|
||||
@ -76,15 +81,26 @@ bool IncludingStreamProxy::MatchIncludeDirective(const ParserLine& line, unsigne
|
||||
{
|
||||
std::ostringstream errorStr;
|
||||
errorStr << "Could not include file \"" << filename << "\"";
|
||||
throw ParsingException(CreatePos(line, directivePosition), errorStr.str());
|
||||
throw ParsingException(CreatePos(line, currentPos), errorStr.str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncludingStreamProxy::MatchPragmaOnceDirective(const ParserLine& line, unsigned directivePosition)
|
||||
bool IncludingStreamProxy::MatchPragmaOnceDirective(const ParserLine& line, const unsigned directiveStartPos, const unsigned directiveEndPos)
|
||||
{
|
||||
if(!MatchString(line, directivePosition, PRAGMA_ONCE_DIRECTIVE, std::char_traits<char>::length(PRAGMA_ONCE_DIRECTIVE)))
|
||||
auto currentPos = directiveStartPos;
|
||||
|
||||
if(directiveEndPos - directiveStartPos != std::char_traits<char>::length(PRAGMA_DIRECTIVE)
|
||||
|| !MatchString(line, currentPos, PRAGMA_DIRECTIVE, std::char_traits<char>::length(PRAGMA_DIRECTIVE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SkipWhitespace(line, currentPos))
|
||||
return false;
|
||||
|
||||
if (!MatchString(line, currentPos, ONCE_PRAGMA_COMMAND, std::char_traits<char>::length(ONCE_PRAGMA_COMMAND)))
|
||||
return false;
|
||||
|
||||
const auto absolutePath = absolute(fs::path(line.m_filename.get()));
|
||||
@ -101,14 +117,14 @@ bool IncludingStreamProxy::MatchPragmaOnceDirective(const ParserLine& line, unsi
|
||||
|
||||
bool IncludingStreamProxy::MatchDirectives(const ParserLine& line)
|
||||
{
|
||||
unsigned directivePos;
|
||||
unsigned directiveStartPos, directiveEndPos;
|
||||
|
||||
if (!FindDirective(line, directivePos))
|
||||
if (!FindDirective(line, directiveStartPos, directiveEndPos))
|
||||
return false;
|
||||
|
||||
directivePos++;
|
||||
return MatchIncludeDirective(line, directivePos)
|
||||
|| MatchPragmaOnceDirective(line, directivePos);
|
||||
directiveStartPos++;
|
||||
return MatchIncludeDirective(line, directiveStartPos, directiveEndPos)
|
||||
|| MatchPragmaOnceDirective(line, directiveStartPos, directiveEndPos);
|
||||
}
|
||||
|
||||
ParserLine IncludingStreamProxy::NextLine()
|
||||
|
@ -8,15 +8,16 @@
|
||||
class IncludingStreamProxy final : public AbstractDirectiveStreamProxy
|
||||
{
|
||||
static constexpr const char* INCLUDE_QUOTES_ERROR = "Invalid include directive. Expected \"\" or <>";
|
||||
static constexpr const char* INCLUDE_DIRECTIVE = "include ";
|
||||
static constexpr const char* PRAGMA_ONCE_DIRECTIVE = "pragma once";
|
||||
static constexpr const char* INCLUDE_DIRECTIVE = "include";
|
||||
static constexpr const char* PRAGMA_DIRECTIVE = "pragma";
|
||||
static constexpr const char* ONCE_PRAGMA_COMMAND = "once";
|
||||
|
||||
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 ExtractIncludeFilename(const ParserLine& line, unsigned includeDirectivePosition, unsigned& directiveStartPos, unsigned& filenameEndPos);
|
||||
_NODISCARD bool MatchIncludeDirective(const ParserLine& line, unsigned directiveStartPos, unsigned directiveEndPos) const;
|
||||
_NODISCARD bool MatchPragmaOnceDirective(const ParserLine& line, unsigned directiveStartPos, unsigned directiveEndPos);
|
||||
_NODISCARD bool MatchDirectives(const ParserLine& line);
|
||||
|
||||
public:
|
||||
|
@ -7,37 +7,50 @@ PackDefinitionStreamProxy::PackDefinitionStreamProxy(IParserLineStream* stream)
|
||||
{
|
||||
}
|
||||
|
||||
bool PackDefinitionStreamProxy::MatchPackDirective(const ParserLine& line, unsigned directivePosition)
|
||||
bool PackDefinitionStreamProxy::MatchPackDirective(const ParserLine& line, const unsigned directiveStartPosition, const unsigned directiveEndPosition)
|
||||
{
|
||||
auto packValue = 0;
|
||||
auto currentPosition = directiveStartPosition;
|
||||
|
||||
if (!MatchString(line, directivePosition, PRAGMA_PACK_DIRECTIVE, std::char_traits<char>::length(PRAGMA_PACK_DIRECTIVE)))
|
||||
return false;
|
||||
|
||||
if (!MatchNextCharacter(line, directivePosition, '('))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Invalid pack directive.");
|
||||
|
||||
bool isPush;
|
||||
if (MatchNextString(line, directivePosition, PUSH_KEYWORD, std::char_traits<char>::length(PUSH_KEYWORD)))
|
||||
isPush = true;
|
||||
else if (MatchNextString(line, directivePosition, POP_KEYWORD, std::char_traits<char>::length(POP_KEYWORD)))
|
||||
isPush = false;
|
||||
else
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Unknown pack directive command.");
|
||||
|
||||
if(isPush)
|
||||
if (directiveEndPosition - directiveStartPosition != std::char_traits<char>::length(PRAGMA_DIRECTIVE)
|
||||
|| !MatchString(line, currentPosition, PRAGMA_DIRECTIVE, std::char_traits<char>::length(PRAGMA_DIRECTIVE)))
|
||||
{
|
||||
if (!MatchNextCharacter(line, directivePosition, ','))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Invalid pack directive.");
|
||||
|
||||
if (!ExtractInteger(line, directivePosition, packValue))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Invalid pack value.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!MatchNextCharacter(line, directivePosition, ')'))
|
||||
throw ParsingException(CreatePos(line, directivePosition), "Invalid pack directive.");
|
||||
if (!SkipWhitespace(line, currentPosition))
|
||||
return false;
|
||||
|
||||
if(isPush)
|
||||
if (!MatchString(line, currentPosition, PACK_PRAGMA_COMMAND, std::char_traits<char>::length(PACK_PRAGMA_COMMAND)))
|
||||
return false;
|
||||
|
||||
if (!SkipWhitespace(line, currentPosition))
|
||||
throw ParsingException(CreatePos(line, currentPosition), "Invalid pack directive.");
|
||||
|
||||
if (!MatchNextCharacter(line, currentPosition, '('))
|
||||
throw ParsingException(CreatePos(line, currentPosition), "Invalid pack directive.");
|
||||
|
||||
bool isPush;
|
||||
if (MatchNextString(line, currentPosition, PUSH_KEYWORD, std::char_traits<char>::length(PUSH_KEYWORD)))
|
||||
isPush = true;
|
||||
else if (MatchNextString(line, currentPosition, POP_KEYWORD, std::char_traits<char>::length(POP_KEYWORD)))
|
||||
isPush = false;
|
||||
else
|
||||
throw ParsingException(CreatePos(line, currentPosition), "Unknown pack directive command.");
|
||||
|
||||
if (isPush)
|
||||
{
|
||||
if (!MatchNextCharacter(line, currentPosition, ','))
|
||||
throw ParsingException(CreatePos(line, currentPosition), "Invalid pack directive.");
|
||||
|
||||
if (!ExtractInteger(line, currentPosition, packValue))
|
||||
throw ParsingException(CreatePos(line, currentPosition), "Invalid pack value.");
|
||||
}
|
||||
|
||||
if (!MatchNextCharacter(line, currentPosition, ')'))
|
||||
throw ParsingException(CreatePos(line, currentPosition), "Invalid pack directive.");
|
||||
|
||||
if (isPush)
|
||||
m_current_pack.push(packValue);
|
||||
else if (!m_current_pack.empty())
|
||||
m_current_pack.pop();
|
||||
@ -47,13 +60,13 @@ bool PackDefinitionStreamProxy::MatchPackDirective(const ParserLine& line, unsig
|
||||
|
||||
bool PackDefinitionStreamProxy::MatchDirectives(const ParserLine& line)
|
||||
{
|
||||
unsigned directivePos;
|
||||
unsigned directiveStartPos, directiveEndPos;
|
||||
|
||||
if (!FindDirective(line, directivePos))
|
||||
if (!FindDirective(line, directiveStartPos, directiveEndPos))
|
||||
return false;
|
||||
|
||||
directivePos++;
|
||||
return MatchPackDirective(line, directivePos);
|
||||
directiveStartPos++;
|
||||
return MatchPackDirective(line, directiveStartPos, directiveEndPos);
|
||||
}
|
||||
|
||||
ParserLine PackDefinitionStreamProxy::NextLine()
|
||||
|
@ -12,14 +12,15 @@ public:
|
||||
static constexpr int DEFAULT_PACK = 8;
|
||||
|
||||
private:
|
||||
static constexpr const char* PRAGMA_PACK_DIRECTIVE = "pragma pack";
|
||||
static constexpr const char* PRAGMA_DIRECTIVE = "pragma";
|
||||
static constexpr const char* PACK_PRAGMA_COMMAND = "pack";
|
||||
static constexpr const char* PUSH_KEYWORD = "push";
|
||||
static constexpr const char* POP_KEYWORD = "pop";
|
||||
|
||||
IParserLineStream* const m_stream;
|
||||
std::stack<int> m_current_pack;
|
||||
|
||||
_NODISCARD bool MatchPackDirective(const ParserLine& line, unsigned directivePosition);
|
||||
_NODISCARD bool MatchPackDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition);
|
||||
_NODISCARD bool MatchDirectives(const ParserLine& line);
|
||||
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user