diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp')
| -rw-r--r-- | contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp | 93 | 
1 files changed, 93 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp b/contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp new file mode 100644 index 000000000000..b58f45728ce7 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp @@ -0,0 +1,93 @@ +//===--------------------- TildeExpressionResolver.cpp ----------*- C++ -*-===// +// +// 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) { +  Output.clear(); +  if (!Expr.startswith("~")) { +    Output.append(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)) +    return false; + +  Output.append(Expr.begin() + Left.size(), Expr.end()); +  return true; +}  | 
