stigger created this revision.
stigger added a reviewer: zturner.
stigger added a subscriber: lldb-commits.

- File path comparisons should be case-insensitive on OS X 
- Fixed TestBreakpointCaseSensitivity

http://reviews.llvm.org/D20041

Files:
  include/lldb/Host/FileSpec.h
  
packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/TestBreakpointCaseSensitivity.py
  source/Host/common/FileSpec.cpp
  source/Host/common/HostInfoBase.cpp

Index: source/Host/common/HostInfoBase.cpp
===================================================================
--- source/Host/common/HostInfoBase.cpp
+++ source/Host/common/HostInfoBase.cpp
@@ -59,15 +59,15 @@
         ArchSpec m_host_arch_32;
         ArchSpec m_host_arch_64;
 
-        FileSpec m_lldb_so_dir;
-        FileSpec m_lldb_support_exe_dir;
-        FileSpec m_lldb_headers_dir;
-        FileSpec m_lldb_python_dir;
-        FileSpec m_lldb_clang_resource_dir;
-        FileSpec m_lldb_system_plugin_dir;
-        FileSpec m_lldb_user_plugin_dir;
-        FileSpec m_lldb_process_tmp_dir;
-        FileSpec m_lldb_global_tmp_dir;
+        FileSpec m_lldb_so_dir = FileSpec(false);
+        FileSpec m_lldb_support_exe_dir = FileSpec(false);
+        FileSpec m_lldb_headers_dir = FileSpec(false);
+        FileSpec m_lldb_python_dir = FileSpec(false);
+        FileSpec m_lldb_clang_resource_dir = FileSpec(false);
+        FileSpec m_lldb_system_plugin_dir = FileSpec(false);
+        FileSpec m_lldb_user_plugin_dir = FileSpec(false);
+        FileSpec m_lldb_process_tmp_dir = FileSpec(false);
+        FileSpec m_lldb_global_tmp_dir = FileSpec(false);
     };
     
     HostInfoBaseFields *g_fields = nullptr;
Index: source/Host/common/FileSpec.cpp
===================================================================
--- source/Host/common/FileSpec.cpp
+++ source/Host/common/FileSpec.cpp
@@ -36,6 +36,7 @@
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Host/HostInfo.h"
 #include "lldb/Utility/CleanUp.h"
 
 #include "llvm/ADT/StringRef.h"
@@ -304,9 +305,15 @@
 }
 
 FileSpec::FileSpec() : 
+    FileSpec{IsCaseSensitive(ePathSyntaxHostNative)}
+{
+}
+
+FileSpec::FileSpec(bool case_sensitive) :
     m_directory(), 
     m_filename(), 
-    m_syntax(FileSystem::GetNativePathSyntax())
+    m_syntax(FileSystem::GetNativePathSyntax()),
+    m_case_sensitive(case_sensitive)
 {
 }
 
@@ -318,15 +325,17 @@
     m_directory(),
     m_filename(),
     m_is_resolved(false),
-    m_syntax(syntax)
+    m_syntax(syntax),
+    m_case_sensitive(IsCaseSensitive(syntax))
 {
     if (pathname && pathname[0])
-        SetFile(pathname, resolve_path, syntax);
+        SetFile(pathname, resolve_path, m_case_sensitive, syntax);
 }
 
 FileSpec::FileSpec(const char *pathname, bool resolve_path, ArchSpec arch) :
     FileSpec{pathname, resolve_path, arch.GetTriple().isOSWindows() ? ePathSyntaxWindows : ePathSyntaxPosix}
 {
+    m_case_sensitive = IsCaseSensitive(m_syntax, &arch.GetTriple());
 }
 
 FileSpec::FileSpec(const std::string &path, bool resolve_path, PathSyntax syntax) :
@@ -346,7 +355,8 @@
     m_directory (rhs.m_directory),
     m_filename (rhs.m_filename),
     m_is_resolved (rhs.m_is_resolved),
-    m_syntax (rhs.m_syntax)
+    m_syntax (rhs.m_syntax),
+    m_case_sensitive (rhs.m_case_sensitive)
 {
 }
 
@@ -380,6 +390,7 @@
         m_filename = rhs.m_filename;
         m_is_resolved = rhs.m_is_resolved;
         m_syntax = rhs.m_syntax;
+        m_case_sensitive = rhs.m_case_sensitive;
     }
     return *this;
 }
@@ -390,11 +401,12 @@
 // string values for quick comparison and efficient memory usage.
 //------------------------------------------------------------------
 void
