diff options
author | Max Kellermann <max@musicpd.org> | 2017-09-20 23:43:06 +0200 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2017-09-20 23:43:27 +0200 |
commit | 1295a1272a1d787986c99bd133261fe45c763efc (patch) | |
tree | 3f5a9d5299063e9d69f99a9a275097d02908dbb0 /src/lib | |
parent | 66646d927637b7b370fa81a098d3c35de7a47748 (diff) |
lib/icu/Compare: add fallback using strcasecmp() and strcasestr()
Our IcuCaseFold() fallback using strxfrm() is not actually case
insensitive. This commit fixes the problem by switching to
strcasecmp(). That function is not guaranteed to support UTF-8, but
it's the best we can do in this sparse situation.
Closes #111
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/icu/CaseFold.hxx | 4 | ||||
-rw-r--r-- | src/lib/icu/Compare.cxx | 25 |
2 files changed, 29 insertions, 0 deletions
diff --git a/src/lib/icu/CaseFold.hxx b/src/lib/icu/CaseFold.hxx index bb5d5e76e..5b9fa6064 100644 --- a/src/lib/icu/CaseFold.hxx +++ b/src/lib/icu/CaseFold.hxx @@ -23,6 +23,10 @@ #include "check.h" #include "Compiler.h" +#if defined(HAVE_ICU) || defined(_WIN32) +#define HAVE_ICU_CASE_FOLD +#endif + template<typename T> class AllocatedString; gcc_nonnull_all diff --git a/src/lib/icu/Compare.cxx b/src/lib/icu/Compare.cxx index dc571a316..21b3230bb 100644 --- a/src/lib/icu/Compare.cxx +++ b/src/lib/icu/Compare.cxx @@ -24,18 +24,43 @@ #include <string.h> +#ifdef HAVE_ICU_CASE_FOLD + IcuCompare::IcuCompare(const char *_needle) noexcept :needle(IcuCaseFold(_needle)) {} +#else + +IcuCompare::IcuCompare(const char *_needle) noexcept + :needle(AllocatedString<>::Duplicate(_needle)) {} + +#endif + bool IcuCompare::operator==(const char *haystack) const noexcept { +#ifdef HAVE_ICU_CASE_FOLD return StringIsEqual(IcuCaseFold(haystack).c_str(), needle.c_str()); +#else + return strcasecmp(haystack, needle.c_str()); +#endif } bool IcuCompare::IsIn(const char *haystack) const noexcept { +#ifdef HAVE_ICU_CASE_FOLD return StringFind(IcuCaseFold(haystack).c_str(), needle.c_str()) != nullptr; +#elif defined(HAVE_STRCASESTR) + return strcasestr(haystack, needle.c_str()) != nullptr; +#else + /* poor man's strcasestr() */ + for (const size_t length = strlen(needle.c_str()); + *haystack != 0; ++haystack) + if (strncasecmp(haystack, needle.c_str(), length) == 0) + return true; + + return false; +#endif } |