95 lines · cpp
1//===-- TildeExpressionResolver.cpp ---------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Utility/TildeExpressionResolver.h"10 11#include <cassert>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#endif23 24using namespace lldb_private;25using namespace llvm;26 27namespace fs = llvm::sys::fs;28namespace path = llvm::sys::path;29 30TildeExpressionResolver::~TildeExpressionResolver() = default;31 32bool StandardTildeExpressionResolver::ResolveExact(33 StringRef Expr, SmallVectorImpl<char> &Output) {34 // We expect the tilde expression to be ONLY the expression itself, and35 // 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 42bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr,43 StringSet<> &Output) {44 // We expect the tilde expression to be ONLY the expression itself, and45 // 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#else53 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.starts_with(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#endif74}75 76bool TildeExpressionResolver::ResolveFullPath(77 StringRef Expr, llvm::SmallVectorImpl<char> &Output) {78 if (!Expr.starts_with("~")) {79 Output.assign(Expr.begin(), Expr.end());80 return false;81 }82 83 namespace path = llvm::sys::path;84 StringRef Left =85 Expr.take_until([](char c) { return path::is_separator(c); });86 87 if (!ResolveExact(Left, Output)) {88 Output.assign(Expr.begin(), Expr.end());89 return false;90 }91 92 Output.append(Expr.begin() + Left.size(), Expr.end());93 return true;94}95