Wildcard.h#
Fully qualified name: omni/str/Wildcard.h
File members: omni/str/Wildcard.h
// SPDX-FileCopyrightText: Copyright (c) 2020-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.
#pragma once
#include "../../carb/Deprecation.h"
#include "../../carb/cpp/Optional.h"
#include "../../carb/cpp/Span.h"
#include "../../carb/cpp/StringView.h"
#include "../../carb/cpp/UnboundedString.h"
#include <cstddef>
#include <cstdint>
namespace omni::str
{
CARB_DEPRECATED("Use omni::str::matchWildcard with carb::cpp::string_view instead")
inline bool matchWildcard(carb::cpp::unbounded_string str, carb::cpp::unbounded_string pattern)
{
const char* star = nullptr;
const char* s0 = str;
const char* s1 = s0;
const char* p = pattern;
while (*s0)
{
// Advance both pointers when both characters match or '?' found in pattern
if ((*p == '?') || (*p == *s0))
{
s0++;
p++;
continue;
}
// * found in pattern, save index of *, advance a pattern pointer
if (*p == '*')
{
star = p++;
s1 = s0;
continue;
}
// Current characters didn't match, consume character in string and rewind to star pointer in the pattern
if (star)
{
p = star + 1;
s0 = ++s1;
continue;
}
// Characters do not match and current pattern pointer is not star
return false;
}
// Skip remaining stars in pattern
while (*p == '*')
{
p++;
}
return !*p; // Was whole pattern matched?
}
inline bool matchWildcard(carb::cpp::string_view str, carb::cpp::string_view pattern) noexcept
{
size_t s = 0, p = 0;
size_t star_idx = carb::cpp::string_view::npos;
size_t match_pos = 0;
while (s < str.size())
{
// Direct match or '?' wildcard
if (p < pattern.size() && (pattern[p] == str[s] || pattern[p] == '?'))
{
++s;
++p;
}
// '*' wildcard - save position for backtracking
else if (p < pattern.size() && pattern[p] == '*')
{
star_idx = p++;
match_pos = s;
}
// Backtrack to last '*' if available
else if (star_idx != carb::cpp::string_view::npos)
{
p = star_idx + 1;
s = ++match_pos;
}
// No match possible
else
{
return false;
}
}
// Consume trailing '*' in pattern
while (p < pattern.size() && pattern[p] == '*')
++p;
return p == pattern.size();
}
inline const char* matchWildcards(const char* str, const char* const* patterns, size_t patternsCount)
{
for (size_t i = 0; i < patternsCount; ++i)
{
CARB_IGNORE_DEPRECATION_BEGIN
if (matchWildcard(str, patterns[i]))
{
return patterns[i];
}
CARB_IGNORE_DEPRECATION_END
}
return nullptr;
}
inline carb::cpp::optional<carb::cpp::string_view> matchWildcards(carb::cpp::string_view str,
carb::cpp::span<const carb::cpp::string_view> patterns)
{
for (const auto& pattern : patterns)
{
if (matchWildcard(str, pattern))
return pattern;
}
return carb::cpp::nullopt;
}
CARB_DEPRECATED("Use omni::str::matchWildcard with carb::cpp::string_view instead")
inline bool isWildcardPattern(carb::cpp::unbounded_string pattern)
{
for (const char* p = pattern; p[0] != 0; p++)
{
if (*p == '*' || *p == '?')
return true;
}
return false;
}
inline bool isWildcardPattern(carb::cpp::string_view pattern)
{
return pattern.find_first_of("*?") != carb::cpp::string_view::npos;
}
} // namespace omni::str