[Lldb-commits] [lldb] r298526 - Resubmit "Delete the remainder of platform specific code in FileSpec."

Zachary Turner via lldb-commits lldb-commits at lists.llvm.org
Wed Mar 22 10:33:23 PDT 2017


Author: zturner
Date: Wed Mar 22 12:33:23 2017
New Revision: 298526

URL: http://llvm.org/viewvc/llvm-project?rev=298526&view=rev
Log:
Resubmit "Delete the remainder of platform specific code in FileSpec."

This was causing a test failure in one of LLDB's tests which
specifically dealt with a limitation in LLVM's implementation
of home_directory() that LLDB's own implementation had worked
around.

This limitation has been addressed in r298513 on the LLVM side,
so the failing test (which is now unnecessary as the limitation
no longer exists) was removed in r298519, allowing this patch to
be re-submitted without modification.

Added:
    lldb/trunk/unittests/Utility/Mocks/CMakeLists.txt
    lldb/trunk/unittests/Utility/Mocks/MockTildeExpressionResolver.cpp
    lldb/trunk/unittests/Utility/Mocks/MockTildeExpressionResolver.h
    lldb/trunk/unittests/Utility/TildeExpressionResolverTest.cpp
Modified:
    lldb/trunk/include/lldb/Host/FileSpec.h
    lldb/trunk/include/lldb/Utility/TildeExpressionResolver.h
    lldb/trunk/source/API/SBDeclaration.cpp
    lldb/trunk/source/API/SBFileSpec.cpp
    lldb/trunk/source/API/SBFileSpecList.cpp
    lldb/trunk/source/API/SBLineEntry.cpp
    lldb/trunk/source/Host/common/FileSpec.cpp
    lldb/trunk/source/Host/windows/FileSystem.cpp
    lldb/trunk/source/Host/windows/HostInfoWindows.cpp
    lldb/trunk/source/Target/TargetList.cpp
    lldb/trunk/source/Utility/TildeExpressionResolver.cpp
    lldb/trunk/unittests/CMakeLists.txt
    lldb/trunk/unittests/Interpreter/CMakeLists.txt
    lldb/trunk/unittests/Interpreter/TestCompletion.cpp
    lldb/trunk/unittests/Utility/CMakeLists.txt

Modified: lldb/trunk/include/lldb/Host/FileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/FileSpec.h?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/FileSpec.h (original)
+++ lldb/trunk/include/lldb/Host/FileSpec.h Wed Mar 22 12:33:23 2017
@@ -17,7 +17,6 @@
 
 // Other libraries and framework includes
 // Project includes
-#include "lldb/Host/PosixApi.h"
 #include "lldb/Utility/ConstString.h"
 #include "lldb/lldb-private.h"
 
@@ -539,26 +538,6 @@ public:
 
   ConstString GetLastPathComponent() const;
 
