180814287SRaphael Isemann //===-- TildeExpressionResolver.cpp ---------------------------------------===// 22cc5a18dSZachary Turner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62cc5a18dSZachary Turner // 72cc5a18dSZachary Turner //===----------------------------------------------------------------------===// 82cc5a18dSZachary Turner 92cc5a18dSZachary Turner #include "lldb/Utility/TildeExpressionResolver.h" 102cc5a18dSZachary Turner 11672d2c12SJonas Devlieghere #include <assert.h> 12672d2c12SJonas Devlieghere #include <system_error> 134479ac15SZachary Turner 14672d2c12SJonas Devlieghere #include "llvm/ADT/STLExtras.h" 15672d2c12SJonas Devlieghere #include "llvm/ADT/SmallVector.h" 1672787ac6SJonas Devlieghere #include "llvm/Support/FileSystem.h" 172cc5a18dSZachary Turner #include "llvm/Support/Path.h" 18672d2c12SJonas Devlieghere #include "llvm/Support/raw_ostream.h" 192cc5a18dSZachary Turner 20b1cb0b79SNico Weber #if !defined(_WIN32) 211f875347SZachary Turner #include <pwd.h> 221f875347SZachary Turner #endif 231f875347SZachary Turner 242cc5a18dSZachary Turner using namespace lldb_private; 252cc5a18dSZachary Turner using namespace llvm; 262cc5a18dSZachary Turner 272cc5a18dSZachary Turner namespace fs = llvm::sys::fs; 282cc5a18dSZachary Turner namespace path = llvm::sys::path; 292cc5a18dSZachary Turner 302cc5a18dSZachary Turner TildeExpressionResolver::~TildeExpressionResolver() {} 312cc5a18dSZachary Turner 322cc5a18dSZachary Turner bool StandardTildeExpressionResolver::ResolveExact( 332cc5a18dSZachary Turner StringRef Expr, SmallVectorImpl<char> &Output) { 342cc5a18dSZachary Turner // We expect the tilde expression to be ONLY the expression itself, and 355c5091fcSZachary Turner // contain no separators. 365c5091fcSZachary Turner assert(!llvm::any_of(Expr, [](char c) { return path::is_separator(c); })); 372cc5a18dSZachary Turner assert(Expr.empty() || Expr[0] == '~'); 382cc5a18dSZachary Turner 3972787ac6SJonas Devlieghere return !fs::real_path(Expr, Output, true); 402cc5a18dSZachary Turner } 412cc5a18dSZachary Turner 422cc5a18dSZachary Turner bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr, 432cc5a18dSZachary Turner StringSet<> &Output) { 442cc5a18dSZachary Turner // We expect the tilde expression to be ONLY the expression itself, and 452cc5a18dSZachary Turner // contain no separators. 465c5091fcSZachary Turner assert(!llvm::any_of(Expr, [](char c) { return path::is_separator(c); })); 472cc5a18dSZachary Turner assert(Expr.empty() || Expr[0] == '~'); 482cc5a18dSZachary Turner 492cc5a18dSZachary Turner Output.clear(); 50b1cb0b79SNico Weber #if defined(_WIN32) || defined(__ANDROID__) 512cc5a18dSZachary Turner return false; 522cc5a18dSZachary Turner #else 532cc5a18dSZachary Turner if (Expr.empty()) 542cc5a18dSZachary Turner return false; 552cc5a18dSZachary Turner 561f875347SZachary Turner SmallString<32> Buffer("~"); 572cc5a18dSZachary Turner setpwent(); 582cc5a18dSZachary Turner struct passwd *user_entry; 592cc5a18dSZachary Turner Expr = Expr.drop_front(); 602cc5a18dSZachary Turner 6165e5e278SJonas Devlieghere while ((user_entry = getpwent()) != nullptr) { 622cc5a18dSZachary Turner StringRef ThisName(user_entry->pw_name); 632cc5a18dSZachary Turner if (!ThisName.startswith(Expr)) 642cc5a18dSZachary Turner continue; 652cc5a18dSZachary Turner 662cc5a18dSZachary Turner Buffer.resize(1); 672cc5a18dSZachary Turner Buffer.append(ThisName); 689bd69ad9SPavel Labath Buffer.append(path::get_separator()); 699bd69ad9SPavel Labath Output.insert(Buffer); 702cc5a18dSZachary Turner } 712cc5a18dSZachary Turner 722cc5a18dSZachary Turner return true; 732cc5a18dSZachary Turner #endif 742cc5a18dSZachary Turner } 758d48cd60SZachary Turner 768d48cd60SZachary Turner bool TildeExpressionResolver::ResolveFullPath( 778d48cd60SZachary Turner StringRef Expr, llvm::SmallVectorImpl<char> &Output) { 788d48cd60SZachary Turner if (!Expr.startswith("~")) { 79*dcdd231dSJonas Devlieghere Output.assign(Expr.begin(), Expr.end()); 808d48cd60SZachary Turner return false; 818d48cd60SZachary Turner } 828d48cd60SZachary Turner 838d48cd60SZachary Turner namespace path = llvm::sys::path; 848d48cd60SZachary Turner StringRef Left = 858d48cd60SZachary Turner Expr.take_until([](char c) { return path::is_separator(c); }); 868d48cd60SZachary Turner 87*dcdd231dSJonas Devlieghere if (!ResolveExact(Left, Output)) { 88*dcdd231dSJonas Devlieghere Output.assign(Expr.begin(), Expr.end()); 898d48cd60SZachary Turner return false; 90*dcdd231dSJonas Devlieghere } 918d48cd60SZachary Turner 928d48cd60SZachary Turner Output.append(Expr.begin() + Left.size(), Expr.end()); 938d48cd60SZachary Turner return true; 948d48cd60SZachary Turner } 95