aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndré Aparício <aparicio99@gmail.com>2012-06-19 18:36:58 +0100
committerMu Qiao <qiaomuf@gentoo.org>2012-07-20 09:20:22 +0800
commitafe72fecbc6371c6d4cc2c784738459b5281db09 (patch)
treeb6ee207a711bd950c5e065c1a87717b43c2adf96
parentBuiltin: Support variable declarations in declare (diff)
downloadlibbash-afe72fecbc6371c6d4cc2c784738459b5281db09.tar.gz
libbash-afe72fecbc6371c6d4cc2c784738459b5281db09.tar.bz2
libbash-afe72fecbc6371c6d4cc2c784738459b5281db09.zip
Builtin: Support more options for declare
-rw-r--r--src/builtins/declare_builtin.cpp13
-rw-r--r--src/builtins/tests/declare_tests.cpp23
-rw-r--r--src/core/interpreter.h8
3 files changed, 39 insertions, 5 deletions
diff --git a/src/builtins/declare_builtin.cpp b/src/builtins/declare_builtin.cpp
index 81877b5..34a78cd 100644
--- a/src/builtins/declare_builtin.cpp
+++ b/src/builtins/declare_builtin.cpp
@@ -41,6 +41,8 @@ int declare_builtin::exec(const std::vector<std::string>& bash_args)
}
int result = 0;
+ bool jump_option = false;
+ bool option_global = false;
std::vector<std::string> tokens;
boost::split(tokens, bash_args[0], boost::is_any_of(" "));
@@ -50,6 +52,7 @@ int declare_builtin::exec(const std::vector<std::string>& bash_args)
if(tokens[0].size() > 2)
throw libbash::unsupported_exception("declare: " + tokens[0] + " is not supported yet");
+ jump_option = true;
switch(tokens[0][1])
{
case 'F':
@@ -100,6 +103,10 @@ int declare_builtin::exec(const std::vector<std::string>& bash_args)
return result;
case 'a':
case 'i':
+ break;
+ case 'g':
+ option_global = true;
+ break;
case 'A':
case 'f':
case 'l':
@@ -119,7 +126,11 @@ int declare_builtin::exec(const std::vector<std::string>& bash_args)
for(auto iter = bash_args.begin(); iter != bash_args.end(); ++iter)
script << *iter + " ";
- bash_ast ast(script, std::bind(&bash_ast::parser_builtin_variable_definitions, std::placeholders::_1, false));
+ if(jump_option)
+ script.ignore(static_cast<std::streamsize>(tokens[0].size()));
+
+ bool local = _walker.is_local_scope() && !option_global;
+ bash_ast ast(script, std::bind(&bash_ast::parser_builtin_variable_definitions, std::placeholders::_1, local));
ast.interpret_with(_walker);
return result;
diff --git a/src/builtins/tests/declare_tests.cpp b/src/builtins/tests/declare_tests.cpp
index eec5e41..1b83f7d 100644
--- a/src/builtins/tests/declare_tests.cpp
+++ b/src/builtins/tests/declare_tests.cpp
@@ -119,22 +119,37 @@ TEST(declare_built_test, _p)
EXPECT_EQ("-bash: declare: bar: not found\n-bash: declare: test: not found\n", test_output2.str());
}
+TEST(declare_built_test, _a)
+{
+ interpreter walker;
+ EXPECT_EQ(0, cppbash_builtin::exec("declare", {"-a", "foo"}, std::cout, cerr, cin, walker));
+ walker.set_value("foo", "bar", 3);
+ EXPECT_STREQ("bar", walker.resolve<std::string>("foo", 3).c_str());
+}
+
+TEST(declare_built_test, _g)
+{
+ stringstream expression("function func() { declare -g var1=foo; declare var2=bar; }; func;");
+ interpreter walker;
+ bash_ast ast(expression);
+ ast.interpret_with(walker);
+
+ EXPECT_STREQ("foo", walker.resolve<std::string>("var1").c_str());
+ EXPECT_STREQ("", walker.resolve<std::string>("var2").c_str());
+}
+
#define TEST_DECLARE(name, expected, ...) \
TEST(declare_builtin_test, name) { test_declare<libbash::unsupported_exception>(expected, {__VA_ARGS__}); }
-TEST_DECLARE(_a, "declare -a is not supported yet", "-a", "world")
TEST_DECLARE(_A, "declare -A is not supported yet", "-A", "world")
TEST_DECLARE(_f, "declare -f is not supported yet", "-f", "world")
-TEST_DECLARE(_i, "declare -i is not supported yet", "-i", "world")
TEST_DECLARE(_l, "declare -l is not supported yet", "-l", "world")
TEST_DECLARE(_r, "declare -r is not supported yet", "-r", "world")
TEST_DECLARE(_t, "declare -t is not supported yet", "-t", "world")
TEST_DECLARE(_u, "declare -u is not supported yet", "-u", "world")
TEST_DECLARE(_x, "declare -x is not supported yet", "-x", "world")
-TEST_DECLARE(pa, "declare +a is not supported yet", "+a", "world")
TEST_DECLARE(pA, "declare +A is not supported yet", "+A", "world")
TEST_DECLARE(pf, "declare +f is not supported yet", "+f", "world")
-TEST_DECLARE(pi, "declare +i is not supported yet", "+i", "world")
TEST_DECLARE(pl, "declare +l is not supported yet", "+l", "world")
TEST_DECLARE(pr, "declare +r is not supported yet", "+r", "world")
TEST_DECLARE(pt, "declare +t is not supported yet", "+t", "world")
diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index 3f77f5d..2f6854b 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -176,6 +176,14 @@ public:
return members.end();
}
+ ///
+ /// \brief checks whether the current scope is local or global
+ /// \return whether current scope is local
+ bool is_local_scope() const
+ {
+ return local_members.size() > 0;
+ }
+
/// \brief set current output stream
/// \param stream the pointer to the output stream
void set_output_stream(std::ostream* stream)