aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndré Aparício <aparicio99@gmail.com>2012-06-19 17:46:40 +0100
committerMu Qiao <qiaomuf@gentoo.org>2012-07-20 09:20:22 +0800
commitf9501f5d7ad82d273cab44cd96114d644fb5772d (patch)
tree8a0639ad40b65f460cdb7409ea94ffc52d7fd67b /src
parentReplace boost::scoped_ptr with std::unique_ptr (diff)
downloadlibbash-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.cpp144
-rw-r--r--src/builtins/tests/declare_tests.cpp35
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());
}