mpw-shell/environment.h

170 lines
4.5 KiB
C
Raw Normal View History

2016-02-02 01:38:29 +00:00
#ifndef __environment_h__
#define __environment_h__
#include <string>
#include <unordered_map>
#include <utility>
2016-02-02 21:19:13 +00:00
#include <new>
2016-06-16 20:48:04 +00:00
#include <vector>
2016-02-02 21:19:13 +00:00
2016-02-02 01:38:29 +00:00
// 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; }
2016-02-03 20:06:48 +00:00
const char *c_str() const { return value.c_str(); }
2016-02-02 01:38:29 +00:00
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::unordered_map<std::string, EnvironmentEntry> mapped_type;
typedef mapped_type::iterator iterator;
typedef mapped_type::const_iterator const_iterator;
2016-06-22 17:47:48 +00:00
typedef std::vector<std::pair<std::string, std::string>> alias_table_type;
typedef alias_table_type::const_iterator const_alias_iterator;
2016-02-02 01:38:29 +00:00
//const EnvironmentEntry & lookup(const std::string &s);
2016-06-16 20:48:04 +00:00
void set_argv(const std::string &argv0, const std::vector<std::string>& argv);
void set_argv(const std::vector<std::string>& argv);
2016-02-02 01:38:29 +00:00
void set(const std::string &k, const std::string &value, bool exported = false);
2016-06-16 20:48:04 +00:00
void set(const std::string &k, long l, bool exported = false);
2016-02-02 01:38:29 +00:00
void unset(const std::string &k);
void unset();
2016-02-11 20:49:19 +00:00
std::string get(const std::string &k) const;
2016-02-02 01:38:29 +00:00
constexpr bool echo() const noexcept { return _echo; }
constexpr bool test() const noexcept { return _test; }
2016-02-11 20:49:19 +00:00
constexpr bool exit() const noexcept { return _exit; }
2016-02-02 01:38:29 +00:00
constexpr int status() const noexcept { return _status; }
2016-06-16 20:48:04 +00:00
constexpr int pound() const noexcept { return _pound; }
2016-02-02 01:38:29 +00:00
2016-02-02 21:19:13 +00:00
int status(int i, bool throw_up = true);
int status(int i, const std::nothrow_t &);
2016-02-02 01:38:29 +00:00
constexpr bool startup() const noexcept { return _startup; }
constexpr void startup(bool tf) noexcept { _startup = tf; }
constexpr bool passthrough() const noexcept { return _passthrough; }
constexpr void passthrough(bool tf) noexcept { _passthrough = 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, ...);
2016-02-11 02:58:00 +00:00
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; }
}
constexpr bool loop() const noexcept { return _loop; }
2016-06-22 17:47:48 +00:00
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(); }
2016-02-02 01:38:29 +00:00
private:
// magic variables.
2016-02-02 21:19:13 +00:00
friend class indent_helper;
int _indent = 0;
int _loop = 0;
2016-02-02 21:19:13 +00:00
2016-02-02 01:38:29 +00:00
bool _exit = false;
bool _test = false;
bool _echo = false;
int _status = 0;
2016-06-16 20:48:04 +00:00
int _pound = 0;
2016-02-02 01:38:29 +00:00
bool _startup = false;
bool _passthrough = false;
2016-06-16 20:48:04 +00:00
void set_common(const std::string &, const std::string &, bool);
2016-06-22 17:47:48 +00:00
void rebuild_aliases();
2016-06-16 20:48:04 +00:00
2016-02-02 01:38:29 +00:00
std::unordered_map<std::string, EnvironmentEntry> _table;
2016-06-22 17:47:48 +00:00
alias_table_type _alias_table;
2016-02-02 01:38:29 +00:00
};
2016-02-11 02:58:00 +00:00
/*
2016-02-02 21:19:13 +00:00
class indent_helper {
public:
indent_helper(Environment &e) : env(e) { env._indent++; }
void release() { if (active) { active = false; env._indent--; }}
~indent_helper() { if (active) env._indent--; }
private:
Environment &env;
bool active = true;
};
2016-02-11 02:58:00 +00:00
*/
2016-02-02 01:38:29 +00:00
#endif