summaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Support/GlobPattern.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-12-20 19:53:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-12-20 19:53:05 +0000
commit0b57cec536236d46e3dba9bd041533462f33dbb7 (patch)
tree56229dbdbbf76d18580f72f789003db17246c8d9 /contrib/llvm/lib/Support/GlobPattern.cpp
parent718ef55ec7785aae63f98f8ca05dc07ed399c16d (diff)
Notes
Diffstat (limited to 'contrib/llvm/lib/Support/GlobPattern.cpp')
-rw-r--r--contrib/llvm/lib/Support/GlobPattern.cpp169
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);
- }
-}