Properly handle tabs in pragma directives and other precompiler statements

This commit is contained in:
Jan 2021-11-01 14:36:53 +01:00
parent be4e489118
commit e19f526d8b
8 changed files with 178 additions and 104 deletions

View File

@ -94,17 +94,29 @@ bool AbstractDirectiveStreamProxy::MatchNextString(const ParserLine& line, unsig
return SkipWhitespace(line, position) && MatchString(line, position, str, len); 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; directiveStartPosition = 0;
for (; directivePosition < line.m_line.size(); directivePosition++) for (; directiveStartPosition < line.m_line.size(); directiveStartPosition++)
{ {
const auto c = line.m_line[directivePosition]; const auto c = line.m_line[directiveStartPosition];
if (isspace(c)) if (isspace(c))
continue; 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; return false;

View File

@ -18,5 +18,5 @@ protected:
static bool MatchString(const ParserLine& line, unsigned& position, const char* str, unsigned len); 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 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);
}; };

View File

@ -157,22 +157,30 @@ std::vector<std::string> DefinesStreamProxy::MatchDefineParameters(const ParserL
return parameters; 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; return false;
}
const auto nameStartPos = directivePosition; if (!SkipWhitespace(line, currentPos))
if (!ExtractIdentifier(line, directivePosition)) throw ParsingException(CreatePos(line, currentPos), "Cannot define without a name.");
throw ParsingException(CreatePos(line, directivePosition), "Cannot ifdef 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; std::string value;
if (directivePosition < line.m_line.size()) if (currentPos < line.m_line.size())
value = line.m_line.substr(directivePosition + 1); value = line.m_line.substr(currentPos + 1);
Define define(name, value); Define define(name, value);
define.IdentifyParameters(parameters); define.IdentifyParameters(parameters);
@ -181,19 +189,24 @@ bool DefinesStreamProxy::MatchDefineDirective(const ParserLine& line, unsigned d
return true; 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; return false;
}
if (!SkipWhitespace(line, directivePosition)) if (!SkipWhitespace(line, currentPos))
throw ParsingException(CreatePos(line, directivePosition), "Cannot undef without a name."); throw ParsingException(CreatePos(line, currentPos), "Cannot undef without a name.");
const auto nameStartPos = directivePosition; const auto nameStartPos = currentPos;
if (!ExtractIdentifier(line, directivePosition)) if (!ExtractIdentifier(line, currentPos))
throw ParsingException(CreatePos(line, directivePosition), "Cannot ifdef without a name."); 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); const auto entry = m_defines.find(name);
if (entry != m_defines.end()) if (entry != m_defines.end())
@ -202,13 +215,19 @@ bool DefinesStreamProxy::MatchUndefDirective(const ParserLine& line, unsigned di
return true; 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; 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; return false;
}
reverse = true; reverse = true;
} }
@ -219,14 +238,14 @@ bool DefinesStreamProxy::MatchIfdefDirective(const ParserLine& line, unsigned di
return true; return true;
} }
if (!SkipWhitespace(line, directivePosition)) if (!SkipWhitespace(line, currentPos))
throw ParsingException(CreatePos(line, directivePosition), "Cannot ifdef without a name."); throw ParsingException(CreatePos(line, currentPos), "Cannot ifdef without a name.");
const auto nameStartPos = directivePosition; const auto nameStartPos = currentPos;
if (!ExtractIdentifier(line, directivePosition)) if (!ExtractIdentifier(line, currentPos))
throw ParsingException(CreatePos(line, directivePosition), "Cannot ifdef without a name."); 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); const auto entry = m_defines.find(name);
if (entry != m_defines.end()) if (entry != m_defines.end())
@ -237,10 +256,15 @@ bool DefinesStreamProxy::MatchIfdefDirective(const ParserLine& line, unsigned di
return true; 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; return false;
}
if (m_ignore_depth > 0) if (m_ignore_depth > 0)
return true; return true;
@ -248,15 +272,20 @@ bool DefinesStreamProxy::MatchElseDirective(const ParserLine& line, unsigned dir
if (!m_modes.empty()) if (!m_modes.empty())
m_modes.top() = !m_modes.top(); m_modes.top() = !m_modes.top();
else else
throw ParsingException(CreatePos(line, directivePosition), "Cannot use else without ifdef"); throw ParsingException(CreatePos(line, currentPos), "Cannot use else without ifdef");
return true; 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; return false;
}
if (m_ignore_depth > 0) if (m_ignore_depth > 0)
{ {
@ -267,30 +296,31 @@ bool DefinesStreamProxy::MatchEndifDirective(const ParserLine& line, unsigned di
if (!m_modes.empty()) if (!m_modes.empty())
m_modes.pop(); m_modes.pop();
else else
throw ParsingException(CreatePos(line, directivePosition), "Cannot use endif without ifdef"); throw ParsingException(CreatePos(line, currentPos), "Cannot use endif without ifdef");
return true; return true;
} }
bool DefinesStreamProxy::MatchDirectives(const ParserLine& line) bool DefinesStreamProxy::MatchDirectives(const ParserLine& line)
{ {
unsigned directivePos; unsigned directiveStartPos;
unsigned directiveEndPos;
if (!FindDirective(line, directivePos)) if (!FindDirective(line, directiveStartPos, directiveEndPos))
return false; return false;
directivePos++; directiveStartPos++;
if (m_modes.empty() || m_modes.top() == true) if (m_modes.empty() || m_modes.top() == true)
{ {
if (MatchDefineDirective(line, directivePos) if (MatchDefineDirective(line, directiveStartPos, directiveEndPos)
|| MatchUndefDirective(line, directivePos)) || MatchUndefDirective(line, directiveStartPos, directiveEndPos))
return true; return true;
} }
return MatchIfdefDirective(line, directivePos) return MatchIfdefDirective(line, directiveStartPos, directiveEndPos)
|| MatchElseDirective(line, directivePos) || MatchElseDirective(line, directiveStartPos, directiveEndPos)
|| MatchEndifDirective(line, directivePos); || MatchEndifDirective(line, directiveStartPos, directiveEndPos);
} }
bool DefinesStreamProxy::FindDefineForWord(const ParserLine& line, const unsigned wordStart, const unsigned wordEnd, Define*& value) bool DefinesStreamProxy::FindDefineForWord(const ParserLine& line, const unsigned wordStart, const unsigned wordEnd, Define*& value)
@ -427,7 +457,8 @@ void DefinesStreamProxy::ExpandDefines(ParserLine& line)
} }
defineIterations++; defineIterations++;
} while (usesDefines); }
while (usesDefines);
} }
void DefinesStreamProxy::AddDefine(Define define) void DefinesStreamProxy::AddDefine(Define define)