-FileSpec::SetFile (const char *pathname, bool resolve, PathSyntax syntax)
+FileSpec::SetFile(const char *pathname, bool resolve, bool case_sensitive, PathSyntax syntax)
 {
     m_filename.Clear();
     m_directory.Clear();
     m_is_resolved = false;
+    m_case_sensitive = case_sensitive;
     m_syntax = (syntax == ePathSyntaxHostNative) ? FileSystem::GetNativePathSyntax() : syntax;
 
     if (pathname == NULL || pathname[0] == '\0')
@@ -431,12 +443,19 @@
 }
 
 void
+FileSpec::SetFile (const char *pathname, bool resolve, PathSyntax syntax, llvm::Triple *triple)
+{
+    return SetFile(pathname, resolve, IsCaseSensitive(syntax, triple), syntax);
+}
+
+void
 FileSpec::SetFile(const char *pathname, bool resolve, ArchSpec arch)
 {
     return SetFile(pathname, resolve,
             arch.GetTriple().isOSWindows()
             ? ePathSyntaxWindows
-            : ePathSyntaxPosix);
+            : ePathSyntaxPosix,
+            &arch.GetTriple());
 }
 
 void
@@ -850,7 +869,7 @@
     if (!GetPath (path_buf, PATH_MAX, false))
         return false;
     // SetFile(...) will set m_is_resolved correctly if it can resolve the path
-    SetFile (path_buf, true);
+    SetFile(path_buf, true, m_case_sensitive, m_syntax);
     return m_is_resolved; 
 }
 
@@ -1507,7 +1526,7 @@
     const bool resolve = false;
     if (m_filename.IsEmpty() && m_directory.IsEmpty())
     {
-        SetFile(new_path, resolve);
+        SetFile(new_path, resolve, m_case_sensitive, m_syntax);
         return;
     }
     StreamString stream;
@@ -1517,7 +1536,7 @@
         stream.Printf("%s/%s", new_path, m_filename.GetCString());
     else
         stream.Printf("%s/%s/%s", new_path, m_directory.GetCString(), m_filename.GetCString());
-    SetFile(stream.GetData(), resolve);
+    SetFile(stream.GetData(), resolve, m_case_sensitive, m_syntax);
 }
 
 void
@@ -1555,7 +1574,7 @@
     stream.PutCString(new_path);
 
     const bool resolve = false;
-    SetFile(stream.GetData(), resolve, m_syntax);
+    SetFile(stream.GetData(), resolve, m_case_sensitive, m_syntax);
 }
 
 void
@@ -1576,12 +1595,12 @@
     const bool resolve = false;
     if (m_filename.IsEmpty() && m_directory.IsEmpty())
     {
-        SetFile("",resolve);
+        SetFile("", resolve, m_case_sensitive, m_syntax);
         return;
     }
     if (m_directory.IsEmpty())
     {
-        SetFile("",resolve);
+        SetFile("", resolve, m_case_sensitive, m_syntax);
         return;
     }
     if (m_filename.IsEmpty())
@@ -1592,20 +1611,20 @@
         // check for obvious cases before doing the full thing
         if (!last_slash_ptr)
         {
-            SetFile("",resolve);
+            SetFile("", resolve, m_case_sensitive, m_syntax);
             return;
         }
         if (last_slash_ptr == dir_cstr)
         {
-            SetFile("/",resolve);
+            SetFile("/", resolve, m_case_sensitive, m_syntax);
             return;
         }        
         size_t last_slash_pos = last_slash_ptr - dir_cstr+1;
         ConstString new_path(dir_cstr,last_slash_pos);
-        SetFile(new_path.GetCString(),resolve);
+        SetFile(new_path.GetCString(), resolve, m_case_sensitive, m_syntax);
     }
     else
-        SetFile(m_directory.GetCString(),resolve);
+        SetFile(m_directory.GetCString(), resolve, m_case_sensitive, m_syntax);
 }
 //------------------------------------------------------------------
 /// Returns true if the filespec represents an implementation source
@@ -1670,3 +1689,25 @@
 {
     return !FileSpec::IsRelative();
 }
+
+bool
+FileSpec::IsCaseSensitive() const
+{
+    return m_case_sensitive;
+}
+
+bool
+FileSpec::IsCaseSensitive(PathSyntax syntax, const llvm::Triple *triple)
+{
+    switch (syntax)
+    {
+        case ePathSyntaxPosix:
+            return triple == nullptr || !triple->isMacOSX();
+        case ePathSyntaxWindows:
+            return false;
+        case ePathSyntaxHostNative:
+            return IsCaseSensitive(FileSystem::GetNativePathSyntax(), &HostInfo::GetArchitecture().GetTriple());
+        default:
+            return true;
+    }
+}
Index: packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/TestBreakpointCaseSensitivity.py
===================================================================
--- packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/TestBreakpointCaseSensitivity.py
+++ packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_case_sensitivity/TestBreakpointCaseSensitivity.py
@@ -18,14 +18,13 @@
         TestBase.setUp(self)
         self.line = line_number('main.c', self.BREAKPOINT_TEXT)
 
