aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/builtins/set_builtin.cpp79
-rw-r--r--src/builtins/set_builtin.h46
-rw-r--r--src/builtins/tests/set_tests.cpp43
-rw-r--r--src/core/interpreter.cpp15
-rw-r--r--src/core/interpreter.h3
-rw-r--r--src/cppbash_builtin.cpp2
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;
}