diff options
author | André Aparício <aparicio99@gmail.com> | 2012-06-19 17:46:40 +0100 |
---|---|---|
committer | Mu Qiao <qiaomuf@gentoo.org> | 2012-07-20 09:20:22 +0800 |
commit | f9501f5d7ad82d273cab44cd96114d644fb5772d (patch) | |
tree | 8a0639ad40b65f460cdb7409ea94ffc52d7fd67b /src | |
parent | Replace boost::scoped_ptr with std::unique_ptr (diff) | |
download | libbash-f9501f5d7ad82d273cab44cd96114d644fb5772d.tar.gz libbash-f9501f5d7ad82d273cab44cd96114d644fb5772d.tar.bz2 libbash-f9501f5d7ad82d273cab44cd96114d644fb5772d.zip |
Builtin: Support variable declarations in declare
Diffstat (limited to 'src')
-rw-r--r-- | src/builtins/declare_builtin.cpp | 144 | ||||
-rw-r--r-- | src/builtins/tests/declare_tests.cpp | 35 |
2 files changed, 106 insertions, 73 deletions
diff --git a/src/builtins/declare_builtin.cpp b/src/builtins/declare_builtin.cpp index db955c4..81877b5 100644 --- a/src/builtins/declare_builtin.cpp +++ b/src/builtins/declare_builtin.cpp @@ -25,6 +25,10 @@ #include <algorithm> #include <iostream> +#include <boost/algorithm/string/classification.hpp> +#include <boost/algorithm/string/split.hpp> + +#include "core/bash_ast.h" #include "core/interpreter.h" #include "exceptions.h" @@ -35,80 +39,88 @@ int declare_builtin::exec(const std::vector<std::string>& bash_args) throw libbash::illegal_argument_exception("declare: arguments required"); return 1; } - else if(bash_args[0].size() != 2) - { - throw libbash::unsupported_exception("declare: multiple arguments are not supported"); - return 1; - } - - if(bash_args[0][0] != '-' && bash_args[0][0] != '+') - { - throw libbash::illegal_argument_exception("declare: invalid option"); - return 1; - } int result = 0; - switch(bash_args[0][1]) + + std::vector<std::string> tokens; + boost::split(tokens, bash_args[0], boost::is_any_of(" ")); + + if(tokens[0][0] == '-' || tokens[0][0] == '+') { - case 'F': - if(bash_args[0][0] == '+') - return 0; - if(bash_args.size() > 1) - { - for(auto iter = bash_args.begin() + 1; iter != bash_args.end(); ++iter) - { - if(_walker.has_function(*iter)) - *_out_stream << *iter << std::endl; - else - result = 1; - } - } - else - { - std::vector<std::string> functions; - - _walker.get_all_function_names(functions); - sort(functions.begin(), functions.end()); - - for(auto iter = functions.begin(); iter != functions.end(); ++iter) - *_out_stream << "declare -f " << *iter << std::endl; - } - return result; - case 'p': - if(bash_args.size() > 1) - { - for(auto iter = bash_args.begin() + 1; iter != bash_args.end(); ++iter) + if(tokens[0].size() > 2) + throw libbash::unsupported_exception("declare: " + tokens[0] + " is not supported yet"); + + switch(tokens[0][1]) + { + case 'F': + if(tokens[0][0] == '+') + return 0; + if(tokens.size() > 1) { - // We do not print the type of the variable for now - if(!_walker.is_unset(*iter)) + for(auto iter = tokens.begin() + 1; iter != tokens.end(); ++iter) { - *_out_stream << "declare -- " << *iter << "=\"" << _walker.resolve<std::string>(*iter) << "\"" << std::endl; + if(_walker.has_function(*iter)) + *_out_stream << *iter << std::endl; + else + result = 1; } - else + } + else + { + std::vector<std::string> functions; + + _walker.get_all_function_names(functions); + sort(functions.begin(), functions.end()); + + for(auto iter = functions.begin(); iter != functions.end(); ++iter) + *_out_stream << "declare -f " << *iter << std::endl; + } + return result; + case 'p': + if(tokens.size() > 1) + { + for(auto iter = tokens.begin() + 1; iter != tokens.end(); ++iter) { - *_out_stream << "-bash: declare: " << *iter << ": not found" << std::endl; - result = 1; + // We do not print the type of the variable for now + if(!_walker.is_unset(*iter)) + { + *_out_stream << "declare -- " << *iter << "=\"" << _walker.resolve<std::string>(*iter) << "\"" << std::endl; + } + else + { + *_out_stream << "-bash: declare: " << *iter << ": not found" << std::endl; + result = 1; + } } } - } - else - { - throw libbash::unsupported_exception("We do not support declare -p without arguments for now"); - } - return result; - case 'a': - case 'A': - case 'f': - case 'i': - case 'l': - case 'r': - case 't': - case 'u': - case 'x': - throw libbash::unsupported_exception("declare " + bash_args[0] + " is not supported yet"); - return 1; - default: - throw libbash::illegal_argument_exception("declare: unrecognized option: " + bash_args[0]); - return 1; + else + { + throw libbash::unsupported_exception("We do not support declare -p without arguments for now"); + } + return result; + case 'a': + case 'i': + case 'A': + case 'f': + case 'l': + case 'r': + case 't': + case 'u': + case 'x': + throw libbash::unsupported_exception("declare " + tokens[0] + " is not supported yet"); + return 1; + default: + throw libbash::illegal_argument_exception("declare: unrecognized option: " + tokens[0]); + return 1; + } } + + std::stringstream script; + 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)); + ast.interpret_with(_walker); + + return result; } diff --git a/src/builtins/tests/declare_tests.cpp b/src/builtins/tests/declare_tests.cpp index 19347ac..eec5e41 100644 --- a/src/builtins/tests/declare_tests.cpp +++ b/src/builtins/tests/declare_tests.cpp @@ -55,11 +55,32 @@ namespace TEST(declare_builtin_test, invalid_arguments) { test_declare<libbash::illegal_argument_exception>("declare: arguments required", {}); - test_declare<libbash::unsupported_exception>("declare: multiple arguments are not supported", {"-ap"}); - test_declare<libbash::illegal_argument_exception>("declare: invalid option", {"_a"}); + test_declare<libbash::unsupported_exception>("declare: -ap is not supported yet", {"-ap"}); test_declare<libbash::illegal_argument_exception>("declare: unrecognized option: -L", {"-L"}); } +TEST(declare_built_test, declarations) +{ + interpreter walker; + + EXPECT_EQ(0, cppbash_builtin::exec("declare", {"var"}, cout, cerr, cin, walker)); + + EXPECT_EQ(0, cppbash_builtin::exec("declare", {"foo1=bar"}, cout, cerr, cin, walker)); + EXPECT_STREQ("bar", walker.resolve<std::string>("foo1").c_str()); + + walker.define("foo2", "bar"); + EXPECT_EQ(0, cppbash_builtin::exec("declare", {"foo2"}, cout, cerr, cin, walker)); + EXPECT_STREQ("bar", walker.resolve<std::string>("foo2").c_str()); + + EXPECT_EQ(0, cppbash_builtin::exec("declare", {"var1=foo var2 var3=bar"}, cout, cerr, cin, walker)); + EXPECT_STREQ("foo", walker.resolve<std::string>("var1").c_str()); + EXPECT_STREQ("", walker.resolve<std::string>("var2").c_str()); + EXPECT_STREQ("bar", walker.resolve<std::string>("var3").c_str()); + + EXPECT_EQ(0, cppbash_builtin::exec("declare", {"var=\"foo bar\""}, cout, cerr, cin, walker)); + EXPECT_STREQ("foo bar", walker.resolve<std::string>("var").c_str()); +} + TEST(declare_builtin_test, _F) { stringstream expression("function foo() { :; }; function bar() { :; }"); @@ -68,15 +89,15 @@ TEST(declare_builtin_test, _F) ast.interpret_with(walker); stringstream test_output1; - EXPECT_EQ(0, cppbash_builtin::exec("declare", {"-F", "foo"}, test_output1, cerr, cin, walker)); + EXPECT_EQ(0, cppbash_builtin::exec("declare", {"-F foo"}, test_output1, cerr, cin, walker)); EXPECT_EQ("foo\n", test_output1.str()); stringstream test_output2; - EXPECT_EQ(1, cppbash_builtin::exec("declare", {"-F", "foo", "bar", "test"}, test_output2, cerr, cin, walker)); + EXPECT_EQ(1, cppbash_builtin::exec("declare", {"-F foo bar test"}, test_output2, cerr, cin, walker)); EXPECT_EQ("foo\nbar\n", test_output2.str()); stringstream test_output3; - EXPECT_EQ(0, cppbash_builtin::exec("declare", {"+F", "foo", "bar", "test"}, test_output3, cerr, cin, walker)); + EXPECT_EQ(0, cppbash_builtin::exec("declare", {"+F foo bar test"}, test_output3, cerr, cin, walker)); EXPECT_EQ("", test_output3.str()); stringstream test_output4; @@ -90,11 +111,11 @@ TEST(declare_built_test, _p) walker.define("foo", "bar"); stringstream test_output1; - EXPECT_EQ(0, cppbash_builtin::exec("declare", {"-p", "foo"}, test_output1, cerr, cin, walker)); + EXPECT_EQ(0, cppbash_builtin::exec("declare", {"-p foo"}, test_output1, cerr, cin, walker)); EXPECT_EQ("declare -- foo=\"bar\"\n", test_output1.str()); stringstream test_output2; - EXPECT_EQ(1, cppbash_builtin::exec("declare", {"-p", "bar", "test"}, test_output2, cerr, cin, walker)); + EXPECT_EQ(1, cppbash_builtin::exec("declare", {"-p bar test"}, test_output2, cerr, cin, walker)); EXPECT_EQ("-bash: declare: bar: not found\n-bash: declare: test: not found\n", test_output2.str()); } |