aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMu Qiao <qiaomuf@gentoo.org>2011-07-21 23:41:08 +0800
committerMu Qiao <qiaomuf@gentoo.org>2011-08-02 15:46:29 +0800
commit2a7c39aed496a03d4e0fe184bafbc34d50c87bd5 (patch)
tree20768a3eaacc1b2bbe53bf1c016ef5a7a9a71f26
parentParser: allow filename expansion characters (diff)
downloadlibbash-2a7c39aed496a03d4e0fe184bafbc34d50c87bd5.tar.gz
libbash-2a7c39aed496a03d4e0fe184bafbc34d50c87bd5.tar.bz2
libbash-2a7c39aed496a03d4e0fe184bafbc34d50c87bd5.zip
Parser&Walker: reimplement export built-in
Now export built-in will call back to parser grammar in order to support array definition.
-rw-r--r--Makefile.am2
-rw-r--r--bashast/bashast.g11
-rw-r--r--bashast/gunit/array.gunit3
-rw-r--r--bashast/gunit/pipeline.gunit2
-rw-r--r--bashast/libbashWalker.g5
-rw-r--r--src/builtins/export_builtin.cpp46
-rw-r--r--src/builtins/export_builtin.h46
-rw-r--r--src/core/bash_ast.cpp5
-rw-r--r--src/core/bash_ast.h4
-rw-r--r--src/cppbash_builtin.cpp2
10 files changed, 118 insertions, 8 deletions
diff --git a/Makefile.am b/Makefile.am
index 4ef9622..97652a8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -196,6 +196,8 @@ libcppbash_la_SOURCES = src/common.h \
src/builtins/echo_builtin.h \
src/builtins/eval_builtin.cpp \
src/builtins/eval_builtin.h \
+ src/builtins/export_builtin.cpp \
+ src/builtins/export_builtin.h \
src/builtins/declare_builtin.cpp \
src/builtins/declare_builtin.h \
src/builtins/boolean_builtins.h \
diff --git a/bashast/bashast.g b/bashast/bashast.g
index 2709fc5..3b9b5bd 100644
--- a/bashast/bashast.g
+++ b/bashast/bashast.g
@@ -313,11 +313,12 @@ command_atom
: (FOR|SELECT|IF|WHILE|UNTIL|CASE|LPAREN|LBRACE|LLPAREN|LSQUARE|TEST_EXPR) => compound_command
| FUNCTION BLANK string_expr_no_reserved_word ((BLANK? parens wspace?)|wspace) compound_command
-> ^(FUNCTION string_expr_no_reserved_word compound_command)
- | (name (LSQUARE|EQUALS|PLUS EQUALS)|LOCAL|EXPORT) => variable_definitions
+ | (name (LSQUARE|EQUALS|PLUS EQUALS)|LOCAL) => variable_definitions
(
(BLANK bash_command) => BLANK bash_command -> bash_command variable_definitions
| -> ^(VARIABLE_DEFINITIONS variable_definitions)
)
+ | (EXPORT) => EXPORT BLANK export_item -> ^(STRING EXPORT) ^(STRING ^(DOUBLE_QUOTED_STRING export_item))
| string_expr_no_reserved_word
(
(BLANK? parens) => BLANK? parens wspace? compound_command
@@ -355,7 +356,6 @@ variable_definitions
: (
variable_definition_atom ((BLANK name (LSQUARE|EQUALS|PLUS EQUALS)) => BLANK! variable_definition_atom)*
| (LOCAL) => LOCAL BLANK! local_item ((BLANK name) => BLANK! local_item)*
- | (EXPORT) => EXPORT! ((BLANK name) => BLANK! export_item)+
);
variable_definition_atom
@@ -406,6 +406,13 @@ local_item
#endif
} ->;
export_item
+ : ((~EOL) => (string_expr_part|BLANK|LPAREN|RPAREN))+;
+
+builtin_variable_definitions
+ : (builtin_variable_definition_atom) (BLANK builtin_variable_definition_atom)*
+ -> ^(LIST ^(COMMAND ^(VARIABLE_DEFINITIONS builtin_variable_definition_atom +)));
+
+builtin_variable_definition_atom
: variable_definition_atom
| name ->;
diff --git a/bashast/gunit/array.gunit b/bashast/gunit/array.gunit
index c304e7c..734343f 100644
--- a/bashast/gunit/array.gunit
+++ b/bashast/gunit/array.gunit
@@ -31,6 +31,9 @@ variable_definition_atom:
"asdf+=()" -> (PLUS_ASSIGN asdf ARRAY)
"asdf+=(a)" -> (PLUS_ASSIGN asdf (ARRAY (STRING a)))
+builtin_variable_definitions:
+"asdf=(a b c d) ade acd=bde" -> (LIST (COMMAND (VARIABLE_DEFINITIONS (= asdf (ARRAY (STRING a) (STRING b) (STRING c) (STRING d))) (= acd (STRING bde)))))
+
variable_reference:
"$asdf" -> (VAR_REF asdf)
"${asdf[0]:-default}" -> (VAR_REF (USE_DEFAULT_WHEN_UNSET_OR_NULL (asdf 0) (STRING default)))
diff --git a/bashast/gunit/pipeline.gunit b/bashast/gunit/pipeline.gunit
index ec6deda..8f6dd43 100644
--- a/bashast/gunit/pipeline.gunit
+++ b/bashast/gunit/pipeline.gunit
@@ -20,7 +20,7 @@ gunit java_libbash;
pipeline:
"cat asdf" -> (COMMAND (STRING cat) (STRING asdf))
-"export VAR=bar LAA=laa foo" -> (COMMAND (VARIABLE_DEFINITIONS (= VAR (STRING bar)) (= LAA (STRING laa))))
+"export VAR=bar LAA=(1 2 3) foo" -> (COMMAND (STRING export) (STRING (DOUBLE_QUOTED_STRING VAR = bar LAA = ( 1 2 3 ) foo)))
"LOCAL1=a LOCAL2=b export GLOBAL1=2 GLOBAL2 GLOBAL3" -> (COMMAND (STRING export) (STRING GLOBAL1 = 2) (STRING GLOBAL2) (STRING GLOBAL3) (= LOCAL1 (STRING a)) (= LOCAL2 (STRING b)))
"time -p cat file" -> (COMMAND (STRING cat) (STRING file) (time p))
"time cat file | grep search" -> (| (COMMAND (STRING cat) (STRING file) time) (COMMAND (STRING grep) (STRING search)))
diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g
index 2ee887c..25bfcb2 100644
--- a/bashast/libbashWalker.g
+++ b/bashast/libbashWalker.g
@@ -602,11 +602,6 @@ execute_command[const std::string& name, std::vector<std::string>& libbash_args]
{
walker->set_status(walker->execute_builtin(name, libbash_args, out.get(), err.get(), in.get()));
}
- else if(name == "export")
- {
- std::cerr << "We do not support command env before the export builtin." << std::endl;
- walker->set_status(1);
- }
else
{
walker->set_status(1);
diff --git a/src/builtins/export_builtin.cpp b/src/builtins/export_builtin.cpp
new file mode 100644
index 0000000..2086cea
--- /dev/null
+++ b/src/builtins/export_builtin.cpp
@@ -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 export_builtin.h
+/// \brief class that implements the export builtin
+///
+
+#include "builtins/export_builtin.h"
+
+#include <sstream>
+
+#include "core/bash_ast.h"
+#include "core/interpreter.h"
+
+int export_builtin::exec(const std::vector<std::string>& bash_args)
+{
+ std::stringstream script;
+ for(auto iter = bash_args.begin(); iter != bash_args.end(); ++iter)
+ script << *iter;
+
+ // Check if there is variable definition. If there isn't, parser_builtin_variable_definitions
+ // will generate empty AST, which is not what we want.
+ if(script.str().find("=") != std::string::npos)
+ {
+ bash_ast ast(script, &bash_ast::parser_builtin_variable_definitions);
+ ast.interpret_with(_walker);
+ }
+
+ return 0;
+}
diff --git a/src/builtins/export_builtin.h b/src/builtins/export_builtin.h
new file mode 100644
index 0000000..9ed5d70
--- /dev/null
+++ b/src/builtins/export_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 export_builtin.h
+/// \brief class that implements the export builtin
+///
+
+#ifndef LIBBASH_BUILTINS_export_BUILTIN_H_
+#define LIBBASH_BUILTINS_export_BUILTIN_H_
+
+#include "cppbash_builtin.h"
+
+///
+/// \class export_builtin
+/// \brief the export builtin for bash
+///
+class export_builtin: public virtual cppbash_builtin
+{
+ public:
+ BUILTIN_CONSTRUCTOR(export)
+
+ ///
+ /// \brief runs the export builtin on the supplied arguments
+ /// \param bash_args the arguments to the export builtin
+ /// \return exit status of export
+ ///
+ virtual int exec(const std::vector<std::string>& bash_args);
+};
+
+#endif
diff --git a/src/core/bash_ast.cpp b/src/core/bash_ast.cpp
index f3afc30..5b2ac68 100644
--- a/src/core/bash_ast.cpp
+++ b/src/core/bash_ast.cpp
@@ -237,6 +237,11 @@ pANTLR3_BASE_TREE bash_ast::parser_all_expansions(libbashParser_Ctx_struct* pars
return parser->all_expansions(parser).tree;
}
+pANTLR3_BASE_TREE bash_ast::parser_builtin_variable_definitions(libbashParser_Ctx_struct* parser)
+{
+ return parser->builtin_variable_definitions(parser).tree;
+}
+
void bash_ast::call_function(plibbashWalker ctx,
ANTLR3_MARKER index)
{
diff --git a/src/core/bash_ast.h b/src/core/bash_ast.h
index fcf031c..bd7ecf8 100644
--- a/src/core/bash_ast.h
+++ b/src/core/bash_ast.h
@@ -115,6 +115,10 @@ public:
/// \param parser the pointer to the parser
static pANTLR3_BASE_TREE parser_all_expansions(libbashParser_Ctx_struct* parser);
+ /// \brief the functor for parser builtin_variable_definitions rule
+ /// \param parser the pointer to the parser
+ static pANTLR3_BASE_TREE parser_builtin_variable_definitions(libbashParser_Ctx_struct* parser);
+
///
/// \brief interpret the script with a given interpreter
/// \param walker the interpreter object
diff --git a/src/cppbash_builtin.cpp b/src/cppbash_builtin.cpp
index c8eb5b9..03620d1 100644
--- a/src/cppbash_builtin.cpp
+++ b/src/cppbash_builtin.cpp
@@ -34,6 +34,7 @@
#include "builtins/declare_builtin.h"
#include "builtins/echo_builtin.h"
#include "builtins/eval_builtin.h"
+#include "builtins/export_builtin.h"
#include "builtins/inherit_builtin.h"
#include "builtins/let_builtin.h"
#include "builtins/return_builtin.h"
@@ -57,6 +58,7 @@ cppbash_builtin::builtins_type& cppbash_builtin::builtins() {
{"continue", boost::factory<continue_builtin*>()},
{"echo", boost::factory<echo_builtin*>()},
{"eval", boost::factory<eval_builtin*>()},
+ {"export", boost::factory<export_builtin*>()},
{"declare", boost::factory<declare_builtin*>()},
{"source", boost::factory<source_builtin*>()},
{"shift", boost::factory<shift_builtin*>()},