diff --git a/src/env.cpp b/src/env.cpp index 5563d2ab4..6ba77a6e6 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -216,8 +216,10 @@ static const string_set_t env_electric = {L"history", L"pipestatus", L"status", static bool is_electric(const wcstring &key) { return contains(env_electric, key); } -env_stack_t::env_stack_t() : vars_(make_unique()) {} -env_stack_t::env_stack_t(std::unique_ptr vars) : vars_(std::move(vars)) {} +env_scoped_t::env_scoped_t() : env_scoped_t(make_unique()) {} +env_scoped_t::env_scoped_t(std::unique_ptr vars) : vars_(std::move(vars)) {} +env_scoped_t::env_scoped_t(env_scoped_t &&) = default; +env_scoped_t::~env_scoped_t() = default; void env_stack_t::universal_barrier() { ASSERT_IS_MAIN_THREAD(); @@ -233,9 +235,9 @@ void env_stack_t::universal_barrier() { } // Get the variable stack -var_stack_t &env_stack_t::vars_stack() { return *vars_; } +var_stack_t &env_scoped_t::vars_stack() { return *vars_; } -const var_stack_t &env_stack_t::vars_stack() const { return *vars_; } +const var_stack_t &env_scoped_t::vars_stack() const { return *vars_; } /// Return the current umask value. static mode_t get_umask() { @@ -856,7 +858,7 @@ static maybe_t get_electric(const wcstring &key, const environment_t DIE("unrecognized electric var name"); } -maybe_t env_stack_t::get(const wcstring &key, env_mode_flags_t mode) const { +maybe_t env_scoped_t::get(const wcstring &key, env_mode_flags_t mode) const { const bool has_scope = mode & (ENV_LOCAL | ENV_GLOBAL | ENV_UNIVERSAL); const bool search_local = !has_scope || (mode & ENV_LOCAL); const bool search_global = !has_scope || (mode & ENV_GLOBAL); @@ -953,7 +955,7 @@ static void add_key_to_string_set(const var_table_t &envs, std::set *s } } -wcstring_list_t env_stack_t::get_names(int flags) const { +wcstring_list_t env_scoped_t::get_names(int flags) const { scoped_lock locker(env_lock); wcstring_list_t result; diff --git a/src/env.h b/src/env.h index 9812077b3..fa598f629 100644 --- a/src/env.h +++ b/src/env.h @@ -193,13 +193,36 @@ class null_environment_t : public environment_t { wcstring_list_t get_names(int flags) const override; }; -/// A environment stack of scopes. This is the main class that tracks fish variables. +/// An environment stack of scopes. +/// The base implementation provides read-only access. struct var_stack_t; class env_node_t; -class env_stack_t final : public environment_t { - friend class parser_t; +class env_scoped_t : public environment_t { + private: std::unique_ptr vars_; + protected: + var_stack_t &vars_stack(); + const var_stack_t &vars_stack() const; + + explicit env_scoped_t(std::unique_ptr vars_); + env_scoped_t(); + env_scoped_t(env_scoped_t &&); + + public: + /// Gets the variable with the specified name, or none() if it does not exist. + maybe_t get(const wcstring &key, env_mode_flags_t mode = ENV_DEFAULT) const override; + + /// Returns all variable names. + wcstring_list_t get_names(int flags) const override; + + ~env_scoped_t() override; +}; + +/// A mutable env_scoped_t, that allows scopes to be pushed and popped. +class env_stack_t final : public env_scoped_t { + friend class parser_t; + int set_internal(const wcstring &key, env_mode_flags_t var_mode, wcstring_list_t val); bool try_remove(std::shared_ptr n, const wchar_t *key, int var_mode); @@ -207,18 +230,11 @@ class env_stack_t final : public environment_t { static env_stack_t make_principal(); - var_stack_t &vars_stack(); - const var_stack_t &vars_stack() const; - - explicit env_stack_t(std::unique_ptr vars_); - env_stack_t(); + using env_scoped_t::env_scoped_t; ~env_stack_t() override; - env_stack_t(env_stack_t &&); public: - /// Gets the variable with the specified name, or none() if it does not exist. - maybe_t get(const wcstring &key, env_mode_flags_t mode = ENV_DEFAULT) const override; /// Sets the variable with the specified name to the given values. int set(const wcstring &key, env_mode_flags_t mode, wcstring_list_t vals); @@ -254,9 +270,6 @@ class env_stack_t final : public environment_t { /// Returns an array containing all exported variables in a format suitable for execv const char *const *export_arr(); - /// Returns all variable names. - wcstring_list_t get_names(int flags) const override; - /// Update the termsize variable. void set_termsize();