summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2017-09-20 23:43:06 +0200
committerMax Kellermann <max@musicpd.org>2017-09-20 23:43:27 +0200
commit1295a1272a1d787986c99bd133261fe45c763efc (patch)
tree3f5a9d5299063e9d69f99a9a275097d02908dbb0 /src/lib
parent66646d927637b7b370fa81a098d3c35de7a47748 (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.hxx4
-rw-r--r--src/lib/icu/Compare.cxx25
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
}