View File

@ -8,10 +8,10 @@
class DefinesStreamProxy final : public AbstractDirectiveStreamProxy class DefinesStreamProxy final : public AbstractDirectiveStreamProxy
{ {
static constexpr const char* DEFINE_DIRECTIVE = "define "; static constexpr const char* DEFINE_DIRECTIVE = "define";
static constexpr const char* UNDEF_DIRECTIVE = "undef "; static constexpr const char* UNDEF_DIRECTIVE = "undef";
static constexpr const char* IFDEF_DIRECTIVE = "ifdef "; static constexpr const char* IFDEF_DIRECTIVE = "ifdef";
static constexpr const char* IFNDEF_DIRECTIVE = "ifndef "; static constexpr const char* IFNDEF_DIRECTIVE = "ifndef";
static constexpr const char* ELSE_DIRECTIVE = "else"; static constexpr const char* ELSE_DIRECTIVE = "else";
static constexpr const char* ENDIF_DIRECTIVE = "endif"; static constexpr const char* ENDIF_DIRECTIVE = "endif";
@ -48,11 +48,11 @@ private:
unsigned m_ignore_depth; unsigned m_ignore_depth;
static std::vector<std::string> MatchDefineParameters(const ParserLine& line, unsigned& parameterPosition); static std::vector<std::string> MatchDefineParameters(const ParserLine& line, unsigned& parameterPosition);
_NODISCARD bool MatchDefineDirective(const ParserLine& line, unsigned directivePosition); _NODISCARD bool MatchDefineDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition);
_NODISCARD bool MatchUndefDirective(const ParserLine& line, unsigned directivePosition); _NODISCARD bool MatchUndefDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition);
_NODISCARD bool MatchIfdefDirective(const ParserLine& line, unsigned directivePosition); _NODISCARD bool MatchIfdefDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition);
_NODISCARD bool MatchElseDirective(const ParserLine& line, unsigned directivePosition); _NODISCARD bool MatchElseDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition);
_NODISCARD bool MatchEndifDirective(const ParserLine& line, unsigned directivePosition); _NODISCARD bool MatchEndifDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition);
_NODISCARD bool MatchDirectives(const ParserLine& line); _NODISCARD bool MatchDirectives(const ParserLine& line);
static void ExtractParametersFromDefineUsage(const ParserLine& line, unsigned parameterStart, unsigned& parameterEnd, std::vector<std::string>& parameterValues); static void ExtractParametersFromDefineUsage(const ParserLine& line, unsigned parameterStart, unsigned& parameterEnd, std::vector<std::string>& parameterValues);

