[Lldb-commits] [lldb] 532290e - [lldb] s/FileSpec::Equal/FileSpec::Match
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Wed Dec 4 01:45:18 PST 2019
Author: Pavel Labath
Date: 2019-12-04T10:42:32+01:00
New Revision: 532290e69fcb0e1f2005853241bc2cac6941e0f7
URL: https://github.com/llvm/llvm-project/commit/532290e69fcb0e1f2005853241bc2cac6941e0f7
DIFF: https://github.com/llvm/llvm-project/commit/532290e69fcb0e1f2005853241bc2cac6941e0f7.diff
LOG: [lldb] s/FileSpec::Equal/FileSpec::Match
Summary:
The FileSpec class is often used as a sort of a pattern -- one specifies
a bare file name to search, and we check if in matches the full file
name of an existing module (for example).
These comparisons used FileSpec::Equal, which had some support for it
(via the full=false argument), but it was not a good fit for this job.
For one, it did a symmetric comparison, which makes sense for a function
called "equal", but not for typical searches (when searching for
"/foo/bar.so", we don't want to find a module whose name is just
"bar.so"). This resulted in patterns like:
if (FileSpec::Equal(pattern, file, pattern.GetDirectory()))
which would request a "full" match only if the pattern really contained
a directory. This worked, but the intended behavior was very unobvious.
On top of that, a lot of the code wanted to handle the case of an
"empty" pattern, and treat it as matching everything. This resulted in
conditions like:
if (pattern && !FileSpec::Equal(pattern, file, pattern.GetDirectory())
which are nearly impossible to decipher.
This patch introduces a FileSpec::Match function, which does exactly
what most of FileSpec::Equal callers want, an asymmetric match between a
"pattern" FileSpec and a an actual FileSpec. Empty paterns match
everything, filename-only patterns match only the filename component.
I've tried to update all callers of FileSpec::Equal to use a simpler
interface. Those that hardcoded full=true have been changed to use
operator==. Those passing full=pattern.GetDirectory() have been changed
to use FileSpec::Match.
There was also a handful of places which hardcoded full=false. I've
changed these to use FileSpec::Match too. This is a slight change in
semantics, but it does not look like that was ever intended, and it was
more likely a result of a misunderstanding of the "proper" way to use
FileSpec::Equal.
[In an ideal world a "FileSpec" and a "FileSpec pattern" would be two
different types, but given how widespread FileSpec is, it is unlikely
we'll get there in one go. This at least provides a good starting point
by centralizing all matching behavior.]
Reviewers: teemperor, JDevlieghere, jdoerfert
Subscribers: emaste, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D70851
Added:
Modified:
lldb/include/lldb/Core/ModuleSpec.h
lldb/include/lldb/Core/SourceManager.h
lldb/include/lldb/Utility/FileSpec.h
lldb/source/Breakpoint/Breakpoint.cpp
lldb/source/Commands/CommandObjectSource.cpp
lldb/source/Core/IOHandlerCursesGUI.cpp
lldb/source/Core/Module.cpp
lldb/source/Core/SearchFilter.cpp
lldb/source/Core/SourceManager.cpp
lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
lldb/source/Symbol/CompileUnit.cpp
lldb/source/Symbol/Declaration.cpp
lldb/source/Symbol/SymbolContext.cpp
lldb/source/Target/TargetList.cpp
lldb/source/Target/ThreadPlanStepInRange.cpp
lldb/source/Utility/FileSpec.cpp
lldb/unittests/Utility/FileSpecTest.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Core/ModuleSpec.h b/lldb/include/lldb/Core/ModuleSpec.h
index 26be59e3f4ae..6d024fe3434b 100644
--- a/lldb/include/lldb/Core/ModuleSpec.h
+++ b/lldb/include/lldb/Core/ModuleSpec.h
@@ -251,24 +251,18 @@ class ModuleSpec {
if (match_module_spec.GetObjectName() &&
match_module_spec.GetObjectName() != GetObjectName())
return false;
- if (match_module_spec.GetFileSpecPtr()) {
- const FileSpec &fspec = match_module_spec.GetFileSpec();
- if (!FileSpec::Equal(fspec, GetFileSpec(),
- !fspec.GetDirectory().IsEmpty()))
- return false;
- }
- if (GetPlatformFileSpec() && match_module_spec.GetPlatformFileSpecPtr()) {
- const FileSpec &fspec = match_module_spec.GetPlatformFileSpec();
- if (!FileSpec::Equal(fspec, GetPlatformFileSpec(),
- !fspec.GetDirectory().IsEmpty()))
- return false;
+ if (!FileSpec::Match(match_module_spec.GetFileSpec(), GetFileSpec()))
+ return false;
+ if (GetPlatformFileSpec() &&
+ !FileSpec::Match(match_module_spec.GetPlatformFileSpec(),
+ GetPlatformFileSpec())) {
+ return false;
}
// Only match the symbol file spec if there is one in this ModuleSpec
- if (GetSymbolFileSpec() && match_module_spec.GetSymbolFileSpecPtr()) {
- const FileSpec &fspec = match_module_spec.GetSymbolFileSpec();
- if (!FileSpec::Equal(fspec, GetSymbolFileSpec(),
- !fspec.GetDirectory().IsEmpty()))
- return false;
+ if (GetSymbolFileSpec() &&
+ !FileSpec::Match(match_module_spec.GetSymbolFileSpec(),
+ GetSymbolFileSpec())) {
+ return false;
}
if (match_module_spec.GetArchitecturePtr()) {
if (exact_arch_match) {
diff --git a/lldb/include/lldb/Core/SourceManager.h b/lldb/include/lldb/Core/SourceManager.h
index bca817750d8d..f1f56d0886c3 100644
--- a/lldb/include/lldb/Core/SourceManager.h
+++ b/lldb/include/lldb/Core/SourceManager.h
@@ -54,8 +54,6 @@ class SourceManager {
bool LineIsValid(uint32_t line);
- bool FileSpecMatches(const FileSpec &file_spec);
-
const FileSpec &GetFileSpec() { return m_file_spec; }
uint32_t GetSourceMapModificationID() const { return m_source_map_mod_id; }
diff --git a/lldb/include/lldb/Utility/FileSpec.h b/lldb/include/lldb/Utility/FileSpec.h
index 53b0a9c08699..9da6670f1c61 100644
--- a/lldb/include/lldb/Utility/FileSpec.h
+++ b/lldb/include/lldb/Utility/FileSpec.h
@@ -195,6 +195,12 @@ class FileSpec {
static bool Equal(const FileSpec &a, const FileSpec &b, bool full);
+ /// Match FileSpec \a pattern against FileSpec \a file. If \a pattern has a
+ /// directory component, then the \a file must have the same directory
+ /// component. Otherwise, just it matches just the filename. An empty \a
+ /// pattern matches everything.
+ static bool Match(const FileSpec &pattern, const FileSpec &file);
+
/// Attempt to guess path style for a given path string. It returns a style,
/// if it was able to make a reasonable guess, or None if it wasn't. The guess
/// will be correct if the input path was a valid absolute path on the system
diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp
index 3ee9ece56776..13acf4bb92e2 100644
--- a/lldb/source/Breakpoint/Breakpoint.cpp
+++ b/lldb/source/Breakpoint/Breakpoint.cpp
@@ -638,8 +638,8 @@ static bool SymbolContextsMightBeEquivalent(SymbolContext &old_sc,
} else {
// Otherwise we will compare by name...
if (old_sc.comp_unit && new_sc.comp_unit) {
- if (FileSpec::Equal(old_sc.comp_unit->GetPrimaryFile(),
- new_sc.comp_unit->GetPrimaryFile(), true)) {
+ if (old_sc.comp_unit->GetPrimaryFile() ==
+ new_sc.comp_unit->GetPrimaryFile()) {
// Now check the functions:
if (old_sc.function && new_sc.function &&
(old_sc.function->GetName() == new_sc.function->GetName())) {
diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp
index f2591b4f6256..807c04f4c65e 100644
--- a/lldb/source/Commands/CommandObjectSource.cpp
+++ b/lldb/source/Commands/CommandObjectSource.cpp
@@ -146,12 +146,6 @@ class CommandObjectSourceInfo : public CommandObjectParsed {
Target *target = m_exe_ctx.GetTargetPtr();
uint32_t num_matches = 0;
- bool has_path = false;
- if (file_spec) {
- assert(file_spec.GetFilename().AsCString());
- has_path = (file_spec.GetDirectory().AsCString() != nullptr);
- }
-
// Dump all the line entries for the file in the list.
ConstString last_module_file_name;
uint32_t num_scs = sc_list.GetSize();
@@ -168,8 +162,7 @@ class CommandObjectSourceInfo : public CommandObjectParsed {
if (module_list.GetSize() &&
module_list.GetIndexForModule(module) == LLDB_INVALID_INDEX32)
continue;
- if (file_spec && !lldb_private::FileSpec::Equal(
- file_spec, line_entry.file, has_path))
+ if (!FileSpec::Match(file_spec, line_entry.file))
continue;
if (start_line > 0 && line_entry.line < start_line)
continue;
@@ -250,8 +243,7 @@ class CommandObjectSourceInfo : public CommandObjectParsed {
num_matches++;
if (num_lines > 0 && num_matches > num_lines)
break;
- assert(lldb_private::FileSpec::Equal(cu_file_spec, line_entry.file,
- has_path));
+ assert(cu_file_spec == line_entry.file);
if (!cu_header_printed) {
if (num_matches > 0)
strm << "\n\n";
diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp b/lldb/source/Core/IOHandlerCursesGUI.cpp
index 0c9fdd3b0a14..cb6fbaa99ea6 100644
--- a/lldb/source/Core/IOHandlerCursesGUI.cpp
+++ b/lldb/source/Core/IOHandlerCursesGUI.cpp
@@ -3322,7 +3322,7 @@ class SourceFileWindowDelegate : public WindowDelegate {
if (context_changed)
m_selected_line = m_pc_line;
- if (m_file_sp && m_file_sp->FileSpecMatches(m_sc.line_entry.file)) {
+ if (m_file_sp && m_file_sp->GetFileSpec() == m_sc.line_entry.file) {
// Same file, nothing to do, we should either have the lines or not
// (source file missing)
if (m_selected_line >= static_cast<size_t>(m_first_visible_line)) {
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index a8a92bb5b1fa..cc4eea674170 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -613,12 +613,10 @@ void Module::FindCompileUnits(const FileSpec &path,
const size_t num_compile_units = GetNumCompileUnits();
SymbolContext sc;
sc.module_sp = shared_from_this();
- const bool compare_directory = (bool)path.GetDirectory();
for (size_t i = 0; i < num_compile_units; ++i) {
sc.comp_unit = GetCompileUnitAtIndex(i).get();
if (sc.comp_unit) {
- if (FileSpec::Equal(sc.comp_unit->GetPrimaryFile(), path,
- compare_directory))
+ if (FileSpec::Match(path, sc.comp_unit->GetPrimaryFile()))
sc_list.Append(sc);
}
}
@@ -1561,19 +1559,13 @@ bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) {
}
const FileSpec &file_spec = module_ref.GetFileSpec();
- if (file_spec) {
- if (!FileSpec::Equal(file_spec, m_file, (bool)file_spec.GetDirectory()) &&
- !FileSpec::Equal(file_spec, m_platform_file,
- (bool)file_spec.GetDirectory()))
- return false;
- }
+ if (!FileSpec::Match(file_spec, m_file) &&
+ !FileSpec::Match(file_spec, m_platform_file))
+ return false;
const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec();
- if (platform_file_spec) {
- if (!FileSpec::Equal(platform_file_spec, GetPlatformFileSpec(),
- (bool)platform_file_spec.GetDirectory()))
- return false;
- }
+ if (!FileSpec::Match(platform_file_spec, GetPlatformFileSpec()))
+ return false;
const ArchSpec &arch = module_ref.GetArchitecture();
if (arch.IsValid()) {
diff --git a/lldb/source/Core/SearchFilter.cpp b/lldb/source/Core/SearchFilter.cpp
index c49b59e601e1..077aa8967425 100644
--- a/lldb/source/Core/SearchFilter.cpp
+++ b/lldb/source/Core/SearchFilter.cpp
@@ -403,13 +403,11 @@ SearchFilterByModule::~SearchFilterByModule() = default;
bool SearchFilterByModule::ModulePasses(const ModuleSP &module_sp) {
return (module_sp &&
- FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false));
+ FileSpec::Match(m_module_spec, module_sp->GetFileSpec()));
}
bool SearchFilterByModule::ModulePasses(const FileSpec &spec) {
- // Do a full match only if "spec" has a directory
- const bool full_match = (bool)spec.GetDirectory();
- return FileSpec::Equal(spec, m_module_spec, full_match);
+ return FileSpec::Match(m_module_spec, spec);
}
bool SearchFilterByModule::AddressPasses(Address &address) {
@@ -443,8 +441,7 @@ void SearchFilterByModule::Search(Searcher &searcher) {
const size_t num_modules = target_modules.GetSize();
for (size_t i = 0; i < num_modules; i++) {
Module *module = target_modules.GetModulePointerAtIndexUnlocked(i);
- const bool full_match = (bool)m_module_spec.GetDirectory();
- if (FileSpec::Equal(m_module_spec, module->GetFileSpec(), full_match)) {
+ if (FileSpec::Match(m_module_spec, module->GetFileSpec())) {
SymbolContext matchingContext(m_target_sp, module->shared_from_this());
Searcher::CallbackReturn shouldContinue;
diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp
index e3780e0b071a..8e0cc57f80c1 100644
--- a/lldb/source/Core/SourceManager.cpp
+++ b/lldb/source/Core/SourceManager.cpp
@@ -64,7 +64,8 @@ SourceManager::~SourceManager() {}
SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) {
bool same_as_previous =
- m_last_file_sp && m_last_file_sp->FileSpecMatches(file_spec);
+ m_last_file_sp &&
+ FileSpec::Match(file_spec, m_last_file_sp->GetFileSpec());
DebuggerSP debugger_sp(m_debugger_wp.lock());
FileSP file_sp;
@@ -602,10 +603,6 @@ void SourceManager::File::FindLinesMatchingRegex(
}
}
-bool SourceManager::File::FileSpecMatches(const FileSpec &file_spec) {
- return FileSpec::Equal(m_file_spec, file_spec, false);
-}
-
bool lldb_private::operator==(const SourceManager::File &lhs,
const SourceManager::File &rhs) {
if (lhs.m_file_spec != rhs.m_file_spec)
diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index b12e21deb459..154bd25da481 100644
--- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -235,7 +235,7 @@ PlatformPOSIX::PutFile(const lldb_private::FileSpec &source,
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
if (IsHost()) {
- if (FileSpec::Equal(source, destination, true))
+ if (source == destination)
return Status();
// cp src dst
// chown uid:gid dst
@@ -307,7 +307,7 @@ lldb_private::Status PlatformPOSIX::GetFile(
if (dst_path.empty())
return Status("unable to get file path for destination");
if (IsHost()) {
- if (FileSpec::Equal(source, destination, true))
+ if (source == destination)
return Status("local scenario->source and destination are the same file "
"path: no operation performed");
// cp src dst
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 837a475c166c..b8575d13d457 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1950,9 +1950,8 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
if (!dc_cu)
continue;
- const bool full_match = (bool)file_spec.GetDirectory();
bool file_spec_matches_cu_file_spec =
- FileSpec::Equal(file_spec, dc_cu->GetPrimaryFile(), full_match);
+ FileSpec::Match(file_spec, dc_cu->GetPrimaryFile());
if (check_inlines || file_spec_matches_cu_file_spec) {
SymbolContext sc(m_objfile_sp->GetModule());
sc.comp_unit = dc_cu;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index d3090ed3b6f2..cce666a222d0 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -812,12 +812,8 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
if (!resolve) {
FileSpec so_file_spec;
- if (GetFileSpecForSO(i, so_file_spec)) {
- // Match the full path if the incoming file_spec has a directory (not
- // just a basename)
- const bool full_match = (bool)file_spec.GetDirectory();
- resolve = FileSpec::Equal(file_spec, so_file_spec, full_match);
- }
+ if (GetFileSpecForSO(i, so_file_spec))
+ resolve = FileSpec::Match(file_spec, so_file_spec);
}
if (resolve) {
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i);
diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp
index 6aef807f86dc..98cf675fb370 100644
--- a/lldb/source/Symbol/CompileUnit.cpp
+++ b/lldb/source/Symbol/CompileUnit.cpp
@@ -243,9 +243,8 @@ void CompileUnit::ResolveSymbolContext(const FileSpec &file_spec,
// "file_spec" has an empty directory, then only compare the basenames when
// finding file indexes
std::vector<uint32_t> file_indexes;
- const bool full_match = (bool)file_spec.GetDirectory();
bool file_spec_matches_cu_file_spec =
- FileSpec::Equal(file_spec, this->GetPrimaryFile(), full_match);
+ FileSpec::Match(file_spec, this->GetPrimaryFile());
// If we are not looking for inlined functions and our file spec doesn't
// match then we are done...
diff --git a/lldb/source/Symbol/Declaration.cpp b/lldb/source/Symbol/Declaration.cpp
index d78ba967d280..4d0975d34256 100644
--- a/lldb/source/Symbol/Declaration.cpp
+++ b/lldb/source/Symbol/Declaration.cpp
@@ -90,12 +90,9 @@ bool Declaration::FileAndLineEqual(const Declaration &declaration) const {
bool lldb_private::operator==(const Declaration &lhs, const Declaration &rhs) {
#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
- if (lhs.GetColumn() == rhs.GetColumn())
- if (lhs.GetLine() == rhs.GetLine())
- return lhs.GetFile() == rhs.GetFile();
+ if (lhs.GetColumn() != rhs.GetColumn())
+ return false;
#else
- if (lhs.GetLine() == rhs.GetLine())
- return FileSpec::Equal(lhs.GetFile(), rhs.GetFile(), true);
+ return lhs.GetLine() == rhs.GetLine() && lhs.GetFile() == rhs.GetFile();
#endif
- return false;
}
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index 11548c0a5a19..b77c011f8cb8 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -1026,8 +1026,7 @@ bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) {
return false;
} else {
FileSpec module_file_spec(m_module_spec);
- if (!FileSpec::Equal(module_file_spec, sc.module_sp->GetFileSpec(),
- false))
+ if (!FileSpec::Match(module_file_spec, sc.module_sp->GetFileSpec()))
return false;
}
}
@@ -1046,8 +1045,8 @@ bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) {
sc.block->GetInlinedFunctionInfo();
if (inline_info != nullptr) {
was_inlined = true;
- if (!FileSpec::Equal(inline_info->GetDeclaration().GetFile(),
- *(m_file_spec_up.get()), false))
+ if (!FileSpec::Match(*m_file_spec_up,
+ inline_info->GetDeclaration().GetFile()))
return false;
}
}
@@ -1055,8 +1054,7 @@ bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) {
// Next check the comp unit, but only if the SymbolContext was not
// inlined.
if (!was_inlined && sc.comp_unit != nullptr) {
- if (!FileSpec::Equal(sc.comp_unit->GetPrimaryFile(), *m_file_spec_up,
- false))
+ if (!FileSpec::Match(*m_file_spec_up, sc.comp_unit->GetPrimaryFile()))
return false;
}
}
diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp
index ebd02a504d09..1b4db0c2aba5 100644
--- a/lldb/source/Target/TargetList.cpp
+++ b/lldb/source/Target/TargetList.cpp
@@ -457,15 +457,12 @@ TargetSP TargetList::FindTargetWithExecutableAndArchitecture(
const FileSpec &exe_file_spec, const ArchSpec *exe_arch_ptr) const {
std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
TargetSP target_sp;
- bool full_match = (bool)exe_file_spec.GetDirectory();
-
collection::const_iterator pos, end = m_target_list.end();
for (pos = m_target_list.begin(); pos != end; ++pos) {
Module *exe_module = (*pos)->GetExecutableModulePointer();
if (exe_module) {
- if (FileSpec::Equal(exe_file_spec, exe_module->GetFileSpec(),
- full_match)) {
+ if (FileSpec::Match(exe_file_spec, exe_module->GetFileSpec())) {
if (exe_arch_ptr) {
if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture()))
continue;
diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp b/lldb/source/Target/ThreadPlanStepInRange.cpp
index 77772aed516b..fdb2782bc518 100644
--- a/lldb/source/Target/ThreadPlanStepInRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepInRange.cpp
@@ -339,7 +339,7 @@ bool ThreadPlanStepInRange::FrameMatchesAvoidCriteria() {
if (frame_library) {
for (size_t i = 0; i < num_libraries; i++) {
const FileSpec &file_spec(libraries_to_avoid.GetFileSpecAtIndex(i));
- if (FileSpec::Equal(file_spec, frame_library, false)) {
+ if (FileSpec::Match(file_spec, frame_library)) {
libraries_say_avoid = true;
break;
}
diff --git a/lldb/source/Utility/FileSpec.cpp b/lldb/source/Utility/FileSpec.cpp
index 7fb6e9db72c8..de4714282adc 100644
--- a/lldb/source/Utility/FileSpec.cpp
+++ b/lldb/source/Utility/FileSpec.cpp
@@ -308,6 +308,14 @@ bool FileSpec::Equal(const FileSpec &a, const FileSpec &b, bool full) {
return a.FileEquals(b);
}
+bool FileSpec::Match(const FileSpec &pattern, const FileSpec &file) {
+ if (pattern.GetDirectory())
+ return pattern == file;
+ if (pattern.GetFilename())
+ return pattern.FileEquals(file);
+ return true;
+}
+
llvm::Optional<FileSpec::Style> FileSpec::GuessPathStyle(llvm::StringRef absolute_path) {
if (absolute_path.startswith("/"))
return Style::posix;
diff --git a/lldb/unittests/Utility/FileSpecTest.cpp b/lldb/unittests/Utility/FileSpecTest.cpp
index 132c7cb94fad..d5f1091d5d46 100644
--- a/lldb/unittests/Utility/FileSpecTest.cpp
+++ b/lldb/unittests/Utility/FileSpecTest.cpp
@@ -399,3 +399,24 @@ TEST(FileSpecTest, Equal) {
EXPECT_FALSE(Eq("foo", "/bar/foo", true));
EXPECT_TRUE(Eq("foo", "/bar/foo", false));
}
+
+TEST(FileSpecTest, Match) {
+ auto Match = [](const char *pattern, const char *file) {
+ return FileSpec::Match(PosixSpec(pattern), PosixSpec(file));
+ };
+ EXPECT_TRUE(Match("/foo/bar", "/foo/bar"));
+ EXPECT_FALSE(Match("/foo/bar", "/oof/bar"));
+ EXPECT_FALSE(Match("/foo/bar", "/foo/baz"));
+ EXPECT_FALSE(Match("/foo/bar", "bar"));
+ EXPECT_FALSE(Match("/foo/bar", ""));
+
+ EXPECT_TRUE(Match("bar", "/foo/bar"));
+ EXPECT_FALSE(Match("bar", "/foo/baz"));
+ EXPECT_TRUE(Match("bar", "bar"));
+ EXPECT_FALSE(Match("bar", "baz"));
+ EXPECT_FALSE(Match("bar", ""));
+
+ EXPECT_TRUE(Match("", "/foo/bar"));
+ EXPECT_TRUE(Match("", ""));
+
+}
More information about the lldb-commits
mailing list