Consider triple number sign in macro value combination of ## and #

This commit is contained in:
Jan 2023-12-30 14:39:08 +01:00
parent 799fa37c44
commit 729b72c1d9
No known key found for this signature in database
GPG Key ID: 44B581F78FF5C57C
2 changed files with 22 additions and 10 deletions

View File

@ -39,6 +39,23 @@ DefinesStreamProxy::MacroParameterState::MacroParameterState()
{ {
} }
bool DefinesStreamProxy::Define::IsStringizeParameter(const std::string& value, unsigned pos)
{
// Check if # is prepended to the word
if (pos <= 0 || value[pos - 1] != '#')
return false;
bool min2IsNumberSign = pos >= 2 && value[pos - 2] == '#';
bool min3IsNumberSign = pos >= 3 && value[pos - 3] == '#';
bool min4IsNumberSign = pos >= 4 && value[pos - 4] == '#';
return
// #
!min2IsNumberSign
// ###
|| (min3IsNumberSign && !min4IsNumberSign);
}
void DefinesStreamProxy::Define::IdentifyParameters(const std::vector<std::string>& parameterNames) void DefinesStreamProxy::Define::IdentifyParameters(const std::vector<std::string>& parameterNames)
{ {
if (parameterNames.empty()) if (parameterNames.empty())
@ -64,11 +81,7 @@ void DefinesStreamProxy::Define::IdentifyParameters(const std::vector<std::strin
if (parameterIndex < parameterNames.size()) if (parameterIndex < parameterNames.size())
{ {
const auto stringize = const auto stringize = IsStringizeParameter(m_value, wordStart);
// Check if # is prepended to the word
(wordStart > 0 && m_value[wordStart - 1] == '#')
// Make sure it's not a token pasting operator
&& (wordStart <= 1 || m_value[wordStart - 2] != '#');
const auto stringizeOffset = stringize ? 1 : 0; const auto stringizeOffset = stringize ? 1 : 0;
m_value.erase(wordStart - stringizeOffset, i - wordStart + stringizeOffset); m_value.erase(wordStart - stringizeOffset, i - wordStart + stringizeOffset);
@ -102,11 +115,7 @@ void DefinesStreamProxy::Define::IdentifyParameters(const std::vector<std::strin
if (parameterIndex < parameterNames.size()) if (parameterIndex < parameterNames.size())
{ {
const auto stringize = const auto stringize = IsStringizeParameter(m_value, wordStart);
// Check if # is prepended to the word
(wordStart > 0 && m_value[wordStart - 1] == '#')
// Make sure it's not a token pasting operator
&& (wordStart <= 1 || m_value[wordStart - 2] != '#');
const auto stringizeOffset = stringize ? 1 : 0; const auto stringizeOffset = stringize ? 1 : 0;
m_value.erase(wordStart - stringizeOffset, m_value.size() - wordStart + stringizeOffset); m_value.erase(wordStart - stringizeOffset, m_value.size() - wordStart + stringizeOffset);

View File

@ -46,6 +46,9 @@ public:
Define(); Define();
Define(std::string name, std::string value); Define(std::string name, std::string value);
void IdentifyParameters(const std::vector<std::string>& parameterNames); void IdentifyParameters(const std::vector<std::string>& parameterNames);
private:
static bool IsStringizeParameter(const std::string& value, unsigned pos);
}; };
enum class ParameterState : uint8_t enum class ParameterState : uint8_t