View File

@ -57,18 +57,23 @@ bool IncludingStreamProxy::ExtractIncludeFilename(const ParserLine& line, const
return false; 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; return false;
}
unsigned filenameStart, filenameEnd; unsigned filenameStart, filenameEnd;
if (!ExtractIncludeFilename(line, directivePosition, filenameStart, filenameEnd)) if (!ExtractIncludeFilename(line, currentPos, filenameStart, filenameEnd))
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, static_cast<int>(directivePosition)), INCLUDE_QUOTES_ERROR); throw ParsingException(TokenPos(line.m_filename, line.m_line_number, static_cast<int>(currentPos)), INCLUDE_QUOTES_ERROR);
if (filenameEnd <= filenameStart) 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); const auto filename = line.m_line.substr(filenameStart, filenameEnd - filenameStart);
@ -76,15 +81,26 @@ bool IncludingStreamProxy::MatchIncludeDirective(const ParserLine& line, unsigne
{ {
std::ostringstream errorStr; std::ostringstream errorStr;
errorStr << "Could not include file \"" << filename << "\""; errorStr << "Could not include file \"" << filename << "\"";
throw ParsingException(CreatePos(line, directivePosition), errorStr.str()); throw ParsingException(CreatePos(line, currentPos), errorStr.str());
} }
return true; 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; return false;
const auto absolutePath = absolute(fs::path(line.m_filename.get())); 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) bool IncludingStreamProxy::MatchDirectives(const ParserLine& line)
{ {
unsigned directivePos; unsigned directiveStartPos, directiveEndPos;
if (!FindDirective(line, directivePos)) if (!FindDirective(line, directiveStartPos, directiveEndPos))
return false; return false;
directivePos++; directiveStartPos++;
return MatchIncludeDirective(line, directivePos) return MatchIncludeDirective(line, directiveStartPos, directiveEndPos)
|| MatchPragmaOnceDirective(line, directivePos); || MatchPragmaOnceDirective(line, directiveStartPos, directiveEndPos);
} }
ParserLine IncludingStreamProxy::NextLine() ParserLine IncludingStreamProxy::NextLine()

View File

