Fixed #1181 (Preprocessor fails while expanding macros)
This commit is contained in:
parent
0159287437
commit
ee1675270b
|
@ -1742,8 +1742,24 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
|
||||||
// expand macros..
|
// expand macros..
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Limit for each macro.
|
||||||
|
// The limit specify a position in the "line" variable.
|
||||||
|
// For a "recursive macro" where the expanded text contains
|
||||||
|
// the macro again, the macro should not be expanded again.
|
||||||
|
// The limits are used to prevent recursive expanding.
|
||||||
|
// * When a macro is expanded its limit position is set to
|
||||||
|
// the last expanded character.
|
||||||
|
// * macros are only allowed to be expanded when the
|
||||||
|
// the position is beyond the limit.
|
||||||
|
// * The limit is relative to the end of the "line"
|
||||||
|
// variable. Inserting and deleting text before the limit
|
||||||
|
// without updating the limit is safe.
|
||||||
|
// * when pos goes beyond a limit the limit needs to be
|
||||||
|
// deleted because it is unsafe to insert/delete text
|
||||||
|
// after the limit
|
||||||
std::map<const PreprocessorMacro *, unsigned int> limits;
|
std::map<const PreprocessorMacro *, unsigned int> limits;
|
||||||
|
|
||||||
|
// pos is the current position in line
|
||||||
std::string::size_type pos = 0;
|
std::string::size_type pos = 0;
|
||||||
while (pos < line.size())
|
while (pos < line.size())
|
||||||
{
|
{
|
||||||
|
@ -1796,6 +1812,8 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
|
||||||
|
|
||||||
const PreprocessorMacro * const macro = it->second;
|
const PreprocessorMacro * const macro = it->second;
|
||||||
|
|
||||||
|
// check if pos is within allowed limits for this
|
||||||
|
// macro
|
||||||
{
|
{
|
||||||
const std::map<const PreprocessorMacro *, unsigned int>::const_iterator it2 = limits.find(macro);
|
const std::map<const PreprocessorMacro *, unsigned int>::const_iterator it2 = limits.find(macro);
|
||||||
if (it2 != limits.end() && pos <= line.length() - it2->second)
|
if (it2 != limits.end() && pos <= line.length() - it2->second)
|
||||||
|
@ -1907,33 +1925,31 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
|
||||||
if (macro->variadic() || macro->nopar() || !macro->params().empty())
|
if (macro->variadic() || macro->nopar() || !macro->params().empty())
|
||||||
++pos2;
|
++pos2;
|
||||||
|
|
||||||
// When A is expanded in the following code, the old limit for the
|
// Remove old limits
|
||||||
// B needs to deleted, or it will not allow us to expand B,
|
|
||||||
// which is inside the A.
|
|
||||||
// #define B(x) (
|
|
||||||
// #define A() B(xx)
|
|
||||||
// B(1) A() ) )
|
|
||||||
unsigned int macroEnd = line.length() - pos2;
|
|
||||||
for (std::map<const PreprocessorMacro *, unsigned int>::iterator iter = limits.begin();
|
for (std::map<const PreprocessorMacro *, unsigned int>::iterator iter = limits.begin();
|
||||||
iter != limits.end();)
|
iter != limits.end();)
|
||||||
{
|
{
|
||||||
if (pos1 < iter->second)
|
if ((line.length() - pos1) < iter->second)
|
||||||
{
|
{
|
||||||
// We have gone past this limit, so just delete it
|
// We have gone past this limit, so just delete it
|
||||||
limits.erase(iter++);
|
limits.erase(iter++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We need to adjust this limit, because the
|
|
||||||
// length of line will be changed
|
|
||||||
iter->second += macrocode.length() - (pos2 - pos1);
|
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
limits[macro] = macroEnd;
|
// don't allow this macro to be expanded again before pos2
|
||||||
|
limits[macro] = line.length() - pos2;
|
||||||
|
|
||||||
|
// erase macro
|
||||||
line.erase(pos1, pos2 - pos1);
|
line.erase(pos1, pos2 - pos1);
|
||||||
|
|
||||||
|
// insert expanded macro code
|
||||||
line.insert(pos1, macrocode);
|
line.insert(pos1, macrocode);
|
||||||
|
|
||||||
|
// position = start position.
|
||||||
pos = pos1;
|
pos = pos1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue