96 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===--------------------- TildeExpressionResolver.cpp ----------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "lldb/Utility/TildeExpressionResolver.h"
 | |
| 
 | |
| #include <assert.h>     // for assert
 | |
| #include <system_error> // for error_code
 | |
| 
 | |
| #include "llvm/ADT/STLExtras.h"      // for any_of
 | |
| #include "llvm/ADT/SmallVector.h"    // for SmallVectorImpl
 | |
| #include "llvm/Config/llvm-config.h" // for LLVM_ON_WIN32
 | |
| #include "llvm/Support/FileSystem.h"
 | |
| #include "llvm/Support/Path.h"
 | |
| #include "llvm/Support/raw_ostream.h" // for fs
 | |
| 
 | |
| #if !defined(LLVM_ON_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(LLVM_ON_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()) != NULL) {
 | |
|     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;
 | |
| }
 |