diff options
Diffstat (limited to 'src/zenutil/wildcard.cpp')
| -rw-r--r-- | src/zenutil/wildcard.cpp | 112 |
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 |