@ -8,15 +8,16 @@
class IncludingStreamProxy final : public AbstractDirectiveStreamProxy class IncludingStreamProxy final : public AbstractDirectiveStreamProxy
{ {
static constexpr const char* INCLUDE_QUOTES_ERROR = "Invalid include directive. Expected \"\" or <>"; static constexpr const char* INCLUDE_QUOTES_ERROR = "Invalid include directive. Expected \"\" or <>";
static constexpr const char* INCLUDE_DIRECTIVE = "include "; static constexpr const char* INCLUDE_DIRECTIVE = "include";
static constexpr const char* PRAGMA_ONCE_DIRECTIVE = "pragma once"; static constexpr const char* PRAGMA_DIRECTIVE = "pragma";
static constexpr const char* ONCE_PRAGMA_COMMAND = "once";
IParserLineStream* const m_stream; IParserLineStream* const m_stream;
std::set<std::string> m_included_files; std::set<std::string> m_included_files;
_NODISCARD static bool ExtractIncludeFilename(const ParserLine& line, unsigned includeDirectivePosition, unsigned& filenameStartPosition, unsigned& filenameEndPosition); _NODISCARD static bool ExtractIncludeFilename(const ParserLine& line, unsigned includeDirectivePosition, unsigned& directiveStartPos, unsigned& filenameEndPos);
_NODISCARD bool MatchIncludeDirective(const ParserLine& line, unsigned directivePosition) const; _NODISCARD bool MatchIncludeDirective(const ParserLine& line, unsigned directiveStartPos, unsigned directiveEndPos) const;
_NODISCARD bool MatchPragmaOnceDirective(const ParserLine& line, unsigned directivePosition); _NODISCARD bool MatchPragmaOnceDirective(const ParserLine& line, unsigned directiveStartPos, unsigned directiveEndPos);
_NODISCARD bool MatchDirectives(const ParserLine& line); _NODISCARD bool MatchDirectives(const ParserLine& line);
public: public:

View File

@ -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 packValue = 0;
auto currentPosition = directiveStartPosition;
if (!MatchString(line, directivePosition, PRAGMA_PACK_DIRECTIVE, std::char_traits<char>::length(PRAGMA_PACK_DIRECTIVE))) if (directiveEndPosition - directiveStartPosition != std::char_traits<char>::length(PRAGMA_DIRECTIVE)
return false; || !MatchString(line, currentPosition, PRAGMA_DIRECTIVE, std::char_traits<char>::length(PRAGMA_DIRECTIVE)))
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 (!MatchNextCharacter(line, directivePosition, ',')) return false;
throw ParsingException(CreatePos(line, directivePosition), "Invalid pack directive.");
if (!ExtractInteger(line, directivePosition, packValue))
throw ParsingException(CreatePos(line, directivePosition), "Invalid pack value.");
} }
if (!MatchNextCharacter(line, directivePosition, ')')) if (!SkipWhitespace(line, currentPosition))
throw ParsingException(CreatePos(line, directivePosition), "Invalid pack directive."); 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); m_current_pack.push(packValue);
else if (!m_current_pack.empty()) else if (!m_current_pack.empty())
m_current_pack.pop(); m_current_pack.pop();
@ -47,13 +60,13 @@ bool PackDefinitionStreamProxy::MatchPackDirective(const ParserLine& line, unsig
bool PackDefinitionStreamProxy::MatchDirectives(const ParserLine& line) bool PackDefinitionStreamProxy::MatchDirectives(const ParserLine& line)
{ {
unsigned directivePos; unsigned directiveStartPos, directiveEndPos;
if (!FindDirective(line, directivePos)) if (!FindDirective(line, directiveStartPos, directiveEndPos))
return false; return false;
directivePos++; directiveStartPos++;
return MatchPackDirective(line, directivePos); return MatchPackDirective(line, directiveStartPos, directiveEndPos);
} }
ParserLine PackDefinitionStreamProxy::NextLine() ParserLine PackDefinitionStreamProxy::NextLine()

View File

@ -12,14 +12,15 @@ public:
static constexpr int DEFAULT_PACK = 8; static constexpr int DEFAULT_PACK = 8;
private: 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* PUSH_KEYWORD = "push";
static constexpr const char* POP_KEYWORD = "pop"; static constexpr const char* POP_KEYWORD = "pop";
IParserLineStream* const m_stream; IParserLineStream* const m_stream;
std::stack<int> m_current_pack; 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); _NODISCARD bool MatchDirectives(const ParserLine& line);
public: public: