1 //===-- Environment.h -------------------------------------------*- 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 #ifndef LLDB_UTILITY_ENVIRONMENT_H
11 #define LLDB_UTILITY_ENVIRONMENT_H
12 
13 #include "llvm/ADT/StringMap.h"
14 #include "llvm/Support/Allocator.h"
15 #include "llvm/Support/FormatProviders.h"
16 
17 namespace lldb_private {
18 
19 class Environment : private llvm::StringMap<std::string> {
20   using Base = llvm::StringMap<std::string>;
21 
22 public:
23   class Envp {
24   public:
25     Envp(Envp &&RHS) = default;
26     Envp &operator=(Envp &&RHS) = default;
27 
get()28     char *const *get() const { return Data; }
29     operator char *const *() const { return get(); }
30 
31   private:
32     explicit Envp(const Environment &Env);
33     char *make_entry(llvm::StringRef Key, llvm::StringRef Value);
34     Envp(const Envp &) = delete;
35     Envp &operator=(const Envp &) = delete;
36     friend class Environment;
37 
38     llvm::BumpPtrAllocator Allocator;
39     char **Data;
40   };
41 
42   using Base::const_iterator;
43   using Base::iterator;
44   using Base::value_type;
45 
46   using Base::begin;
47   using Base::clear;
48   using Base::count;
49   using Base::empty;
50   using Base::end;
51   using Base::erase;
52   using Base::find;
53   using Base::insert;
54   using Base::lookup;
55   using Base::size;
56   using Base::try_emplace;
57   using Base::operator[];
58 
Environment()59   Environment() : Base() {}
Environment(const Environment & RHS)60   Environment(const Environment &RHS) : Base(RHS) {}
Environment(Environment && RHS)61   Environment(Environment &&RHS) : Base(std::move(RHS)) {}
Environment(char * const * Env)62   Environment(char *const *Env)
63       : Environment(const_cast<const char *const *>(Env)) {}
64   Environment(const char *const *Env);
65 
66   Environment &operator=(Environment RHS) {
67     Base::operator=(std::move(RHS));
68     return *this;
69   }
70 
insert(llvm::StringRef KeyEqValue)71   std::pair<iterator, bool> insert(llvm::StringRef KeyEqValue) {
72     return insert(KeyEqValue.split('='));
73   }
74 
75   void insert(const_iterator first, const_iterator last);
76 
getEnvp()77   Envp getEnvp() const { return Envp(*this); }
78 
compose(const value_type & KeyValue)79   static std::string compose(const value_type &KeyValue) {
80     return (KeyValue.first() + "=" + KeyValue.second).str();
81   }
82 };
83 
84 } // namespace lldb_private
85 
86 namespace llvm {
87 template <> struct format_provider<lldb_private::Environment> {
88   static void format(const lldb_private::Environment &Env, raw_ostream &Stream,
89                      StringRef Style) {
90     for (const auto &KV : Env)
91       Stream << "env[" << KV.first() << "] = " << KV.second << "\n";
92   }
93 };
94 } // namespace llvm
95 
96 #endif // #ifndef LLDB_UTILITY_ENVIRONMENT_H
97