[lld] r290212 - Move GlobPattern class from LLD to llvm/Support.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 20 15:29:22 PST 2016


Thanks!

Rui Ueyama via llvm-commits <llvm-commits at lists.llvm.org> writes:

> Author: ruiu
> Date: Tue Dec 20 17:09:09 2016
> New Revision: 290212
>
> URL: http://llvm.org/viewvc/llvm-project?rev=290212&view=rev
> Log:
> Move GlobPattern class from LLD to llvm/Support.
>
> GlobPattern is a class to handle glob pattern matching. Currently
> only LLD is using that, but technically that feature is not specific
> to linkers, so in this patch I move that file to LLVM.
>
> Differential Revision: https://reviews.llvm.org/D27969
>
> Modified:
>     lld/trunk/ELF/Strings.cpp
>     lld/trunk/ELF/Strings.h
>
> Modified: lld/trunk/ELF/Strings.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Strings.cpp?rev=290212&r1=290211&r2=290212&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Strings.cpp (original)
> +++ lld/trunk/ELF/Strings.cpp Tue Dec 20 17:09:09 2016
> @@ -21,134 +21,14 @@ using namespace llvm;
>  using namespace lld;
>  using namespace lld::elf;
>  
> -// 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.
> -BitVector GlobPattern::scan(StringRef &S) {
> -  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) {
> -      error("invalid glob pattern: " + Original);
> -      S = "";
> -      return BitVector(256, false);
> -    }
> -    StringRef Chars = S.substr(1, End - 1);
> -    S = S.substr(End + 1);
> -    if (Chars.startswith("^"))
> -      return expand(Chars.substr(1)).flip();
> -    return expand(Chars);
> -  }
> -  default:
> -    BitVector BV(256, false);
> -    BV[S[0]] = true;
> -    S = S.substr(1);
> -    return BV;
> -  }
> -}
> -
> -// Expands character ranges and returns a bitmap.
> -// For example, "a-cf-hz" is expanded to "abcfghz".
> -BitVector GlobPattern::expand(StringRef S) {
> -  BitVector BV(256, false);
> -
> -  // Expand "x-y".
> -  for (;;) {
> -    if (S.size() < 3)
> -      break;
> -
> -    // If it doesn't start with something like "x-y",
> -    // consume the first character and proceed.
> -    if (S[1] != '-') {
> -      BV[S[0]] = true;
> -      S = S.substr(1);
> -      continue;
> -    }
> -
> -    // It must be in the form of "x-y".
> -    // Validate it and then interpret the range.
> -    if (S[0] > S[2]) {
> -      error("invalid glob pattern: " + Original);
> -      return BV;
> -    }
> -    for (int C = S[0]; C <= S[2]; ++C)
> -      BV[C] = true;
> -    S = S.substr(3);
> -  }
> -
> -  for (char C : S)
> -    BV[C] = true;
> -  return BV;
> -}
> -
> -GlobPattern::GlobPattern(StringRef S) : Original(S) {
> -  if (!hasWildcard(S)) {
> -    // S doesn't contain any metacharacter,
> -    // so the regular string comparison should work.
> -    Exact = S;
> -  } else if (S.endswith("*") && !hasWildcard(S.drop_back())) {
> -    // S is something like "foo*". We can use startswith().
> -    Prefix = S.drop_back();
> -  } else if (S.startswith("*") && !hasWildcard(S.drop_front())) {
> -    // S is something like "*foo". We can use endswith().
> -    Suffix = S.drop_front();
> -  } else {
> -    // Otherwise, we need to do real glob pattern matching.
> -    // Parse the pattern now.
> -    while (!S.empty())
> -      Tokens.push_back(scan(S));
> -  }
> -}
> -
> -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
> -    // substrings 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][S[0]])
> -      return false;
> -    Pats = Pats.slice(1);
> -    S = S.substr(1);
> -  }
> -}
> -
>  StringMatcher::StringMatcher(const std::vector<StringRef> &Pat) {
> -  for (StringRef S : Pat)
> -    Patterns.push_back(GlobPattern(S));
> +  for (StringRef S : Pat) {
> +    Expected<GlobPattern> Pat = GlobPattern::create(S);
> +    if (!Pat)
> +      error(toString(Pat.takeError()));
> +    else
> +      Patterns.push_back(*Pat);
> +  }
>  }
>  
>  bool StringMatcher::match(StringRef S) const {
>
> Modified: lld/trunk/ELF/Strings.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Strings.h?rev=290212&r1=290211&r2=290212&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Strings.h (original)
> +++ lld/trunk/ELF/Strings.h Tue Dec 20 17:09:09 2016
> @@ -15,6 +15,7 @@
>  #include "llvm/ADT/BitVector.h"
>  #include "llvm/ADT/Optional.h"
>  #include "llvm/ADT/StringRef.h"
> +#include "llvm/Support/GlobPattern.h"
>  #include <vector>
>  
>  namespace lld {
> @@ -56,30 +57,6 @@ private:
>    mutable size_t Size;
>  };
>  
> -// This class represents a glob pattern. Supported metacharacters
> -// are "*", "?", "[<chars>]" and "[^<chars>]".
> -class GlobPattern {
> -public:
> -  explicit GlobPattern(StringRef Pat);
> -  bool match(StringRef S) const;
> -
> -private:
> -  bool matchOne(ArrayRef<llvm::BitVector> Pat, StringRef S) const;
> -  llvm::BitVector scan(StringRef &S);
> -  llvm::BitVector expand(StringRef S);
> -
> -  // Parsed glob pattern.
> -  std::vector<llvm::BitVector> Tokens;
> -
> -  // A glob pattern given to this class. This is for error reporting.
> -  StringRef Original;
> -
> -  // The following members are for optimization.
> -  llvm::Optional<StringRef> Exact;
> -  llvm::Optional<StringRef> Prefix;
> -  llvm::Optional<StringRef> Suffix;
> -};
> -
>  // This class represents multiple glob patterns.
>  class StringMatcher {
>  public:
> @@ -89,7 +66,7 @@ public:
>    bool match(StringRef S) const;
>  
>  private:
> -  std::vector<GlobPattern> Patterns;
> +  std::vector<llvm::GlobPattern> Patterns;
>  };
>  
>  // Returns a demangled C++ symbol name. If Name is not a mangled
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list