From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1QSTix-0002cv-Bo for garchives@archives.gentoo.org; Fri, 03 Jun 2011 12:43:35 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 71EF01C0BF; Fri, 3 Jun 2011 12:43:18 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id 286C31C013 for ; Fri, 3 Jun 2011 12:43:18 +0000 (UTC) Received: from pelican.gentoo.org (unknown [66.219.59.40]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id A2D451BC002 for ; Fri, 3 Jun 2011 12:43:17 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by pelican.gentoo.org (Postfix) with ESMTP id 079868050C for ; Fri, 3 Jun 2011 12:43:17 +0000 (UTC) From: "Petteri Räty" To: gentoo-commits@lists.gentoo.org Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Petteri Räty" Message-ID: <7404d1ac1630b41a94edcfe791dcda1473d11437.betelgeuse@gentoo> Subject: [gentoo-commits] proj/libbash:master commit in: scripts/, src/core/, bashast/, src/core/tests/ X-VCS-Repository: proj/libbash X-VCS-Files: bashast/libbashWalker.g scripts/test_expr.bash scripts/test_expr.bash.result src/core/bash_condition.cpp src/core/bash_condition.h src/core/interpreter.cpp src/core/interpreter.h src/core/tests/bash_condition_test.cpp X-VCS-Directories: scripts/ src/core/ bashast/ src/core/tests/ X-VCS-Committer: betelgeuse X-VCS-Committer-Name: Petteri Räty X-VCS-Revision: 7404d1ac1630b41a94edcfe791dcda1473d11437 Date: Fri, 3 Jun 2011 12:43:17 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: X-Archives-Hash: b1aed2aee62a4d6c590ecf726d574c06 commit: 7404d1ac1630b41a94edcfe791dcda1473d11437 Author: Mu Qiao gentoo org> AuthorDate: Wed Jun 1 10:17:57 2011 +0000 Commit: Petteri R=C3=A4ty gentoo org> CommitDate: Wed Jun 1 13:27:34 2011 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/libbash.git;a= =3Dcommit;h=3D7404d1ac Core: support arithmetic expression in keyword test --- bashast/libbashWalker.g | 2 +- scripts/test_expr.bash | 4 ++ scripts/test_expr.bash.result | 1 + src/core/bash_condition.cpp | 17 +++++---- src/core/bash_condition.h | 5 ++- src/core/interpreter.cpp | 7 ++++ src/core/interpreter.h | 5 +++ src/core/tests/bash_condition_test.cpp | 62 ++++++++++++++++++--------= ------ 8 files changed, 67 insertions(+), 36 deletions(-) diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g index a55e0b2..ec3897d 100644 --- a/bashast/libbashWalker.g +++ b/bashast/libbashWalker.g @@ -556,7 +556,7 @@ common_condition returns[bool status] } // -eq, -ne, -lt, -le, -gt, or -ge for arithmetic. -nt -ot -ef for file= s :^(NAME left_str=3Dstring_expr right_str=3Dstring_expr) { - $status =3D internal::test_binary(walker->get_string($NAME), left_str.= libbash_value, right_str.libbash_value); + $status =3D internal::test_binary(walker->get_string($NAME), left_str.= libbash_value, right_str.libbash_value, *walker); } // -o for shell option, -z -n for string, -abcdefghkprstuwxOGLSN for f= iles |^(op=3DLETTER string_expr) { diff --git a/scripts/test_expr.bash b/scripts/test_expr.bash index 79398dd..1fa00b4 100644 --- a/scripts/test_expr.bash +++ b/scripts/test_expr.bash @@ -44,3 +44,7 @@ echo $? # 0 [[ "abc def xyz" !=3D *"defg"* ]] && echo "true14" shopt -s extglob [[ "123" =3D=3D *([[:digit:]]) ]] && echo "true15" +i=3D2 +[[ i++ -gt 2 ]] && echo wrong +[[ i++ -gt 2 ]] && echo true16 +unset i diff --git a/scripts/test_expr.bash.result b/scripts/test_expr.bash.resul= t index 653200b..e883295 100644 --- a/scripts/test_expr.bash.result +++ b/scripts/test_expr.bash.result @@ -22,3 +22,4 @@ true12 true13 true14 true15 +true16 diff --git a/src/core/bash_condition.cpp b/src/core/bash_condition.cpp index 48b523e..1e44299 100644 --- a/src/core/bash_condition.cpp +++ b/src/core/bash_condition.cpp @@ -27,6 +27,8 @@ #include #include =20 +#include "core/bash_ast.h" +#include "core/interpreter.h" #include "core/interpreter_exception.h" =20 #include "core/bash_condition.h" @@ -147,7 +149,8 @@ namespace =20 bool internal::test_binary(const std::string& op, const std::string& lhs, - const std::string& rhs) + const std::string& rhs, + interpreter& walker) { if(op.size() !=3D 2) throw interpreter_exception("Unrecognized operator " + op); @@ -163,17 +166,17 @@ bool internal::test_binary(const std::string& op, // We do not support arithmetic expressions inside keyword test for = now. // So the operands can only be raw integers. else if(op =3D=3D "eq") - return boost::lexical_cast(lhs) =3D=3D boost::lexical_cast(rhs); + return walker.eval_arithmetic(lhs) =3D=3D walker.eval_arithmetic(r= hs); else if(op =3D=3D "ne") - return boost::lexical_cast(lhs) !=3D boost::lexical_cast= (rhs); + return walker.eval_arithmetic(lhs) !=3D walker.eval_arithmetic(rhs= ); else if(op =3D=3D "lt") - return boost::lexical_cast(lhs) < boost::lexical_cast(rh= s); + return walker.eval_arithmetic(lhs) < walker.eval_arithmetic(rhs); else if(op =3D=3D "le") - return boost::lexical_cast(lhs) <=3D boost::lexical_cast= (rhs); + return walker.eval_arithmetic(lhs) <=3D walker.eval_arithmetic(rhs= ); else if(op =3D=3D "gt") - return boost::lexical_cast(lhs) > boost::lexical_cast(rh= s); + return walker.eval_arithmetic(lhs) > walker.eval_arithmetic(rhs); else if(op =3D=3D "ge") - return boost::lexical_cast(lhs) >=3D boost::lexical_cast= (rhs); + return walker.eval_arithmetic(lhs) >=3D walker.eval_arithmetic(rhs= ); else throw interpreter_exception("Unrecognized operator " + op); } diff --git a/src/core/bash_condition.h b/src/core/bash_condition.h index 8723c28..2df1ec7 100644 --- a/src/core/bash_condition.h +++ b/src/core/bash_condition.h @@ -26,13 +26,16 @@ =20 #include =20 +class interpreter; + namespace internal { bool test_unary(char op, const std::string& target); =20 bool test_binary(const std::string& op, const std::string& lhs, - const std::string& rhs); + const std::string& rhs, + interpreter& walker); } =20 #endif diff --git a/src/core/interpreter.cpp b/src/core/interpreter.cpp index fc12a7a..83fd29a 100644 --- a/src/core/interpreter.cpp +++ b/src/core/interpreter.cpp @@ -35,6 +35,7 @@ #include #include =20 +#include "core/bash_ast.h" #include "core/unset_exception.h" #include "libbashWalker.h" =20 @@ -412,3 +413,9 @@ void interpreter::set_option(const std::string& name,= bool value) =20 iter->second =3D value; } + +int interpreter::eval_arithmetic(const std::string& expression) +{ + bash_ast ast(std::stringstream(expression), &bash_ast::parser_arithmet= ics); + return ast.interpret_with(*this, &bash_ast::walker_arithmetics); +} diff --git a/src/core/interpreter.h b/src/core/interpreter.h index 3420ee4..dc2a9bc 100644 --- a/src/core/interpreter.h +++ b/src/core/interpreter.h @@ -675,6 +675,11 @@ public: /// \return zero unless the name is not a valid shell option void set_option(const std::string& name, bool value); =20 + /// \brief evaluate arithmetic expression and return the result + /// \param the arithmetic expression + /// \return the evaluated result + int eval_arithmetic(const std::string& expression); + /// \brief perform expansion like ${var//foo/bar} /// \param the value to be expanded /// \param the pattern used to match the value diff --git a/src/core/tests/bash_condition_test.cpp b/src/core/tests/bash= _condition_test.cpp index de56fee..18a4e18 100644 --- a/src/core/tests/bash_condition_test.cpp +++ b/src/core/tests/bash_condition_test.cpp @@ -31,6 +31,7 @@ #include =20 #include "core/bash_condition.h" +#include "core/interpreter.h" #include "core/interpreter_exception.h" =20 namespace @@ -140,45 +141,52 @@ TEST(bash_condition, string_unary_operator) =20 TEST_F(file_test, binary_operator) { - EXPECT_TRUE(internal::test_binary("nt", negative, positive)); - EXPECT_FALSE(internal::test_binary("ot", negative, positive)); + interpreter walker; + EXPECT_TRUE(internal::test_binary("nt", negative, positive, walker)); + EXPECT_FALSE(internal::test_binary("ot", negative, positive, walker)); =20 - EXPECT_TRUE(internal::test_binary("ot", positive, negative)); - EXPECT_FALSE(internal::test_binary("nt", positive, negative)); + EXPECT_TRUE(internal::test_binary("ot", positive, negative, walker)); + EXPECT_FALSE(internal::test_binary("nt", positive, negative, walker)); =20 - EXPECT_FALSE(internal::test_binary("ot", positive, positive)); - EXPECT_FALSE(internal::test_binary("nt", positive, positive)); + EXPECT_FALSE(internal::test_binary("ot", positive, positive, walker)); + EXPECT_FALSE(internal::test_binary("nt", positive, positive, walker)); =20 - EXPECT_TRUE(internal::test_binary("ef", positive, positive)); - EXPECT_FALSE(internal::test_binary("ef", positive, negative)); - EXPECT_FALSE(internal::test_binary("ef", "not exist", negative)); + EXPECT_TRUE(internal::test_binary("ef", positive, positive, walker)); + EXPECT_FALSE(internal::test_binary("ef", positive, negative, walker)); + EXPECT_FALSE(internal::test_binary("ef", "not exist", negative, walker= )); =20 - EXPECT_THROW(internal::test_binary("efd", positive, negative), interpr= eter_exception); + EXPECT_THROW(internal::test_binary("efd", positive, negative, walker),= interpreter_exception); } =20 TEST(bash_condition, arithmetic_operator) { - EXPECT_TRUE(internal::test_binary("eq", "1", "1")); - EXPECT_FALSE(internal::test_binary("eq", "2", "1")); + interpreter walker; + walker.define("foo", 1); =20 - EXPECT_TRUE(internal::test_binary("ne", "2", "1")); - EXPECT_FALSE(internal::test_binary("ne", "1", "1")); + EXPECT_TRUE(internal::test_binary("eq", "1", "1", walker)); + EXPECT_FALSE(internal::test_binary("eq", "2", "1", walker)); =20 - EXPECT_TRUE(internal::test_binary("lt", "0", "1")); - EXPECT_FALSE(internal::test_binary("lt", "1", "1")); - EXPECT_FALSE(internal::test_binary("lt", "2", "1")); + EXPECT_TRUE(internal::test_binary("ne", "2", "1", walker)); + EXPECT_FALSE(internal::test_binary("ne", "1", "1", walker)); =20 - EXPECT_TRUE(internal::test_binary("le", "0", "1")); - EXPECT_TRUE(internal::test_binary("le", "1", "1")); - EXPECT_FALSE(internal::test_binary("le", "2", "1")); + EXPECT_TRUE(internal::test_binary("lt", "0", "1", walker)); + EXPECT_FALSE(internal::test_binary("lt", "1", "1", walker)); + EXPECT_FALSE(internal::test_binary("lt", "2", "1", walker)); =20 - EXPECT_TRUE(internal::test_binary("gt", "1", "0")); - EXPECT_FALSE(internal::test_binary("gt", "1", "1")); - EXPECT_FALSE(internal::test_binary("gt", "0", "1")); + EXPECT_TRUE(internal::test_binary("le", "0", "1", walker)); + EXPECT_TRUE(internal::test_binary("le", "1", "1", walker)); + EXPECT_FALSE(internal::test_binary("le", "2", "1", walker)); =20 - EXPECT_TRUE(internal::test_binary("ge", "1", "1")); - EXPECT_TRUE(internal::test_binary("ge", "2", "1")); - EXPECT_FALSE(internal::test_binary("ge", "0", "1")); + EXPECT_TRUE(internal::test_binary("gt", "1", "0", walker)); + EXPECT_FALSE(internal::test_binary("gt", "1", "1", walker)); + EXPECT_FALSE(internal::test_binary("gt", "0", "1", walker)); =20 - EXPECT_FALSE(internal::test_binary("ge", "blah", "1")); + EXPECT_TRUE(internal::test_binary("ge", "1", "1", walker)); + EXPECT_TRUE(internal::test_binary("ge", "2", "1", walker)); + EXPECT_FALSE(internal::test_binary("ge", "0", "1", walker)); + + EXPECT_FALSE(internal::test_binary("ge", "blah", "1", walker)); + + EXPECT_FALSE(internal::test_binary("ge", "foo++", "2", walker)); + EXPECT_TRUE(internal::test_binary("ge", "foo++", "2", walker)); }