// Copyright Epic Games, Inc. All Rights Reserved. #include #include #if ZEN_WITH_TESTS # include #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 == StringEnd) { return false; } if (*StringIt != *WildcardIt) { return false; } ++StringIt; break; } } 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)); } } bool IncludePath(std::span IncludeWildcards, std::span ExcludeWildcards, const std::string& Path, bool CaseSensitive) { bool IncludePath = true; if (!IncludeWildcards.empty()) { IncludePath = false; for (const std::string& IncludeWildcard : IncludeWildcards) { if (MatchWildcard(IncludeWildcard, Path, CaseSensitive)) { IncludePath = true; break; } } if (!IncludePath) { return false; } } for (const std::string& ExcludeWildcard : ExcludeWildcards) { if (MatchWildcard(ExcludeWildcard, Path, CaseSensitive)) { return false; } } return true; } #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)); CHECK(MatchWildcard("*.dll", "dir/path.dll", true)); CHECK(!MatchWildcard("*.dll", "dir/path.d", true)); CHECK(!MatchWildcard("*.d", "dir/path.dll", true)); CHECK(MatchWildcard("*.d", "dir/path.d", true)); } #endif } // namespace zen