aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil/wildcard.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zenutil/wildcard.cpp')
-rw-r--r--src/zenutil/wildcard.cpp112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/zenutil/wildcard.cpp b/src/zenutil/wildcard.cpp
new file mode 100644
index 000000000..df69f6a5e
--- /dev/null
+++ b/src/zenutil/wildcard.cpp
@@ -0,0 +1,112 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include <zencore/string.h>
+#include <zenutil/wildcard.h>
+
+#if ZEN_WITH_TESTS
+# include <zencore/testing.h>
+#endif // ZEN_WITH_TESTS
+
+namespace zen {
+
+bool
+MatchWildcard(std::string_view::const_iterator WildcardIt,
+ std::string_view::const_iterator WildcardEnd,
+ std::string_view::const_iterator StringIt,
+ std::string_view::const_iterator StringEnd)
+{
+ for (; WildcardIt != WildcardEnd; WildcardIt++)
+ {
+ switch (*WildcardIt)
+ {
+ case '?':
+ if (StringIt == StringEnd)
+ {
+ return false;
+ }
+ StringIt++;
+ break;
+ case '*':
+ {
+ if ((WildcardIt + 1) == WildcardEnd)
+ {
+ return true;
+ }
+ size_t Max = std::distance(StringIt, StringEnd);
+ for (size_t i = 0; i < Max; i++)
+ {
+ if (MatchWildcard(WildcardIt + 1, WildcardEnd, StringIt + i, StringEnd))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ default:
+ if (*StringIt != *WildcardIt)
+ {
+ return false;
+ }
+ ++StringIt;
+ }
+ }
+ return StringIt == StringEnd;
+}
+
+bool
+MatchWildcard(std::string_view Wildcard, std::string_view String, bool CaseSensitive)
+{
+ if (CaseSensitive)
+ {
+ return MatchWildcard(begin(Wildcard), end(Wildcard), begin(String), end(String));
+ }
+ else
+ {
+ std::string LowercaseWildcard = ToLower(Wildcard);
+ std::string LowercaseString = ToLower(String);
+ std::string_view LowercaseWildcardView(LowercaseWildcard);
+ std::string_view LowercaseStringView(LowercaseString);
+ return MatchWildcard(begin(LowercaseWildcardView),
+ end(LowercaseWildcardView),
+ begin(LowercaseStringView),
+ end(LowercaseStringView));
+ }
+}
+
+#if ZEN_WITH_TESTS
+
+void
+wildcard_forcelink()
+{
+}
+
+TEST_CASE("Wildcard")
+{
+ CHECK(MatchWildcard("*.*", "normal.txt", true));
+ CHECK(MatchWildcard("*.*", "normal.txt", false));
+
+ CHECK(!MatchWildcard("*.*", "normal", true));
+ CHECK(!MatchWildcard("*.*", "normal", false));
+
+ CHECK(MatchWildcard("*", "hey/normal", true));
+ CHECK(MatchWildcard("*", "hey/normal", false));
+
+ CHECK(MatchWildcard("hey/*.txt", "hey/normal.txt", true));
+ CHECK(MatchWildcard("*/?ormal.txt", "hey/normal.txt", true));
+ CHECK(!MatchWildcard("*/?rmal.txt", "hey/normal.txt", true));
+ CHECK(MatchWildcard("*/?ormal.*", "hey/normal.txt", true));
+ CHECK(MatchWildcard("*/?ormal", "hey/normal", true));
+
+ CHECK(MatchWildcard("hey/*.txt", "hey/normaL.txt", false));
+ CHECK(MatchWildcard("*/?ormal.TXT", "hey/normal.txt", false));
+ CHECK(MatchWildcard("*/?ORMAL.*", "hey/normal.txt", false));
+ CHECK(MatchWildcard("*/?ormal", "HEY/normal", false));
+
+ CHECK(!MatchWildcard("hey/*.txt", "heY/normal.txt", true));
+ CHECK(!MatchWildcard("*/?ormal.TXT", "hey/normal.txt", true));
+ CHECK(!MatchWildcard("*/?ORMAL.*", "hey/normal.txt", true));
+ CHECK(!MatchWildcard("*/?ormal", "hey/normaL", true));
+}
+
+#endif
+} // namespace zen