diff options
author | Petteri Räty <petsku@petteriraty.eu> | 2011-06-25 13:04:08 +0300 |
---|---|---|
committer | Petteri Räty <petsku@petteriraty.eu> | 2011-06-25 13:04:08 +0300 |
commit | 95c82eca762174b0d329af65029fd2e1a280232b (patch) | |
tree | 39cc6d40d3647b1a3032cae9bedbcccb3c65661f /src | |
parent | Builtin: make declare built-in throw exceptions (diff) | |
parent | Walker: support break built-in (diff) | |
download | libbash-95c82eca762174b0d329af65029fd2e1a280232b.tar.gz libbash-95c82eca762174b0d329af65029fd2e1a280232b.tar.bz2 libbash-95c82eca762174b0d329af65029fd2e1a280232b.zip |
Merge remote-tracking branch 'mu/break_builtin'
Conflicts:
src/builtins/builtin_exceptions.h
Diffstat (limited to 'src')
-rw-r--r-- | src/builtins/break_builtin.cpp | 51 | ||||
-rw-r--r-- | src/builtins/break_builtin.h | 35 | ||||
-rw-r--r-- | src/builtins/builtin_exceptions.h | 46 | ||||
-rw-r--r-- | src/builtins/tests/break_tests.cpp | 69 | ||||
-rw-r--r-- | src/cppbash_builtin.cpp | 2 |
5 files changed, 196 insertions, 7 deletions
diff --git a/src/builtins/break_builtin.cpp b/src/builtins/break_builtin.cpp new file mode 100644 index 0000000..0ee20a7 --- /dev/null +++ b/src/builtins/break_builtin.cpp @@ -0,0 +1,51 @@ +/* + 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 break_builtin.h +/// \brief implementation for the break builtin +/// +#include "builtins/break_builtin.h" + +#include <boost/lexical_cast.hpp> + +#include "builtins/builtin_exceptions.h" +#include "core/interpreter_exception.h" + +int break_builtin::exec(const std::vector<std::string>& bash_args) +{ + int nth = 1; + + if(bash_args.size() > 1) + { + throw libbash::interpreter_exception("break: too many arguments"); + } + else if(bash_args.size() == 1) + { + try + { + nth = boost::lexical_cast<int>(bash_args[0]); + } + catch(boost::bad_lexical_cast& e) + { + throw libbash::interpreter_exception("break: argument should be an integer"); + } + } + + throw break_exception(nth); +} diff --git a/src/builtins/break_builtin.h b/src/builtins/break_builtin.h new file mode 100644 index 0000000..fec1bc7 --- /dev/null +++ b/src/builtins/break_builtin.h @@ -0,0 +1,35 @@ +/* + 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 break_builtin.h +/// \brief implementation for the break builtin +/// +#ifndef LIBBASH_BUILTINS_BREAK_BUILTIN_H_ +#define LIBBASH_BUILTINS_BREAK_BUILTIN_H_ + +#include "cppbash_builtin.h" + +class break_builtin : public virtual cppbash_builtin +{ +public: + BUILTIN_CONSTRUCTOR(break) + virtual int exec(const std::vector<std::string>& ); +}; + +#endif diff --git a/src/builtins/builtin_exceptions.h b/src/builtins/builtin_exceptions.h index 9b0c1d8..7b45efc 100644 --- a/src/builtins/builtin_exceptions.h +++ b/src/builtins/builtin_exceptions.h @@ -39,26 +39,58 @@ public: runtime_error("return exception"){} }; -class continue_exception: public std::exception +class loop_control_exception { int count; + + virtual void rethrow() = 0; + +protected: + virtual ~loop_control_exception() {} + public: - explicit continue_exception(int c): count(c) - { - if(c < 1) - throw libbash::illegal_argument_exception("continue: argument should be greater than or equal to 1"); - } + explicit loop_control_exception(int c): count(c) {} void rethrow_unless_correct_frame() { if(count != 1) { --count; - throw *this; + rethrow(); } } }; +class continue_exception: public loop_control_exception +{ +protected: + virtual void rethrow() + { + throw *this; + } + +public: + explicit continue_exception(int c): loop_control_exception(c) { + if(c < 1) + throw libbash::illegal_argument_exception("continue: argument should be greater than or equal to 1"); + } +}; + +class break_exception: public loop_control_exception +{ +protected: + virtual void rethrow() + { + throw *this; + } + +public: + explicit break_exception(int c): loop_control_exception(c) { + if(c < 1) + throw libbash::illegal_argument_exception("break: argument should be greater than or equal to 1"); + } +}; + class suppress_output: public std::exception { }; diff --git a/src/builtins/tests/break_tests.cpp b/src/builtins/tests/break_tests.cpp new file mode 100644 index 0000000..eba422e --- /dev/null +++ b/src/builtins/tests/break_tests.cpp @@ -0,0 +1,69 @@ +/* + 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 break_tests.cpp +/// \brief series of unit tests for break builtin +/// +#include <boost/lexical_cast.hpp> +#include <gtest/gtest.h> + +#include "builtins/builtin_exceptions.h" +#include "core/interpreter.h" +#include "cppbash_builtin.h" + +TEST(break_builtin_test, bad_argument) +{ + interpreter walker; + EXPECT_THROW(cppbash_builtin::exec("break", {"abc"}, std::cout, std::cerr, std::cin, walker), libbash::interpreter_exception); + EXPECT_THROW(cppbash_builtin::exec("break", {"1", "2"}, std::cout, std::cerr, std::cin, walker), libbash::interpreter_exception); + EXPECT_THROW(cppbash_builtin::exec("break", {"0"}, std::cout, std::cerr, std::cin, walker), libbash::interpreter_exception); + EXPECT_THROW(cppbash_builtin::exec("break", {"-1"}, std::cout, std::cerr, std::cin, walker), libbash::interpreter_exception); +} + +TEST(break_builtin_test, throw_exception) +{ + interpreter walker; + try + { + cppbash_builtin::exec("break", {}, std::cout, std::cerr, std::cin, walker); + FAIL(); + } + catch(break_exception& e) + { + EXPECT_NO_THROW(e.rethrow_unless_correct_frame()); + } + + try + { + cppbash_builtin::exec("break", {"2"}, std::cout, std::cerr, std::cin, walker); + FAIL(); + } + catch(break_exception& e) + { + try + { + e.rethrow_unless_correct_frame(); + FAIL(); + } + catch(break_exception& e) + { + EXPECT_NO_THROW(e.rethrow_unless_correct_frame()); + } + } +} diff --git a/src/cppbash_builtin.cpp b/src/cppbash_builtin.cpp index 97ab789..52c5c9b 100644 --- a/src/cppbash_builtin.cpp +++ b/src/cppbash_builtin.cpp @@ -29,6 +29,7 @@ #include "builtins/boolean_builtins.h" #include "builtins/builtin_exceptions.h" +#include "builtins/break_builtin.h" #include "builtins/continue_builtin.h" #include "builtins/declare_builtin.h" #include "builtins/echo_builtin.h" @@ -51,6 +52,7 @@ cppbash_builtin::cppbash_builtin(BUILTIN_ARGS): _out_stream(&out), _err_stream(& cppbash_builtin::builtins_type& cppbash_builtin::builtins() { static boost::scoped_ptr<builtins_type> p(new builtins_type { + {"break", boost::factory<break_builtin*>()}, {"continue", boost::factory<continue_builtin*>()}, {"echo", boost::factory<echo_builtin*>()}, {"eval", boost::factory<eval_builtin*>()}, |