diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
| commit | 0b57cec536236d46e3dba9bd041533462f33dbb7 (patch) | |
| tree | 56229dbdbbf76d18580f72f789003db17246c8d9 /contrib/llvm/lib/Support/GlobPattern.cpp | |
| parent | 718ef55ec7785aae63f98f8ca05dc07ed399c16d (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/lib/Support/GlobPattern.cpp')
| -rw-r--r-- | contrib/llvm/lib/Support/GlobPattern.cpp | 169 |
1 files changed, 0 insertions, 169 deletions
diff --git a/contrib/llvm/lib/Support/GlobPattern.cpp b/contrib/llvm/lib/Support/GlobPattern.cpp deleted file mode 100644 index 6011be86d77f..000000000000 --- a/contrib/llvm/lib/Support/GlobPattern.cpp +++ /dev/null @@ -1,169 +0,0 @@ -//===-- GlobPattern.cpp - Glob pattern matcher implementation -------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements a glob pattern matcher. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/GlobPattern.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Errc.h" - -using namespace llvm; - -static bool hasWildcard(StringRef S) { - return S.find_first_of("?*[") != StringRef::npos; -} - -// Expands character ranges and returns a bitmap. -// For example, "a-cf-hz" is expanded to "abcfghz". -static Expected<BitVector> expand(StringRef S, StringRef Original) { - BitVector BV(256, false); - - // Expand X-Y. - for (;;) { - if (S.size() < 3) - break; - - uint8_t Start = S[0]; - uint8_t End = S[2]; - - // If it doesn't start with something like X-Y, - // consume the first character and proceed. - if (S[1] != '-') { - BV[Start] = true; - S = S.substr(1); - continue; - } - - // It must be in the form of X-Y. - // Validate it and then interpret the range. - if (Start > End) - return make_error<StringError>("invalid glob pattern: " + Original, - errc::invalid_argument); - - for (int C = Start; C <= End; ++C) - BV[(uint8_t)C] = true; - S = S.substr(3); - } - - for (char C : S) - BV[(uint8_t)C] = true; - return BV; -} - -// This is a scanner for the glob pattern. -// A glob pattern token is one of "*", "?", "[<chars>]", "[^<chars>]" -// (which is a negative form of "[<chars>]"), or a non-meta character. -// This function returns the first token in S. -static Expected<BitVector> scan(StringRef &S, StringRef Original) { - switch (S[0]) { - case '*': - S = S.substr(1); - // '*' is represented by an empty bitvector. - // All other bitvectors are 256-bit long. - return BitVector(); - case '?': - S = S.substr(1); - return BitVector(256, true); - case '[': { - size_t End = S.find(']', 1); - if (End == StringRef::npos) - return make_error<StringError>("invalid glob pattern: " + Original, - errc::invalid_argument); - - StringRef Chars = S.substr(1, End - 1); - S = S.substr(End + 1); - if (Chars.startswith("^")) { - Expected<BitVector> BV = expand(Chars.substr(1), Original); - if (!BV) - return BV.takeError(); - return BV->flip(); - } - return expand(Chars, Original); - } - default: - BitVector BV(256, false); - BV[(uint8_t)S[0]] = true; - S = S.substr(1); - return BV; - } -} - -Expected<GlobPattern> GlobPattern::create(StringRef S) { - GlobPattern Pat; - - // S doesn't contain any metacharacter, - // so the regular string comparison should work. - if (!hasWildcard(S)) { - Pat.Exact = S; - return Pat; - } - - // S is something like "foo*". We can use startswith(). - if (S.endswith("*") && !hasWildcard(S.drop_back())) { - Pat.Prefix = S.drop_back(); - return Pat; - } - - // S is something like "*foo". We can use endswith(). - if (S.startswith("*") && !hasWildcard(S.drop_front())) { - Pat.Suffix = S.drop_front(); - return Pat; - } - - // Otherwise, we need to do real glob pattern matching. - // Parse the pattern now. - StringRef Original = S; - while (!S.empty()) { - Expected<BitVector> BV = scan(S, Original); - if (!BV) - return BV.takeError(); - Pat.Tokens.push_back(*BV); - } - return Pat; -} - -bool GlobPattern::match(StringRef S) const { - if (Exact) - return S == *Exact; - if (Prefix) - return S.startswith(*Prefix); - if (Suffix) - return S.endswith(*Suffix); - return matchOne(Tokens, S); -} - -// Runs glob pattern Pats against string S. -bool GlobPattern::matchOne(ArrayRef<BitVector> Pats, StringRef S) const { - for (;;) { - if (Pats.empty()) - return S.empty(); - - // If Pats[0] is '*', try to match Pats[1..] against all possible - // tail strings of S to see at least one pattern succeeds. - if (Pats[0].size() == 0) { - Pats = Pats.slice(1); - if (Pats.empty()) - // Fast path. If a pattern is '*', it matches anything. - return true; - for (size_t I = 0, E = S.size(); I < E; ++I) - if (matchOne(Pats, S.substr(I))) - return true; - return false; - } - - // If Pats[0] is not '*', it must consume one character. - if (S.empty() || !Pats[0][(uint8_t)S[0]]) - return false; - Pats = Pats.slice(1); - S = S.substr(1); - } -} |
