diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/builtins/set_builtin.cpp | 79 | ||||
-rw-r--r-- | src/builtins/set_builtin.h | 46 | ||||
-rw-r--r-- | src/builtins/tests/set_tests.cpp | 43 | ||||
-rw-r--r-- | src/core/interpreter.cpp | 15 | ||||
-rw-r--r-- | src/core/interpreter.h | 3 | ||||
-rw-r--r-- | src/cppbash_builtin.cpp | 2 |
6 files changed, 188 insertions, 0 deletions
diff --git a/src/builtins/set_builtin.cpp b/src/builtins/set_builtin.cpp new file mode 100644 index 0000000..fca0f82 --- /dev/null +++ b/src/builtins/set_builtin.cpp @@ -0,0 +1,79 @@ +/* + Please use git log for copyright holder and year information + + This file is part of libbash. + + libbash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + libbash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libbash. If not, see <http://www.gnu.org/licenses/>. +*/ +/// +/// \file set_builtin.cpp +/// \brief class that implements the set builtin +/// +#include "builtins/set_builtin.h" + +#include "core/interpreter.h" +#include "exceptions.h" + +int set_builtin::exec(const std::vector<std::string>& bash_args) +{ + if(bash_args.empty()) + { + throw libbash::unsupported_exception("set: variables printing are not supported"); + return 1; + } + + if(bash_args[0][0] != '-' && bash_args[0][0] != '+') + { + throw libbash::illegal_argument_exception("set: invalid option"); + return 1; + } + + switch(bash_args[0][1]) + { + case '-': + if(bash_args[0][0] != '-') { + throw libbash::unsupported_exception("set: invalid option"); + return 1; + } + else + { + _walker.define_positional_arguments(bash_args.begin() + 1, bash_args.end()); + return 0; + } + case 'a': + case 'b': + case 'e': + case 'f': + case 'h': + case 'k': + case 'm': + case 'n': + case 'p': + case 't': + case 'u': + case 'v': + case 'x': + case 'B': + case 'C': + case 'E': + case 'H': + case 'P': + case 'T': + throw libbash::unsupported_exception("set " + bash_args[0] + " is not supported yet"); + return 1; + default: + throw libbash::illegal_argument_exception("set: unrecognized option: " + bash_args[0]); + return 1; + } +} diff --git a/src/builtins/set_builtin.h b/src/builtins/set_builtin.h new file mode 100644 index 0000000..ad27243 --- /dev/null +++ b/src/builtins/set_builtin.h @@ -0,0 +1,46 @@ +/* + Please use git log for copyright holder and year information + + This file is part of libbash. + + libbash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + libbash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libbash. If not, see <http://www.gnu.org/licenses/>. +*/ +/// +/// \file set_builtin.h +/// \brief class that implements the set builtin +/// + +#ifndef LIBBASH_BUILTINS_SET_BUILTIN_H_ +#define LIBBASH_BUILTINS_SET_BUILTIN_H_ + +#include "cppbash_builtin.h" + +/// +/// \class set_builtin +/// \brief the set builtin for bash +/// +class set_builtin: public virtual cppbash_builtin +{ +public: + BUILTIN_CONSTRUCTOR(set) + + /// + /// \brief runs the set builtin on the supplied arguments + /// \param bash_args the arguments to the set builtin + /// \return exit status of set + /// + virtual int exec(const std::vector<std::string>& bash_args); +}; + +#endif diff --git a/src/builtins/tests/set_tests.cpp b/src/builtins/tests/set_tests.cpp new file mode 100644 index 0000000..c4807c9 --- /dev/null +++ b/src/builtins/tests/set_tests.cpp @@ -0,0 +1,43 @@ +/* + Please use git log for copyright holder and year information + + This file is part of libbash. + + libbash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + libbash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libbash. If not, see <http://www.gnu.org/licenses/>. +*/ +/// +/// \file set_tests.cpp +/// \brief series of unit tests for set builtin +/// +#include <boost/lexical_cast.hpp> +#include <gtest/gtest.h> + +#include "core/interpreter.h" +#include "cppbash_builtin.h" +#include "exceptions.h" + +TEST(set_builtin_test, positional) +{ + interpreter walker; + + EXPECT_EQ(0, cppbash_builtin::exec("set", {"--", "1", "2", "3"}, std::cout, std::cerr, std::cin, walker)); + EXPECT_EQ(3, walker.get_array_length("*")); + EXPECT_STREQ("1", walker.resolve<std::string>("*", 1).c_str()); + EXPECT_STREQ("2", walker.resolve<std::string>("*", 2).c_str()); + EXPECT_STREQ("3", walker.resolve<std::string>("*", 3).c_str()); + + EXPECT_EQ(0, cppbash_builtin::exec("set", {"--"}, std::cout, std::cerr, std::cin, walker)); + EXPECT_EQ(0, walker.get_array_length("*")); + EXPECT_STREQ("", walker.resolve<std::string>("*", 1).c_str()); +} diff --git a/src/core/interpreter.cpp b/src/core/interpreter.cpp index b048353..405023d 100644 --- a/src/core/interpreter.cpp +++ b/src/core/interpreter.cpp @@ -312,6 +312,21 @@ void interpreter::define_function_arguments(scope& current_stack, current_stack["*"].reset(new variable("*", positional_args)); } +void interpreter::define_positional_arguments(const std::vector<std::string>::const_iterator begin, + const std::vector<std::string>::const_iterator end) +{ + std::map<unsigned, std::string> positional_args; + std::vector<std::string>::const_iterator iter = begin; + + for(auto i = 1u; iter != end ; ++i, ++iter) + positional_args[i] = *iter; + + if(local_members.size() < 1) + define("*", positional_args); + else + define_local("*", positional_args); +} + namespace { bool check_function_name(const std::string& name) diff --git a/src/core/interpreter.h b/src/core/interpreter.h index fbb9d48..dd72377 100644 --- a/src/core/interpreter.h +++ b/src/core/interpreter.h @@ -521,6 +521,9 @@ public: /// \return zero unless n is greater than $# or less than zero, non-zero otherwise. int shift(int shift_number); + void define_positional_arguments(const std::vector<std::string>::const_iterator begin, + const std::vector<std::string>::const_iterator end); + /// \brief perform expansion like ${var//foo/bar} /// \param value the value to be expanded /// \param pattern the pattern used to match the value diff --git a/src/cppbash_builtin.cpp b/src/cppbash_builtin.cpp index c93b94a..e4a7c29 100644 --- a/src/cppbash_builtin.cpp +++ b/src/cppbash_builtin.cpp @@ -45,6 +45,7 @@ #include "builtins/source_builtin.h" #include "builtins/unset_builtin.h" #include "builtins/read_builtin.h" +#include "builtins/set_builtin.h" namespace qi = boost::spirit::qi; namespace karma = boost::spirit::karma; @@ -75,6 +76,7 @@ cppbash_builtin::builtins_type& cppbash_builtin::builtins() { {"let", boost::factory<let_builtin*>()}, {"unset", boost::factory<unset_builtin*>()}, {"read", boost::factory<read_builtin*>()}, + {"set", boost::factory<set_builtin*>()}, }); return *p; } |