diff options
author | Mu Qiao <qiaomuf@gentoo.org> | 2011-07-21 23:41:08 +0800 |
---|---|---|
committer | Mu Qiao <qiaomuf@gentoo.org> | 2011-08-02 15:46:29 +0800 |
commit | 2a7c39aed496a03d4e0fe184bafbc34d50c87bd5 (patch) | |
tree | 20768a3eaacc1b2bbe53bf1c016ef5a7a9a71f26 | |
parent | Parser: allow filename expansion characters (diff) | |
download | libbash-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.am | 2 | ||||
-rw-r--r-- | bashast/bashast.g | 11 | ||||
-rw-r--r-- | bashast/gunit/array.gunit | 3 | ||||
-rw-r--r-- | bashast/gunit/pipeline.gunit | 2 | ||||
-rw-r--r-- | bashast/libbashWalker.g | 5 | ||||
-rw-r--r-- | src/builtins/export_builtin.cpp | 46 | ||||
-rw-r--r-- | src/builtins/export_builtin.h | 46 | ||||
-rw-r--r-- | src/core/bash_ast.cpp | 5 | ||||
-rw-r--r-- | src/core/bash_ast.h | 4 | ||||
-rw-r--r-- | src/cppbash_builtin.cpp | 2 |
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*>()}, |