aboutsummaryrefslogtreecommitdiff
path: root/source/Utility/TildeExpressionResolver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Utility/TildeExpressionResolver.cpp')
-rw-r--r--source/Utility/TildeExpressionResolver.cpp95
1 files changed, 95 insertions, 0 deletions
diff --git a/source/Utility/TildeExpressionResolver.cpp b/source/Utility/TildeExpressionResolver.cpp
new file mode 100644
index 000000000000..64a771118d6e
--- /dev/null
+++ b/source/Utility/TildeExpressionResolver.cpp
@@ -0,0 +1,95 @@
+//===--------------------- TildeExpressionResolver.cpp ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/TildeExpressionResolver.h"
+
+#include <assert.h> // for assert
+#include <system_error> // for error_code
+
+#include "llvm/ADT/STLExtras.h" // for any_of
+#include "llvm/ADT/SmallVector.h" // for SmallVectorImpl
+#include "llvm/Config/llvm-config.h" // for LLVM_ON_WIN32
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h" // for fs
+
+#if !defined(LLVM_ON_WIN32)
+#include <pwd.h>
+#endif
+
+using namespace lldb_private;
+using namespace llvm;
+
+namespace fs = llvm::sys::fs;
+namespace path = llvm::sys::path;
+
+TildeExpressionResolver::~TildeExpressionResolver() {}
+
+bool StandardTildeExpressionResolver::ResolveExact(
+ StringRef Expr, SmallVectorImpl<char> &Output) {
+ // We expect the tilde expression to be ONLY the expression itself, and
+ // contain no separators.
+ assert(!llvm::any_of(Expr, [](char c) { return path::is_separator(c); }));
+ assert(Expr.empty() || Expr[0] == '~');
+
+ return !fs::real_path(Expr, Output, true);
+}
+
+bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr,
+ StringSet<> &Output) {
+ // We expect the tilde expression to be ONLY the expression itself, and
+ // contain no separators.
+ assert(!llvm::any_of(Expr, [](char c) { return path::is_separator(c); }));
+ assert(Expr.empty() || Expr[0] == '~');
+
+ Output.clear();
+#if defined(LLVM_ON_WIN32) || defined(__ANDROID__)
+ return false;
+#else
+ if (Expr.empty())
+ return false;
+
+ SmallString<32> Buffer("~");
+ setpwent();
+ struct passwd *user_entry;
+ Expr = Expr.drop_front();
+
+ while ((user_entry = getpwent()) != NULL) {
+ StringRef ThisName(user_entry->pw_name);
+ if (!ThisName.startswith(Expr))
+ continue;
+
+ Buffer.resize(1);
+ Buffer.append(ThisName);
+ Buffer.append(path::get_separator());
+ Output.insert(Buffer);
+ }
+
+ 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;
+}