1 //===--------------------- TildeExpressionResolver.cpp ----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Utility/TildeExpressionResolver.h"
11 
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/Support/FileSystem.h"
14 #include "llvm/Support/Path.h"
15 
16 #if !defined(LLVM_ON_WIN32)
17 #include <pwd.h>
18 #endif
19 
20 using namespace lldb_private;
21 using namespace llvm;
22 
23 namespace fs = llvm::sys::fs;
24 namespace path = llvm::sys::path;
25 
26 TildeExpressionResolver::~TildeExpressionResolver() {}
27 
28 bool StandardTildeExpressionResolver::ResolveExact(
29     StringRef Expr, SmallVectorImpl<char> &Output) {
30   // We expect the tilde expression to be ONLY the expression itself, and
31   // contain
32   // no separators.
33   assert(!llvm::any_of(Expr, path::is_separator));
34   assert(Expr.empty() || Expr[0] == '~');
35 
36   return !fs::real_path(Expr, Output, true);
37 }
38 
39 bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr,
40                                                      StringSet<> &Output) {
41   // We expect the tilde expression to be ONLY the expression itself, and
42   // contain no separators.
43   assert(!llvm::any_of(Expr, path::is_separator));
44   assert(Expr.empty() || Expr[0] == '~');
45 
46   Output.clear();
47 #if defined(LLVM_ON_WIN32) || defined(__ANDROID__)
48   return false;
49 #else
50   if (Expr.empty())
51     return false;
52 
53   SmallString<32> Buffer("~");
54   setpwent();
55   struct passwd *user_entry;
56   Expr = Expr.drop_front();
57 
58   while ((user_entry = getpwent()) != NULL) {
59     StringRef ThisName(user_entry->pw_name);
60     if (!ThisName.startswith(Expr))
61       continue;
62 
63     Buffer.resize(1);
64     Buffer.append(ThisName);
65     Buffer.append(path::get_separator());
66     Output.insert(Buffer);
67   }
68 
69   return true;
70 #endif
71 }
72