-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathenvironment.h
155 lines (105 loc) · 3.97 KB
/
environment.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#ifndef __environment_h__
#define __environment_h__
#include <map>
#include <new>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
// environment has a bool which indicates if exported.
struct EnvironmentEntry {
public:
operator bool() const { return exported; }
operator bool&() { return exported; }
operator const std::string&() const { return value; }
operator std::string&() { return value; }
const char *c_str() const { return value.c_str(); }
EnvironmentEntry() = default;
EnvironmentEntry(const EnvironmentEntry &) = default;
EnvironmentEntry(EnvironmentEntry &&) = default;
EnvironmentEntry(const std::string &s, bool e = false) : value(s), exported(e)
{}
EnvironmentEntry(std::string &&s, bool e = false) : value(std::move(s)), exported(e)
{}
~EnvironmentEntry() = default;
EnvironmentEntry& operator=(bool rhs) { exported = rhs; return *this; }
EnvironmentEntry& operator=(const std::string &rhs) { value = rhs; return *this; }
EnvironmentEntry& operator=(const EnvironmentEntry &) = default;
EnvironmentEntry& operator=(EnvironmentEntry &&) = default;
private:
std::string value;
bool exported = false;
};
class Environment {
public:
typedef std::map<std::string, EnvironmentEntry> mapped_type;
typedef mapped_type::iterator iterator;
typedef mapped_type::const_iterator const_iterator;
typedef std::vector<std::pair<std::string, std::string>> alias_table_type;
typedef alias_table_type::const_iterator const_alias_iterator;
Environment subshell_environment();
// void set_argv(const std::string &argv0, const std::vector<std::string>& argv);
void set_argv(const std::vector<std::string>& argv);
void shift(int n);
void set(const std::string &k, const std::string &value, bool exported = false);
void set(const std::string &k, long l, bool exported = false);
void unset(const std::string &k);
void unset();
std::string get(const std::string &k) const;
bool echo() const noexcept { return _echo; }
bool test() const noexcept { return _test; }
bool exit() const noexcept { return _exit; }
int status() const noexcept { return _status; }
int pound() const noexcept { return _pound; }
int status(int i, bool throw_up = true);
int status(int i, const std::nothrow_t &);
bool startup() const noexcept { return _startup; }
void startup(bool tf) noexcept { _startup = tf; }
template<class FX>
void foreach(FX && fx) { for (const auto &kv : _table) { fx(kv.first, kv.second); }}
iterator begin() { return _table.begin(); }
const_iterator begin() const { return _table.begin(); }
const_iterator cbegin() const { return _table.cbegin(); }
iterator end() { return _table.end(); }
const_iterator end() const { return _table.end(); }
const_iterator cend() const { return _table.cend(); }
iterator find( const std::string & key );
const_iterator find( const std::string & key ) const;
void echo(const char *format, ...) const;
template<class FX>
void indent_and(FX &&fx) {
int i = _indent++;
try { fx(); _indent = i; }
catch (...) { _indent = i; throw; }
}
template<class FX>
void loop_indent_and(FX &&fx) {
int i = _indent++;
int j = _loop++;
try { fx(); _indent = i; _loop = j; }
catch (...) { _indent = i; _loop = j; throw; }
}
bool loop() const noexcept { return _loop; }
const alias_table_type &aliases() const { return _alias_table; }
void add_alias(std::string &&name, std::string &&value);
const std::string &find_alias(const std::string &s) const;
void remove_alias(const std::string &name);
void remove_alias();
const_alias_iterator alias_begin() const { return _alias_table.begin(); }
const_alias_iterator alias_end() const { return _alias_table.end(); }
private:
// magic variables.
int _indent = 0;
int _loop = 0;
bool _exit = false;
bool _test = false;
bool _echo = false;
int _status = 0;
int _pound = 0;
bool _startup = false;
void set_common(const std::string &, const std::string &, bool);
void rebuild_aliases();
mapped_type _table;
alias_table_type _alias_table;
};
#endif