-  //------------------------------------------------------------------
-  /// Resolves the user name at the beginning of \a src_path, and writes the
-  /// output
-  /// to \a dst_path.  Note, \a src_path can contain other path components after
-  /// the
-  /// user name, they will be copied over, and if the path doesn't start with
-  /// "~" it
-  /// will also be copied over to \a dst_path.
-  ///
-  /// @param[in] src_path
-  ///     Input path to be resolved.
-  ///
-  /// @param[in] dst_path
-  ///     Buffer to store the resolved path.
-  //------------------------------------------------------------------
-  static void ResolveUsername(llvm::SmallVectorImpl<char> &path);
-
-  static size_t ResolvePartialUsername(llvm::StringRef partial_name,
-                                       StringList &matches);
-
   enum EnumerateDirectoryResult {
     eEnumerateDirectoryResultNext,  // Enumerate next entry in the current
                                     // directory

Modified: lldb/trunk/include/lldb/Utility/TildeExpressionResolver.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/TildeExpressionResolver.h?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/TildeExpressionResolver.h (original)
+++ lldb/trunk/include/lldb/Utility/TildeExpressionResolver.h Wed Mar 22 12:33:23 2017
@@ -44,6 +44,11 @@ public:
   /// \returns true if there were any matches, false otherwise.
   virtual bool ResolvePartial(llvm::StringRef Expr,
                               llvm::StringSet<> &Output) = 0;
+
+  /// \brief Resolve an entire path that begins with a tilde expression,
+  /// replacing the username portion with the matched result.
+  bool ResolveFullPath(llvm::StringRef Expr,
+                       llvm::SmallVectorImpl<char> &Output);
 };
 
 class StandardTildeExpressionResolver : public TildeExpressionResolver {

Modified: lldb/trunk/source/API/SBDeclaration.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDeclaration.cpp?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/source/API/SBDeclaration.cpp (original)
+++ lldb/trunk/source/API/SBDeclaration.cpp Wed Mar 22 12:33:23 2017
@@ -1,5 +1,4 @@
-//===-- SBDeclaration.cpp -----------------------------------------*- C++
-//-*-===//
+//===-- SBDeclaration.cpp ----------------------------------------*- C++-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -10,6 +9,7 @@
 
 #include "lldb/API/SBDeclaration.h"
 #include "lldb/API/SBStream.h"
+#include "lldb/Host/PosixApi.h"
 #include "lldb/Symbol/Declaration.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Stream.h"

Modified: lldb/trunk/source/API/SBFileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFileSpec.cpp?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/source/API/SBFileSpec.cpp (original)
+++ lldb/trunk/source/API/SBFileSpec.cpp Wed Mar 22 12:33:23 2017
@@ -13,6 +13,7 @@
 #include "lldb/API/SBFileSpec.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/Host/FileSpec.h"
+#include "lldb/Host/PosixApi.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Stream.h"
 

Modified: lldb/trunk/source/API/SBFileSpecList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFileSpecList.cpp?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/source/API/SBFileSpecList.cpp (original)
+++ lldb/trunk/source/API/SBFileSpecList.cpp Wed Mar 22 12:33:23 2017
@@ -14,6 +14,7 @@
 #include "lldb/API/SBStream.h"
 #include "lldb/Core/FileSpecList.h"
 #include "lldb/Host/FileSpec.h"
+#include "lldb/Host/PosixApi.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Stream.h"
 

Modified: lldb/trunk/source/API/SBLineEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBLineEntry.cpp?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/source/API/SBLineEntry.cpp (original)
+++ lldb/trunk/source/API/SBLineEntry.cpp Wed Mar 22 12:33:23 2017
@@ -11,6 +11,7 @@
 
 #include "lldb/API/SBLineEntry.h"
 #include "lldb/API/SBStream.h"
+#include "lldb/Host/PosixApi.h"
 #include "lldb/Symbol/LineEntry.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/StreamString.h"

Modified: lldb/trunk/source/Host/common/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/FileSpec.cpp (original)
+++ lldb/trunk/source/Host/common/FileSpec.cpp Wed Mar 22 12:33:23 2017
@@ -7,21 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <fstream>
-#include <set>
-#include <string.h>
-
-#include "llvm/Config/llvm-config.h"
-#ifndef LLVM_ON_WIN32
-#include <pwd.h>
-#endif
-
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Utility/CleanUp.h"
 #include "lldb/Utility/RegularExpression.h"
 #include "lldb/Utility/Stream.h"
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/StringList.h"
+#include "lldb/Utility/TildeExpressionResolver.h"
 
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
@@ -144,115 +136,13 @@ size_t ParentPathEnd(llvm::StringRef pat
 
 } // end anonymous namespace
 
-// Resolves the username part of a path of the form ~user/other/directories, and
-// writes the result into dst_path.  This will also resolve "~" to the current
-// user.
-// If you want to complete "~" to the list of users, pass it to
-// ResolvePartialUsername.
-void FileSpec::ResolveUsername(llvm::SmallVectorImpl<char> &path) {
-#ifndef LLVM_ON_WIN32
-  if (path.empty() || path[0] != '~')
-    return;
-
-  llvm::StringRef path_str(path.data(), path.size());
-  size_t slash_pos = path_str.find('/', 1);
-  if (slash_pos == 1 || path.size() == 1) {
-    // A path of ~/ resolves to the current user's home dir
-    llvm::SmallString<64> home_dir;
-    // llvm::sys::path::home_directory() only checks if "HOME" is set in the
-    // environment and does nothing else to locate the user home directory
-    if (!llvm::sys::path::home_directory(home_dir)) {
-      struct passwd *pw = getpwuid(getuid());
-      if (pw && pw->pw_dir && pw->pw_dir[0]) {
-        // Update our environemnt so llvm::sys::path::home_directory() works
-        // next time
-        setenv("HOME", pw->pw_dir, 0);
-        home_dir.assign(llvm::StringRef(pw->pw_dir));
-      } else {
-        return;
-      }
-    }
-
-    // Overwrite the ~ with the first character of the homedir, and insert
-    // the rest.  This way we only trigger one move, whereas an insert
-    // followed by a delete (or vice versa) would trigger two.
-    path[0] = home_dir[0];
-    path.insert(path.begin() + 1, home_dir.begin() + 1, home_dir.end());
-    return;
-  }
-
-  auto username_begin = path.begin() + 1;
-  auto username_end = (slash_pos == llvm::StringRef::npos)
-                          ? path.end()
-                          : (path.begin() + slash_pos);
-  size_t replacement_length = std::distance(path.begin(), username_end);
-
-  llvm::SmallString<20> username(username_begin, username_end);
-  struct passwd *user_entry = ::getpwnam(username.c_str());
-  if (user_entry != nullptr) {
-    // Copy over the first n characters of the path, where n is the smaller of
-    // the length
-    // of the home directory and the slash pos.
-    llvm::StringRef homedir(user_entry->pw_dir);
-    size_t initial_copy_length = std::min(homedir.size(), replacement_length);
-    auto src_begin = homedir.begin();
-    auto src_end = src_begin + initial_copy_length;
-    std::copy(src_begin, src_end, path.begin());
-    if (replacement_length > homedir.size()) {
-      // We copied the entire home directory, but the ~username portion of the
-      // path was
-      // longer, so there's characters that need to be removed.
-      path.erase(path.begin() + initial_copy_length, username_end);
-    } else if (replacement_length < homedir.size()) {
-      // We copied all the way up to the slash in the destination, but there's
-      // still more
-      // characters that need to be inserted.
-      path.insert(username_end, src_end, homedir.end());
-    }
-  } else {
-    // Unable to resolve username (user doesn't exist?)
-    path.clear();
-  }
-#endif
-}
-
-size_t FileSpec::ResolvePartialUsername(llvm::StringRef partial_name,
-                                        StringList &matches) {
-#if !defined(LLVM_ON_WIN32) && !defined(__ANDROID__)
-  size_t extant_entries = matches.GetSize();
-
-  setpwent();
-  struct passwd *user_entry;
-  partial_name = partial_name.drop_front();
-  std::set<std::string> name_list;
-
-  while ((user_entry = getpwent()) != NULL) {
-    if (llvm::StringRef(user_entry->pw_name).startswith(partial_name)) {
-      std::string tmp_buf("~");
-      tmp_buf.append(user_entry->pw_name);
-      tmp_buf.push_back('/');
-      name_list.insert(tmp_buf);
-    }
-  }
-
-  for (auto &name : name_list) {
-    matches.AppendString(name);
-  }
-  return matches.GetSize() - extant_entries;
-#else
-  // Resolving home directories is not supported, just copy the path...
-  return 0;
-#endif // #ifdef LLVM_ON_WIN32
-}
-
 void FileSpec::Resolve(llvm::SmallVectorImpl<char> &path) {
   if (path.empty())
     return;
 
-#ifndef LLVM_ON_WIN32
-  if (path[0] == '~')
-    ResolveUsername(path);
-#endif // #ifdef LLVM_ON_WIN32
+  llvm::SmallString<32> Source(path.begin(), path.end());
+  StandardTildeExpressionResolver Resolver;
+  Resolver.ResolveFullPath(Source, path);
 
   // Save a copy of the original path that's passed in
   llvm::SmallString<128> original_path(path.begin(), path.end());

Modified: lldb/trunk/source/Host/windows/FileSystem.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/FileSystem.cpp?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/source/Host/windows/FileSystem.cpp (original)
+++ lldb/trunk/source/Host/windows/FileSystem.cpp Wed Mar 22 12:33:23 2017
@@ -15,6 +15,7 @@
 
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/windows/AutoHandle.h"
+#include "lldb/Host/windows/PosixApi.h"
 
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/FileSystem.h"

Modified: lldb/trunk/source/Host/windows/HostInfoWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/HostInfoWindows.cpp?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/source/Host/windows/HostInfoWindows.cpp (original)
+++ lldb/trunk/source/Host/windows/HostInfoWindows.cpp Wed Mar 22 12:33:23 2017
@@ -14,6 +14,7 @@
 #include <mutex> // std::once
 
 #include "lldb/Host/windows/HostInfoWindows.h"
+#include "lldb/Host/windows/PosixApi.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/FileSystem.h"

Modified: lldb/trunk/source/Target/TargetList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/TargetList.cpp?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/source/Target/TargetList.cpp (original)
+++ lldb/trunk/source/Target/TargetList.cpp Wed Mar 22 12:33:23 2017
@@ -23,6 +23,7 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Utility/TildeExpressionResolver.h"
 
 // Other libraries and framework includes
 #include "llvm/ADT/SmallString.h"
@@ -347,10 +348,10 @@ Error TargetList::CreateTargetInternal(D
   FileSpec file(user_exe_path, false);
   if (!file.Exists() && user_exe_path.startswith("~")) {
     // we want to expand the tilde but we don't want to resolve any symbolic
-    // links
-    // so we can't use the FileSpec constructor's resolve flag
-    llvm::SmallString<64> unglobbed_path(user_exe_path);
-    FileSpec::ResolveUsername(unglobbed_path);
+    // links so we can't use the FileSpec constructor's resolve flag
+    llvm::SmallString<64> unglobbed_path;
+    StandardTildeExpressionResolver Resolver;
+    Resolver.ResolveFullPath(user_exe_path, unglobbed_path);
 
     if (unglobbed_path.empty())
       file = FileSpec(user_exe_path, false);

Modified: lldb/trunk/source/Utility/TildeExpressionResolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/TildeExpressionResolver.cpp?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/source/Utility/TildeExpressionResolver.cpp (original)
+++ lldb/trunk/source/Utility/TildeExpressionResolver.cpp Wed Mar 22 12:33:23 2017
@@ -68,3 +68,22 @@ bool StandardTildeExpressionResolver::Re
   return true;
 #endif
 }
+
+bool TildeExpressionResolver::ResolveFullPath(
+    StringRef Expr, llvm::SmallVectorImpl<char> &Output) {
+  Output.clear();
+  if (!Expr.startswith("~")) {
+    Output.append(Expr.begin(), Expr.end());
+    return false;
+  }
+
+  namespace path = llvm::sys::path;
+  StringRef Left =
+      Expr.take_until([](char c) { return path::is_separator(c); });
+
+  if (!ResolveExact(Left, Output))
+    return false;
+
+  Output.append(Expr.begin() + Left.size(), Expr.end());
+  return true;
+}

Modified: lldb/trunk/unittests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/CMakeLists.txt?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/unittests/CMakeLists.txt (original)
+++ lldb/trunk/unittests/CMakeLists.txt Wed Mar 22 12:33:23 2017
@@ -2,6 +2,7 @@ add_custom_target(LLDBUnitTests)
 set_target_properties(LLDBUnitTests PROPERTIES FOLDER "LLDB tests")
 
 include_directories(${LLDB_SOURCE_ROOT})
+include_directories(${LLDB_PROJECT_ROOT})
 
 set(LLDB_GTEST_COMMON_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/gtest_common.h)
 if (MSVC)

Modified: lldb/trunk/unittests/Interpreter/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Interpreter/CMakeLists.txt?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/unittests/Interpreter/CMakeLists.txt (original)
+++ lldb/trunk/unittests/Interpreter/CMakeLists.txt Wed Mar 22 12:33:23 2017
@@ -4,6 +4,7 @@ add_lldb_unittest(InterpreterTests
 
   LINK_LIBS
     lldbInterpreter
+    lldbUtilityMocks
   )
 
 target_link_libraries(InterpreterTests

Modified: lldb/trunk/unittests/Interpreter/TestCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Interpreter/TestCompletion.cpp?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/unittests/Interpreter/TestCompletion.cpp (original)
+++ lldb/trunk/unittests/Interpreter/TestCompletion.cpp Wed Mar 22 12:33:23 2017
@@ -8,7 +8,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "gtest/gtest.h"
-
 #include "lldb/Interpreter/CommandCompletions.h"
 #include "lldb/Utility/StringList.h"
 #include "lldb/Utility/TildeExpressionResolver.h"
@@ -18,6 +17,8 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 
+#include "unittests/Utility/Mocks/MockTildeExpressionResolver.h"
+
 namespace fs = llvm::sys::fs;
 namespace path = llvm::sys::path;
 using namespace llvm;
@@ -36,74 +37,6 @@ using namespace lldb_private;
 
 namespace {
 
-class MockTildeExpressionResolver : public TildeExpressionResolver {
-  StringRef CurrentUser;
-  StringMap<StringRef> UserDirectories;
-
-public:
-  explicit MockTildeExpressionResolver(StringRef CurrentUser, StringRef HomeDir)
-      : CurrentUser(CurrentUser) {
-    UserDirectories.insert(std::make_pair(CurrentUser, HomeDir));
-  }
-
-  void AddKnownUser(StringRef User, StringRef HomeDir) {
-    assert(UserDirectories.find(User) == UserDirectories.end());
-    UserDirectories.insert(std::make_pair(User, HomeDir));
-  }
-
-  void Clear() {
-    CurrentUser = StringRef();
-    UserDirectories.clear();
-  }
-
-  void SetCurrentUser(StringRef User) {
-    assert(UserDirectories.find(User) != UserDirectories.end());
-    CurrentUser = User;
-  }
-
-  bool ResolveExact(StringRef Expr, SmallVectorImpl<char> &Output) override {
-    Output.clear();
-
-    assert(!llvm::any_of(
-        Expr, [](char c) { return llvm::sys::path::is_separator(c); }));
-    assert(Expr.empty() || Expr[0] == '~');
-    Expr = Expr.drop_front();
-    if (Expr.empty()) {
-      auto Dir = UserDirectories[CurrentUser];
-      Output.append(Dir.begin(), Dir.end());
-      return true;
-    }
-
-    for (const auto &User : UserDirectories) {
-      if (User.getKey() != Expr)
-        continue;
-      Output.append(User.getValue().begin(), User.getValue().end());
-      return true;
-    }
-    return false;
-  }
-
-  bool ResolvePartial(StringRef Expr, StringSet<> &Output) override {
-    Output.clear();
-
-    assert(!llvm::any_of(
-        Expr, [](char c) { return llvm::sys::path::is_separator(c); }));
-    assert(Expr.empty() || Expr[0] == '~');
-    Expr = Expr.drop_front();
-
-    SmallString<16> QualifiedName("~");
-    for (const auto &User : UserDirectories) {
-      if (!User.getKey().startswith(Expr))
-        continue;
-      QualifiedName.resize(1);
-      QualifiedName.append(User.getKey().begin(), User.getKey().end());
-      Output.insert(QualifiedName);
-    }
-
-    return !Output.empty();
-  }
-};
-
 class CompletionTest : public testing::Test {
 protected:
   /// Unique temporary directory in which all created filesystem entities must

Modified: lldb/trunk/unittests/Utility/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Utility/CMakeLists.txt?rev=298526&r1=298525&r2=298526&view=diff
==============================================================================
--- lldb/trunk/unittests/Utility/CMakeLists.txt (original)
+++ lldb/trunk/unittests/Utility/CMakeLists.txt Wed Mar 22 12:33:23 2017
@@ -1,3 +1,5 @@
+add_subdirectory(Mocks)
+
 add_lldb_unittest(UtilityTests
   ConstStringTest.cpp
   ErrorTest.cpp
@@ -5,12 +7,14 @@ add_lldb_unittest(UtilityTests
   NameMatchesTest.cpp
   StringExtractorTest.cpp
   TaskPoolTest.cpp
+  TildeExpressionResolverTest.cpp
   TimeoutTest.cpp
   UriParserTest.cpp
   VASprintfTest.cpp
 
   LINK_LIBS
       lldbUtility
+      lldbUtilityMocks
   LINK_COMPONENTS
     Support
   )

Added: lldb/trunk/unittests/Utility/Mocks/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Utility/Mocks/CMakeLists.txt?rev=298526&view=auto
==============================================================================
--- lldb/trunk/unittests/Utility/Mocks/CMakeLists.txt (added)
+++ lldb/trunk/unittests/Utility/Mocks/CMakeLists.txt Wed Mar 22 12:33:23 2017
@@ -0,0 +1,9 @@
+add_lldb_library(lldbUtilityMocks
+  MockTildeExpressionResolver.cpp
+
+  LINK_LIBS
+    lldbUtility
+
+  LINK_COMPONENTS
+    Support
+  )

Added: lldb/trunk/unittests/Utility/Mocks/MockTildeExpressionResolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Utility/Mocks/MockTildeExpressionResolver.cpp?rev=298526&view=auto
==============================================================================
--- lldb/trunk/unittests/Utility/Mocks/MockTildeExpressionResolver.cpp (added)
+++ lldb/trunk/unittests/Utility/Mocks/MockTildeExpressionResolver.cpp Wed Mar 22 12:33:23 2017
@@ -0,0 +1,80 @@
+//===----------------- MockTildeExpressionResolver.cpp ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MockTildeExpressionResolver.h"
+#include "llvm/Support/Path.h"
+
+using namespace lldb_private;
+using namespace llvm;
+
+MockTildeExpressionResolver::MockTildeExpressionResolver(StringRef CurrentUser,
+                                                         StringRef HomeDir)
+    : CurrentUser(CurrentUser) {
+  UserDirectories.insert(std::make_pair(CurrentUser, HomeDir));
+}
+
+void MockTildeExpressionResolver::AddKnownUser(StringRef User,
+                                               StringRef HomeDir) {
+  assert(UserDirectories.find(User) == UserDirectories.end());
+  UserDirectories.insert(std::make_pair(User, HomeDir));
+}
+
+void MockTildeExpressionResolver::Clear() {
+  CurrentUser = StringRef();
+  UserDirectories.clear();
+}
+
+void MockTildeExpressionResolver::SetCurrentUser(StringRef User) {
+  assert(UserDirectories.find(User) != UserDirectories.end());
+  CurrentUser = User;
+}
+
+bool MockTildeExpressionResolver::ResolveExact(StringRef Expr,
+                                               SmallVectorImpl<char> &Output) {
+  Output.clear();
+
+  assert(!llvm::any_of(
+      Expr, [](char c) { return llvm::sys::path::is_separator(c); }));
+  assert(Expr.empty() || Expr[0] == '~');
+  Expr = Expr.drop_front();
+  if (Expr.empty()) {
+    auto Dir = UserDirectories[CurrentUser];
+    Output.append(Dir.begin(), Dir.end());
+    return true;
+  }
+
+  for (const auto &User : UserDirectories) {
+    if (User.getKey() != Expr)
+      continue;
+    Output.append(User.getValue().begin(), User.getValue().end());
+    return true;
+  }
+  return false;
+}
+
+bool MockTildeExpressionResolver::ResolvePartial(StringRef Expr,
+                                                 StringSet<> &Output) {
+  Output.clear();
+
+  assert(!llvm::any_of(
+      Expr, [](char c) { return llvm::sys::path::is_separator(c); }));
+  assert(Expr.empty() || Expr[0] == '~');
+  Expr = Expr.drop_front();
+
+  SmallString<16> QualifiedName("~");
+  for (const auto &User : UserDirectories) {
+    if (!User.getKey().startswith(Expr))
+      continue;
+    QualifiedName.resize(1);
+    QualifiedName.append(User.getKey().begin(), User.getKey().end());
+    Output.insert(QualifiedName);
+  }
+
+  return !Output.empty();
+}

Added: lldb/trunk/unittests/Utility/Mocks/MockTildeExpressionResolver.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Utility/Mocks/MockTildeExpressionResolver.h?rev=298526&view=auto
==============================================================================
--- lldb/trunk/unittests/Utility/Mocks/MockTildeExpressionResolver.h (added)
+++ lldb/trunk/unittests/Utility/Mocks/MockTildeExpressionResolver.h Wed Mar 22 12:33:23 2017
@@ -0,0 +1,37 @@
+//===--------------------- TildeExpressionResolver.h ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_UNITTESTS_UTILITY_MOCKS_MOCK_TILDE_EXPRESSION_RESOLVER_H
+#define LLDB_UNITTESTS_UTILITY_MOCKS_MOCK_TILDE_EXPRESSION_RESOLVER_H
+
+#include "lldb/Utility/TildeExpressionResolver.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+
+namespace lldb_private {
+class MockTildeExpressionResolver : public TildeExpressionResolver {
+  llvm::StringRef CurrentUser;
+  llvm::StringMap<llvm::StringRef> UserDirectories;
+
+public:
+  MockTildeExpressionResolver(llvm::StringRef CurrentUser,
+                              llvm::StringRef HomeDir);
+
+  void AddKnownUser(llvm::StringRef User, llvm::StringRef HomeDir);
+  void Clear();
+  void SetCurrentUser(llvm::StringRef User);
+
+  bool ResolveExact(llvm::StringRef Expr,
+                    llvm::SmallVectorImpl<char> &Output) override;
+  bool ResolvePartial(llvm::StringRef Expr, llvm::StringSet<> &Output) override;
+};
+}
+
+#endif

Added: lldb/trunk/unittests/Utility/TildeExpressionResolverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Utility/TildeExpressionResolverTest.cpp?rev=298526&view=auto
==============================================================================
--- lldb/trunk/unittests/Utility/TildeExpressionResolverTest.cpp (added)
+++ lldb/trunk/unittests/Utility/TildeExpressionResolverTest.cpp Wed Mar 22 12:33:23 2017
@@ -0,0 +1,36 @@
+#include "gtest/gtest.h"
+
+#include "Mocks/MockTildeExpressionResolver.h"
+#include "lldb/Utility/TildeExpressionResolver.h"
+
+#include "llvm/ADT/SmallString.h"
+
+using namespace llvm;
+using namespace lldb_private;
+
+TEST(TildeExpressionResolver, ResolveFullPath) {
+  MockTildeExpressionResolver Resolver("James", "/james");
+  Resolver.AddKnownUser("Kirk", "/kirk");
+  Resolver.AddKnownUser("Lars", "/lars");
+  Resolver.AddKnownUser("Jason", "/jason");
+  Resolver.AddKnownUser("Larry", "/larry");
+
+  SmallString<32> Result;
+  ASSERT_TRUE(Resolver.ResolveFullPath("~", Result));
+  EXPECT_EQ("/james", Result);
+  ASSERT_TRUE(Resolver.ResolveFullPath("~/", Result));
+  EXPECT_EQ("/james/", Result);
+
+  ASSERT_TRUE(Resolver.ResolveFullPath("~James/bar/baz", Result));
+  EXPECT_EQ("/james/bar/baz", Result);
+
+  ASSERT_TRUE(Resolver.ResolveFullPath("~Jason/", Result));
+  EXPECT_EQ("/jason/", Result);
+
+  ASSERT_TRUE(Resolver.ResolveFullPath("~Lars", Result));
+  EXPECT_EQ("/lars", Result);
+
+  ASSERT_FALSE(Resolver.ResolveFullPath("~Jaso", Result));
+  ASSERT_FALSE(Resolver.ResolveFullPath("", Result));
+  ASSERT_FALSE(Resolver.ResolveFullPath("Jason", Result));
+}




More information about the lldb-commits mailing list