-    @skipIf(oslist=no_match(['windows']))  # Skip for non-windows platforms
+    @skipIf(oslist=['linux'])
     def test_breakpoint_matches_file_with_different_case(self):
         """Set breakpoint on file, should match files with different case on Windows"""
         self.build()
         self.case_sensitivity_breakpoint(True)
 
-    @skipIf(oslist=['windows']) # Skip for windows platforms
-    @expectedFailureAll() # Failing for unknown reason on non-Windows platforms.
+    @skipIf(oslist=no_match(['linux']))
     def test_breakpoint_doesnt_match_file_with_different_case(self):
         """Set breakpoint on file, shouldn't match files with different case on POSIX systems"""
         self.build()
@@ -86,15 +85,15 @@
                                                                    lldb.SBFileSpec(file))
         else:    
             breakpoint = self.target.BreakpointCreateByLocation(file, self.line)
-        
-        self.assertEqual(breakpoint and breakpoint.GetNumLocations() == 1,
+
+        self.assertEqual(breakpoint.GetNumLocations() == 1,
                     should_hit,
                     VALID_BREAKPOINT + desc)
 
         # Get the breakpoint location from breakpoint after we verified that,
         # indeed, it has one location.
         location = breakpoint.GetLocationAtIndex(0)
-        self.assertEqual(location and location.IsEnabled(),
+        self.assertEqual(location.IsEnabled(),
                     should_hit,
                     VALID_BREAKPOINT_LOCATION + desc)
         
@@ -108,14 +107,12 @@
             self.assertEqual(len(threads), 1, "There should be a thread stopped at breakpoint" + desc)
             # The hit count for the breakpoint should be 1.
             self.assertEqual(breakpoint.GetHitCount(), 1)
-            
+            # let process finish
+            process.Continue()
         else:
             # check the breakpoint was not hit
             self.assertEqual(lldb.eStateExited, process.GetState())
             self.assertEqual(breakpoint.GetHitCount(), 0)
 
-        # let process finish
-        process.Continue()
-        
         # cleanup
         self.target.BreakpointDelete(breakpoint.GetID())
Index: include/lldb/Host/FileSpec.h
===================================================================
--- include/lldb/Host/FileSpec.h
+++ include/lldb/Host/FileSpec.h
@@ -22,6 +22,8 @@
 #include "lldb/Core/STLUtils.h"
 #include "lldb/Host/TimeValue.h"
 
+#include "llvm/ADT/Triple.h"
+
 namespace lldb_private {
 
 //----------------------------------------------------------------------
@@ -66,6 +68,8 @@
 
     FileSpec();
 
+    explicit FileSpec(bool case_sensitive);
+
     //------------------------------------------------------------------
     /// Constructor with path.
     ///
@@ -274,10 +278,7 @@
     ///		if case insensitive (Windows).
     //------------------------------------------------------------------
     bool
-    IsCaseSensitive() const
-    {
-        return m_syntax != ePathSyntaxWindows;
-    }
+    IsCaseSensitive() const;
 
     //------------------------------------------------------------------
     /// Dump this object to a Stream.
@@ -700,9 +701,18 @@
     /// @param[in] resolve_path
     ///     If \b true, then we will try to resolve links the path using
     ///     the static FileSpec::Resolve.
+    ///
+    /// @param[in] triple
+    ///     If \b provided, then used for a more precise case sensitivity detection.
     //------------------------------------------------------------------
     void
-    SetFile (const char *path, bool resolve_path, PathSyntax syntax = ePathSyntaxHostNative);
+    SetFile (const char *path,
+             bool resolve_path,
+             PathSyntax syntax = ePathSyntaxHostNative,
+             llvm::Triple *triple = nullptr);
+
+    void
+    SetFile(const char *path, bool resolve_path, bool case_sensitive, PathSyntax syntax = ePathSyntaxHostNative);
 
     void
     SetFile(const char *path, bool resolve_path, ArchSpec arch);
@@ -838,6 +848,8 @@
     ForEachItemInDirectory (const char *dir_path, DirectoryCallback const &callback);
 
 protected:
+    static bool
+    IsCaseSensitive(PathSyntax syntax, const llvm::Triple *triple = nullptr);
     //------------------------------------------------------------------
     // Member variables
     //------------------------------------------------------------------
@@ -845,6 +857,7 @@
     ConstString m_filename;     ///< The uniqued filename path
     mutable bool m_is_resolved; ///< True if this path has been resolved.
     PathSyntax m_syntax;        ///< The syntax that this path uses (e.g. Windows / Posix)
+    bool m_case_sensitive;
 };
 
 //----------------------------------------------------------------------
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to