|  | //===-- TildeExpressionResolver.cpp ---------------------------------------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "lldb/Utility/TildeExpressionResolver.h" | 
|  |  | 
|  | #include <assert.h> | 
|  | #include <system_error> | 
|  |  | 
|  | #include "llvm/ADT/STLExtras.h" | 
|  | #include "llvm/ADT/SmallVector.h" | 
|  | #include "llvm/Support/FileSystem.h" | 
|  | #include "llvm/Support/Path.h" | 
|  | #include "llvm/Support/raw_ostream.h" | 
|  |  | 
|  | #if !defined(_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(_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()) != nullptr) { | 
|  | 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) { | 
|  | if (!Expr.startswith("~")) { | 
|  | Output.assign(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)) { | 
|  | Output.assign(Expr.begin(), Expr.end()); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | Output.append(Expr.begin() + Left.size(), Expr.end()); | 
|  | return true; | 
|  | } |