]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Utility / TildeExpressionResolver.cpp
1 //===--------------------- TildeExpressionResolver.cpp ----------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Utility/TildeExpressionResolver.h"
10
11 #include <assert.h>
12 #include <system_error>
13
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/Support/FileSystem.h"
17 #include "llvm/Support/Path.h"
18 #include "llvm/Support/raw_ostream.h"
19
20 #if !defined(_WIN32)
21 #include <pwd.h>
22 #endif
23
24 using namespace lldb_private;
25 using namespace llvm;
26
27 namespace fs = llvm::sys::fs;
28 namespace path = llvm::sys::path;
29
30 TildeExpressionResolver::~TildeExpressionResolver() {}
31
32 bool StandardTildeExpressionResolver::ResolveExact(
33     StringRef Expr, SmallVectorImpl<char> &Output) {
34   // We expect the tilde expression to be ONLY the expression itself, and
35   // contain no separators.
36   assert(!llvm::any_of(Expr, [](char c) { return path::is_separator(c); }));
37   assert(Expr.empty() || Expr[0] == '~');
38
39   return !fs::real_path(Expr, Output, true);
40 }
41
42 bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr,
43                                                      StringSet<> &Output) {
44   // We expect the tilde expression to be ONLY the expression itself, and
45   // contain no separators.
46   assert(!llvm::any_of(Expr, [](char c) { return path::is_separator(c); }));
47   assert(Expr.empty() || Expr[0] == '~');
48
49   Output.clear();
50 #if defined(_WIN32) || defined(__ANDROID__)
51   return false;
52 #else
53   if (Expr.empty())
54     return false;
55
56   SmallString<32> Buffer("~");
57   setpwent();
58   struct passwd *user_entry;
59   Expr = Expr.drop_front();
60
61   while ((user_entry = getpwent()) != nullptr) {
62     StringRef ThisName(user_entry->pw_name);
63     if (!ThisName.startswith(Expr))
64       continue;
65
66     Buffer.resize(1);
67     Buffer.append(ThisName);
68     Buffer.append(path::get_separator());
69     Output.insert(Buffer);
70   }
71
72   return true;
73 #endif
74 }
75
76 bool TildeExpressionResolver::ResolveFullPath(
77     StringRef Expr, llvm::SmallVectorImpl<char> &Output) {
78   Output.clear();
79   if (!Expr.startswith("~")) {
80     Output.append(Expr.begin(), Expr.end());
81     return false;
82   }
83
84   namespace path = llvm::sys::path;
85   StringRef Left =
86       Expr.take_until([](char c) { return path::is_separator(c); });
87
88   if (!ResolveExact(Left, Output))
89     return false;
90
91   Output.append(Expr.begin() + Left.size(), Expr.end());
92   return true;
93 }