1 //===--------------------- TildeExpressionResolver.cpp ----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Utility/TildeExpressionResolver.h"
12 #include <assert.h> // for assert
13 #include <system_error> // for error_code
15 #include "llvm/ADT/STLExtras.h" // for any_of
16 #include "llvm/ADT/SmallVector.h" // for SmallVectorImpl
17 #include "llvm/Config/llvm-config.h" // for LLVM_ON_WIN32
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/raw_ostream.h" // for fs
22 #if !defined(LLVM_ON_WIN32)
26 using namespace lldb_private;
29 namespace fs = llvm::sys::fs;
30 namespace path = llvm::sys::path;
32 TildeExpressionResolver::~TildeExpressionResolver() {}
34 bool StandardTildeExpressionResolver::ResolveExact(
35 StringRef Expr, SmallVectorImpl<char> &Output) {
36 // We expect the tilde expression to be ONLY the expression itself, and
37 // contain no separators.
38 assert(!llvm::any_of(Expr, [](char c) { return path::is_separator(c); }));
39 assert(Expr.empty() || Expr[0] == '~');
41 return !fs::real_path(Expr, Output, true);
44 bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr,
45 StringSet<> &Output) {
46 // We expect the tilde expression to be ONLY the expression itself, and
47 // contain no separators.
48 assert(!llvm::any_of(Expr, [](char c) { return path::is_separator(c); }));
49 assert(Expr.empty() || Expr[0] == '~');
52 #if defined(LLVM_ON_WIN32) || defined(__ANDROID__)
58 SmallString<32> Buffer("~");
60 struct passwd *user_entry;
61 Expr = Expr.drop_front();
63 while ((user_entry = getpwent()) != NULL) {
64 StringRef ThisName(user_entry->pw_name);
65 if (!ThisName.startswith(Expr))
69 Buffer.append(ThisName);
70 Buffer.append(path::get_separator());
71 Output.insert(Buffer);
78 bool TildeExpressionResolver::ResolveFullPath(
79 StringRef Expr, llvm::SmallVectorImpl<char> &Output) {
81 if (!Expr.startswith("~")) {
82 Output.append(Expr.begin(), Expr.end());
86 namespace path = llvm::sys::path;
88 Expr.take_until([](char c) { return path::is_separator(c); });
90 if (!ResolveExact(Left, Output))
93 Output.append(Expr.begin() + Left.size(), Expr.end());