diff options
Diffstat (limited to 'src/core/interpreter.h')
-rw-r--r-- | src/core/interpreter.h | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/src/core/interpreter.h b/src/core/interpreter.h index dd72377..3f77f5d 100644 --- a/src/core/interpreter.h +++ b/src/core/interpreter.h @@ -189,6 +189,20 @@ public: _out = &std::cout; } + /// \brief check whether a variable is valid and can be used + /// \param var variable + /// \return whether the variable is valid + bool is_valid(const std::shared_ptr<variable>& var, const std::string& name) const + { + if(var) + return true; + + if(get_option('u')) + throw libbash::unsupported_exception(name + ": unbound variable"); + + return false; + } + /// \brief resolve string/long variable, local scope will be /// checked first, then global scope /// \param name variable name @@ -199,10 +213,25 @@ public: T resolve(const std::string& name, const unsigned index=0) const { auto var = resolve_variable(name); - if(var) + if(is_valid(var, name)) + { + if(get_option('u') && var->is_unset(index)) + { + if(name == "*") + throw libbash::unsupported_exception("$" + boost::lexical_cast<std::string>(index) + ": unbound variable"); + else if(index == 0) + throw libbash::unsupported_exception(name + ": unbound variable"); + else + throw libbash::unsupported_exception(name + "[" + boost::lexical_cast<std::string>(index) + "]: unbound variable"); + } return var->get_value<T>(index); + } else + { + if(get_option('u')) + throw libbash::unsupported_exception(name + ": unbound variable"); return T{}; + } } /// \brief resolve array variable @@ -212,7 +241,7 @@ public: bool resolve_array(const std::string& name, std::vector<T>& values) const { auto var = resolve_variable(name); - if(!var) + if(!is_valid(var, name)) return false; var->get_all_values(values); @@ -467,7 +496,10 @@ public: variable::size_type get_max_index(const std::string& name) const { auto var = resolve_variable(name); - return var ? var->get_max_index() : 0; + if(is_valid(var, name)) + return var->get_max_index(); + else + return 0; } /// \brief get all array elements concatenated by space @@ -496,6 +528,17 @@ public: /// \return zero unless the name is not a valid shell option void set_additional_option(const std::string& name, bool value); + /// \brief get the status of shell optional behavior + /// \param name the option name + /// \return zero unless the name is not a valid shell option + bool get_option(const char name) const; + + /// \brief set the status of shell optional behavior + /// \param name the option name + /// \param[in] value true if option is enabled, false otherwise + /// \return zero unless the name is not a valid shell option + void set_option(const char name, bool value); + /// \brief return an iterator referring to the first variable /// \return iterator referring to the first variable option_iterator additional_options_begin() const |