brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.5 KiB · 5d5a5f2 Raw
79 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "GlobList.h"10#include "llvm/ADT/STLExtras.h"11#include "llvm/ADT/SmallString.h"12 13namespace clang::tidy {14 15// Returns true if GlobList starts with the negative indicator ('-'), removes it16// from the GlobList.17static bool consumeNegativeIndicator(StringRef &GlobList) {18  GlobList = GlobList.trim();19  return GlobList.consume_front("-");20}21 22// Extracts the first glob from the comma-separated list of globs,23// removes it and the trailing comma from the GlobList and24// returns the extracted glob.25static llvm::StringRef extractNextGlob(StringRef &GlobList) {26  const StringRef UntrimmedGlob =27      GlobList.substr(0, GlobList.find_first_of(",\n"));28  const StringRef Glob = UntrimmedGlob.trim();29  GlobList = GlobList.substr(UntrimmedGlob.size() + 1);30  return Glob;31}32 33static llvm::Regex createRegexFromGlob(StringRef &Glob) {34  SmallString<128> RegexText("^");35  const StringRef MetaChars("()^$|*+?.[]\\{}");36  for (const char C : Glob) {37    if (C == '*')38      RegexText.push_back('.');39    else if (MetaChars.contains(C))40      RegexText.push_back('\\');41    RegexText.push_back(C);42  }43  RegexText.push_back('$');44  return {RegexText.str()};45}46 47GlobList::GlobList(StringRef Globs, bool KeepNegativeGlobs /* =true */) {48  Items.reserve(Globs.count(',') + Globs.count('\n') + 1);49  do {50    GlobListItem Item;51    Item.IsPositive = !consumeNegativeIndicator(Globs);52    Item.Text = extractNextGlob(Globs);53    Item.Regex = createRegexFromGlob(Item.Text);54    if (Item.IsPositive || KeepNegativeGlobs)55      Items.push_back(std::move(Item));56  } while (!Globs.empty());57}58 59bool GlobList::contains(StringRef S) const {60  // Iterating the container backwards as the last match determins if S is in61  // the list.62  for (const GlobListItem &Item : llvm::reverse(Items)) {63    if (Item.Regex.match(S))64      return Item.IsPositive;65  }66  return false;67}68 69bool CachedGlobList::contains(StringRef S) const {70  auto Entry = Cache.try_emplace(S);71  bool &Value = Entry.first->getValue();72  // If the entry was just inserted, determine its required value.73  if (Entry.second)74    Value = GlobList::contains(S);75  return Value;76}77 78} // namespace clang::tidy79