]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Utility/TildeExpressionResolver.cpp
MFV r323794: 8605 zfs channel programs: zfs.exists undocumented and non-working
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Utility / TildeExpressionResolver.cpp
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 <assert.h>     // for assert
13 #include <system_error> // for error_code
14
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
21
22 #if !defined(LLVM_ON_WIN32)
23 #include <pwd.h>
24 #endif
25
26 using namespace lldb_private;
27 using namespace llvm;
28
29 namespace fs = llvm::sys::fs;
30 namespace path = llvm::sys::path;
31
32 TildeExpressionResolver::~TildeExpressionResolver() {}
33
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] == '~');
40
41   return !fs::real_path(Expr, Output, true);
42 }
43
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] == '~');
50
51   Output.clear();
52 #if defined(LLVM_ON_WIN32) || defined(__ANDROID__)
53   return false;
54 #else
55   if (Expr.empty())
56     return false;
57
58   SmallString<32> Buffer("~");
59   setpwent();
60   struct passwd *user_entry;
61   Expr = Expr.drop_front();
62
63   while ((user_entry = getpwent()) != NULL) {
64     StringRef ThisName(user_entry->pw_name);
65     if (!ThisName.startswith(Expr))
66       continue;
67
68     Buffer.resize(1);
69     Buffer.append(ThisName);
70     Buffer.append(path::get_separator());
71     Output.insert(Buffer);
72   }
73
74   return true;
75 #endif
76 }
77
78 bool TildeExpressionResolver::ResolveFullPath(
79     StringRef Expr, llvm::SmallVectorImpl<char> &Output) {
80   Output.clear();
81   if (!Expr.startswith("~")) {
82     Output.append(Expr.begin(), Expr.end());
83     return false;
84   }
85
86   namespace path = llvm::sys::path;
87   StringRef Left =
88       Expr.take_until([](char c) { return path::is_separator(c); });
89
90   if (!ResolveExact(Left, Output))
91     return false;
92
93   Output.append(Expr.begin() + Left.size(), Expr.end());
94   return true;
95 }