From 729b72c1d920ea5fe365472ad02bff0ea85b14e2 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 30 Dec 2023 14:39:08 +0100 Subject: [PATCH] Consider triple number sign in macro value combination of ## and # --- .../Parsing/Impl/DefinesStreamProxy.cpp | 29 ++++++++++++------- src/Parser/Parsing/Impl/DefinesStreamProxy.h | 3 ++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp b/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp index 59dbe34a..dc49bb71 100644 --- a/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp +++ b/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp @@ -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& parameterNames) { if (parameterNames.empty()) @@ -64,11 +81,7 @@ void DefinesStreamProxy::Define::IdentifyParameters(const std::vector 0 && m_value[wordStart - 1] == '#') - // Make sure it's not a token pasting operator - && (wordStart <= 1 || m_value[wordStart - 2] != '#'); + const auto stringize = IsStringizeParameter(m_value, wordStart); const auto stringizeOffset = stringize ? 1 : 0; m_value.erase(wordStart - stringizeOffset, i - wordStart + stringizeOffset); @@ -102,11 +115,7 @@ void DefinesStreamProxy::Define::IdentifyParameters(const std::vector 0 && m_value[wordStart - 1] == '#') - // Make sure it's not a token pasting operator - && (wordStart <= 1 || m_value[wordStart - 2] != '#'); + const auto stringize = IsStringizeParameter(m_value, wordStart); const auto stringizeOffset = stringize ? 1 : 0; m_value.erase(wordStart - stringizeOffset, m_value.size() - wordStart + stringizeOffset); diff --git a/src/Parser/Parsing/Impl/DefinesStreamProxy.h b/src/Parser/Parsing/Impl/DefinesStreamProxy.h index 3523260e..cdf0bcaa 100644 --- a/src/Parser/Parsing/Impl/DefinesStreamProxy.h +++ b/src/Parser/Parsing/Impl/DefinesStreamProxy.h @@ -46,6 +46,9 @@ public: Define(); Define(std::string name, std::string value); void IdentifyParameters(const std::vector& parameterNames); + + private: + static bool IsStringizeParameter(const std::string& value, unsigned pos); }; enum class ParameterState : uint8_t