blob: 34ca02546135c05e3ee339ddbbf11150da8afbb6 [file] [log] [blame]
Zachary Turner2cc5a182017-03-13 00:41:011//===--------------------- TildeExpressionResolver.cpp ----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Utility/TildeExpressionResolver.h"
11
Jonas Devlieghere672d2c12018-11-11 23:16:4312#include <assert.h>
13#include <system_error>
Zachary Turner4479ac12017-04-06 18:12:2414
Jonas Devlieghere672d2c12018-11-11 23:16:4315#include "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/SmallVector.h"
Jonas Devlieghere72787ac2018-11-09 01:59:2817#include "llvm/Support/FileSystem.h"
Zachary Turner2cc5a182017-03-13 00:41:0118#include "llvm/Support/Path.h"
Jonas Devlieghere672d2c12018-11-11 23:16:4319#include "llvm/Support/raw_ostream.h"
Zachary Turner2cc5a182017-03-13 00:41:0120
Nico Weberb1cb0b792018-04-10 13:33:4521#if !defined(_WIN32)
Zachary Turner1f875342017-03-13 02:44:3922#include <pwd.h>
23#endif
24
Zachary Turner2cc5a182017-03-13 00:41:0125using namespace lldb_private;
26using namespace llvm;
27
28namespace fs = llvm::sys::fs;
29namespace path = llvm::sys::path;
30
31TildeExpressionResolver::~TildeExpressionResolver() {}
32
33bool StandardTildeExpressionResolver::ResolveExact(
34 StringRef Expr, SmallVectorImpl<char> &Output) {
35 // We expect the tilde expression to be ONLY the expression itself, and
Zachary Turner5c5091f2017-03-16 22:28:0436 // contain no separators.
37 assert(!llvm::any_of(Expr, [](char c) { return path::is_separator(c); }));
Zachary Turner2cc5a182017-03-13 00:41:0138 assert(Expr.empty() || Expr[0] == '~');
39
Jonas Devlieghere72787ac2018-11-09 01:59:2840 return !fs::real_path(Expr, Output, true);
Zachary Turner2cc5a182017-03-13 00:41:0141}
42
43bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr,
44 StringSet<> &Output) {
45 // We expect the tilde expression to be ONLY the expression itself, and
46 // contain no separators.
Zachary Turner5c5091f2017-03-16 22:28:0447 assert(!llvm::any_of(Expr, [](char c) { return path::is_separator(c); }));
Zachary Turner2cc5a182017-03-13 00:41:0148 assert(Expr.empty() || Expr[0] == '~');
49
50 Output.clear();
Nico Weberb1cb0b792018-04-10 13:33:4551#if defined(_WIN32) || defined(__ANDROID__)
Zachary Turner2cc5a182017-03-13 00:41:0152 return false;
53#else
54 if (Expr.empty())
55 return false;
56
Zachary Turner1f875342017-03-13 02:44:3957 SmallString<32> Buffer("~");
Zachary Turner2cc5a182017-03-13 00:41:0158 setpwent();
59 struct passwd *user_entry;
60 Expr = Expr.drop_front();
61
62 while ((user_entry = getpwent()) != NULL) {
63 StringRef ThisName(user_entry->pw_name);
64 if (!ThisName.startswith(Expr))
65 continue;
66
67 Buffer.resize(1);
68 Buffer.append(ThisName);
Pavel Labath9bd69ad2017-03-13 09:46:1569 Buffer.append(path::get_separator());
70 Output.insert(Buffer);
Zachary Turner2cc5a182017-03-13 00:41:0171 }
72
73 return true;
74#endif
75}
Zachary Turner8d48cd62017-03-22 17:33:2376
77bool TildeExpressionResolver::ResolveFullPath(
78 StringRef Expr, llvm::SmallVectorImpl<char> &Output) {
79 Output.clear();
80 if (!Expr.startswith("~")) {
81 Output.append(Expr.begin(), Expr.end());
82 return false;
83 }
84
85 namespace path = llvm::sys::path;
86 StringRef Left =
87 Expr.take_until([](char c) { return path::is_separator(c); });
88
89 if (!ResolveExact(Left, Output))
90 return false;
91
92 Output.append(Expr.begin() + Left.size(), Expr.end());
93 return true;
94}