diff --git a/Source/cmList.cxx b/Source/cmList.cxx index cf65bb2bb2..bef1244a3b 100644 --- a/Source/cmList.cxx +++ b/Source/cmList.cxx @@ -114,9 +114,9 @@ protected: StringFilter GetCaseFilter(CaseSensitivity sensitivity) { - return (sensitivity == CaseSensitivity::INSENSITIVE) - ? cmSystemTools::LowerCase - : nullptr; + constexpr std::string (*filter)(std::string const&) = + cmSystemTools::LowerCase; + return (sensitivity == CaseSensitivity::INSENSITIVE) ? filter : nullptr; } using ComparisonFunction = diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx index 724ca75330..99218bcc38 100644 --- a/Source/cmStringAlgorithms.cxx +++ b/Source/cmStringAlgorithms.cxx @@ -8,6 +8,16 @@ #include #include +bool cmStrCaseEq(cm::string_view s1, cm::string_view s2) +{ + if (s1.size() != s2.size()) { + return false; + } + + return std::equal(s1.begin(), s1.end(), s2.begin(), + [](char a, char b) { return tolower(a) == tolower(b); }); +} + std::string cmTrimWhitespace(cm::string_view str) { // XXX(clang-tidy): This declaration and the next cannot be `const auto*` diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h index 72557d52f0..e70fd785db 100644 --- a/Source/cmStringAlgorithms.h +++ b/Source/cmStringAlgorithms.h @@ -43,6 +43,13 @@ private: std::string const Test_; }; +/** + * Test if two strings are identical, ignoring case. + * + * Note that this is not guaranteed to work correctly on non-ASCII strings. + */ +bool cmStrCaseEq(cm::string_view a, cm::string_view b); + /** Returns true if the character @a ch is a whitespace character. **/ inline bool cmIsSpace(char ch) { diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 24ab7ae949..6c79601521 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -387,6 +387,28 @@ void cmSystemTools::ExpandRegistryValues(std::string& source, } #endif +// Return a lower case string +std::string cmSystemTools::LowerCase(cm::string_view s) +{ + std::string n; + n.resize(s.size()); + for (size_t i = 0; i < s.size(); i++) { + n[i] = static_cast(tolower(s[i])); + } + return n; +} + +// Return an upper case string +std::string cmSystemTools::UpperCase(cm::string_view s) +{ + std::string n; + n.resize(s.size()); + for (size_t i = 0; i < s.size(); i++) { + n[i] = static_cast(toupper(s[i])); + } + return n; +} + std::string cmSystemTools::HelpFileName(cm::string_view str) { std::string name(str); diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 4f62aee639..7907a9454d 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -40,6 +40,26 @@ public: using Superclass = cmsys::SystemTools; using Encoding = cmProcessOutput::Encoding; + /** + * Return a lower case string + */ + static std::string LowerCase(cm::string_view); + static std::string LowerCase(char const* s) + { + return LowerCase(cm::string_view{ s }); + } + using cmsys::SystemTools::LowerCase; + + /** + * Return an upper case string + */ + static std::string UpperCase(cm::string_view); + static std::string UpperCase(char const* s) + { + return UpperCase(cm::string_view{ s }); + } + using cmsys::SystemTools::UpperCase; + /** * Look for and replace registry values in a string */