mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
Make DefinesProxy go over a line with defines substitution multiple times until no further substitution has been done
This commit is contained in:
parent
bba55706bf
commit
9816d01ac2
@ -26,7 +26,7 @@ DefinesStreamProxy::Define::Define(std::string name, std::string value)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DefinesStreamProxy::Define::Render(std::vector<std::string>& parameterValues)
|
std::string DefinesStreamProxy::Define::Render(const std::vector<std::string>& parameterValues)
|
||||||
{
|
{
|
||||||
if (parameterValues.empty() || m_parameter_positions.empty())
|
if (parameterValues.empty() || m_parameter_positions.empty())
|
||||||
return m_value;
|
return m_value;
|
||||||
@ -52,7 +52,7 @@ std::string DefinesStreamProxy::Define::Render(std::vector<std::string>& paramet
|
|||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinesStreamProxy::Define::IdentifyParameters(std::vector<std::string>& parameterNames)
|
void DefinesStreamProxy::Define::IdentifyParameters(const std::vector<std::string>& parameterNames)
|
||||||
{
|
{
|
||||||
if (parameterNames.empty())
|
if (parameterNames.empty())
|
||||||
return;
|
return;
|
||||||
@ -168,7 +168,7 @@ bool DefinesStreamProxy::MatchDefineDirective(const ParserLine& line, unsigned d
|
|||||||
|
|
||||||
const auto name = line.m_line.substr(nameStartPos, directivePosition - nameStartPos);
|
const auto name = line.m_line.substr(nameStartPos, directivePosition - nameStartPos);
|
||||||
|
|
||||||
auto parameters = MatchDefineParameters(line, directivePosition);
|
const auto parameters = MatchDefineParameters(line, directivePosition);
|
||||||
|
|
||||||
std::string value;
|
std::string value;
|
||||||
if (directivePosition < line.m_line.size())
|
if (directivePosition < line.m_line.size())
|
||||||
@ -346,77 +346,88 @@ void DefinesStreamProxy::ExtractParametersFromDefineUsage(const ParserLine& line
|
|||||||
|
|
||||||
void DefinesStreamProxy::ExpandDefines(ParserLine& line)
|
void DefinesStreamProxy::ExpandDefines(ParserLine& line)
|
||||||
{
|
{
|
||||||
auto wordStart = 0u;
|
bool usesDefines;
|
||||||
auto lastWordEnd = 0u;
|
auto defineIterations = 0u;
|
||||||
auto inWord = false;
|
|
||||||
Define* value;
|
|
||||||
|
|
||||||
std::ostringstream str;
|
do
|
||||||
auto usesDefines = false;
|
|
||||||
|
|
||||||
for (auto i = 0u; i < line.m_line.size(); i++)
|
|
||||||
{
|
{
|
||||||
const auto c = line.m_line[i];
|
if (defineIterations > MAX_DEFINE_ITERATIONS)
|
||||||
if (!inWord)
|
throw ParsingException(CreatePos(line, 1), "Potential define loop? Exceeded max define iterations of " + std::to_string(MAX_DEFINE_ITERATIONS) + " iterations.");
|
||||||
|
|
||||||
|
usesDefines = false;
|
||||||
|
|
||||||
|
auto wordStart = 0u;
|
||||||
|
auto lastWordEnd = 0u;
|
||||||
|
auto inWord = false;
|
||||||
|
Define* value;
|
||||||
|
std::ostringstream str;
|
||||||
|
|
||||||
|
for (auto i = 0u; i < line.m_line.size(); i++)
|
||||||
{
|
{
|
||||||
if (isalpha(c) || c == '_')
|
const auto c = line.m_line[i];
|
||||||
|
if (!inWord)
|
||||||
{
|
{
|
||||||
wordStart = i;
|
if (isalpha(c) || c == '_')
|
||||||
inWord = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!isalnum(c) && c != '_')
|
|
||||||
{
|
|
||||||
if (FindDefineForWord(line, wordStart, i, value))
|
|
||||||
{
|
{
|
||||||
std::vector<std::string> parameterValues;
|
wordStart = i;
|
||||||
ExtractParametersFromDefineUsage(line, i, i, parameterValues);
|
inWord = true;
|
||||||
const auto defineValue = value->Render(parameterValues);
|
|
||||||
|
|
||||||
if (!usesDefines)
|
|
||||||
{
|
|
||||||
str << std::string(line.m_line, 0, wordStart) << defineValue;
|
|
||||||
usesDefines = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
str << std::string(line.m_line, lastWordEnd, wordStart - lastWordEnd) << defineValue;
|
|
||||||
}
|
|
||||||
lastWordEnd = i;
|
|
||||||
}
|
}
|
||||||
inWord = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inWord)
|
|
||||||
{
|
|
||||||
if (FindDefineForWord(line, wordStart, line.m_line.size(), value))
|
|
||||||
{
|
|
||||||
std::vector<std::string> parameterValues;
|
|
||||||
const auto defineValue = value->Render(parameterValues);
|
|
||||||
|
|
||||||
if (!usesDefines)
|
|
||||||
{
|
|
||||||
str << std::string(line.m_line, 0, wordStart) << defineValue;
|
|
||||||
usesDefines = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
str << std::string(line.m_line, lastWordEnd, wordStart - lastWordEnd) << defineValue;
|
if (!isalnum(c) && c != '_')
|
||||||
}
|
{
|
||||||
lastWordEnd = line.m_line.size();
|
if (FindDefineForWord(line, wordStart, i, value))
|
||||||
}
|
{
|
||||||
}
|
std::vector<std::string> parameterValues;
|
||||||
|
ExtractParametersFromDefineUsage(line, i, i, parameterValues);
|
||||||
|
const auto defineValue = value->Render(parameterValues);
|
||||||
|
|
||||||
if (usesDefines)
|
if (!usesDefines)
|
||||||
{
|
{
|
||||||
if (lastWordEnd < line.m_line.size())
|
str << std::string(line.m_line, 0, wordStart) << defineValue;
|
||||||
str << std::string(line.m_line, lastWordEnd, line.m_line.size() - lastWordEnd);
|
usesDefines = true;
|
||||||
line.m_line = str.str();
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
str << std::string(line.m_line, lastWordEnd, wordStart - lastWordEnd) << defineValue;
|
||||||
|
}
|
||||||
|
lastWordEnd = i;
|
||||||
|
}
|
||||||
|
inWord = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inWord)
|
||||||
|
{
|
||||||
|
if (FindDefineForWord(line, wordStart, line.m_line.size(), value))
|
||||||
|
{
|
||||||
|
const std::vector<std::string> parameterValues;
|
||||||
|
const auto defineValue = value->Render(parameterValues);
|
||||||
|
|
||||||
|
if (!usesDefines)
|
||||||
|
{
|
||||||
|
str << std::string(line.m_line, 0, wordStart) << defineValue;
|
||||||
|
usesDefines = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str << std::string(line.m_line, lastWordEnd, wordStart - lastWordEnd) << defineValue;
|
||||||
|
}
|
||||||
|
lastWordEnd = line.m_line.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usesDefines)
|
||||||
|
{
|
||||||
|
if (lastWordEnd < line.m_line.size())
|
||||||
|
str << std::string(line.m_line, lastWordEnd, line.m_line.size() - lastWordEnd);
|
||||||
|
line.m_line = str.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
defineIterations++;
|
||||||
|
} while (usesDefines);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinesStreamProxy::AddDefine(Define define)
|
void DefinesStreamProxy::AddDefine(Define define)
|
||||||
|
@ -15,6 +15,8 @@ class DefinesStreamProxy final : public AbstractDirectiveStreamProxy
|
|||||||
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";
|
||||||
|
|
||||||
|
static constexpr auto MAX_DEFINE_ITERATIONS = 128u;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class DefineParameterPosition
|
class DefineParameterPosition
|
||||||
{
|
{
|
||||||
@ -35,8 +37,8 @@ public:
|
|||||||
|
|
||||||
Define();
|
Define();
|
||||||
Define(std::string name, std::string value);
|
Define(std::string name, std::string value);
|
||||||
void IdentifyParameters(std::vector<std::string>& parameterNames);
|
void IdentifyParameters(const std::vector<std::string>& parameterNames);
|
||||||
std::string Render(std::vector<std::string>& parameterValues);
|
std::string Render(const std::vector<std::string>& parameterValues);
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -44,16 +46,16 @@ private:
|
|||||||
std::unordered_map<std::string, Define> m_defines;
|
std::unordered_map<std::string, Define> m_defines;
|
||||||
std::stack<bool> m_modes;
|
std::stack<bool> m_modes;
|
||||||
unsigned m_ignore_depth;
|
unsigned m_ignore_depth;
|
||||||
|
|
||||||
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 directivePosition);
|
||||||
_NODISCARD bool MatchUndefDirective(const ParserLine& line, unsigned directivePosition);
|
_NODISCARD bool MatchUndefDirective(const ParserLine& line, unsigned directivePosition);
|
||||||
_NODISCARD bool MatchIfdefDirective(const ParserLine& line, unsigned directivePosition);
|
_NODISCARD bool MatchIfdefDirective(const ParserLine& line, unsigned directivePosition);
|
||||||
_NODISCARD bool MatchElseDirective(const ParserLine& line, unsigned directivePosition);
|
_NODISCARD bool MatchElseDirective(const ParserLine& line, unsigned directivePosition);
|
||||||
_NODISCARD bool MatchEndifDirective(const ParserLine& line, unsigned directivePosition);
|
_NODISCARD bool MatchEndifDirective(const ParserLine& line, unsigned directivePosition);
|
||||||
_NODISCARD bool MatchDirectives(const ParserLine& line);
|
_NODISCARD bool MatchDirectives(const ParserLine& line);
|
||||||
|
|
||||||
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);
|
||||||
bool FindDefineForWord(const ParserLine& line, unsigned wordStart, unsigned wordEnd, Define*& value);
|
bool FindDefineForWord(const ParserLine& line, unsigned wordStart, unsigned wordEnd, Define*& value);
|
||||||
void ExpandDefines(ParserLine& line);
|
void ExpandDefines(ParserLine& line);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user