* [gentoo-commits] proj/libbash:master commit in: src/core/, bashast/, src/core/tests/, utils/, src/builtins/
@ 2011-06-26 13:38 Petteri Räty
0 siblings, 0 replies; only message in thread
From: Petteri Räty @ 2011-06-26 13:38 UTC (permalink / raw
To: gentoo-commits
commit: ccec9a99b7f370c2b4d4ae872d97385848fb1845
Author: Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Wed Jun 22 13:25:48 2011 +0000
Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Sun Jun 26 14:06:37 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=ccec9a99
Walker: make arithmetic expansion follow POSIX
POSIX requires signed long integer for arithmetic expansion. $? is
implemented in the interpreter class now because POSIX doesn't require
the type of $? to be long. It would cause conversion in many places if
we used long for $?.
---
bashast/libbashWalker.g | 45 ++++++++++++++++++-----------------
src/builtins/inherit_builtin.cpp | 6 ++--
src/core/bash_ast.cpp | 2 +-
src/core/bash_ast.h | 2 +-
src/core/interpreter.cpp | 4 +-
src/core/interpreter.h | 17 +++++++-----
src/core/symbols.hpp | 30 +++++++++++-----------
src/core/tests/interpreter_test.cpp | 16 ++++++------
src/core/tests/symbols_test.cpp | 14 +++++-----
utils/variable_printer.cpp | 2 +-
10 files changed, 71 insertions(+), 67 deletions(-)
diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g
index 1483e0c..f379183 100644
--- a/bashast/libbashWalker.g
+++ b/bashast/libbashWalker.g
@@ -127,10 +127,10 @@ options
return boost::xpressive::regex_match(target, pattern);
}
- /// \brief parse the text value of a tree to integer
+ /// \brief parse the text value of a tree to long
/// \param the target tree
/// \return the parsed value
- int parse_int(ANTLR3_BASE_TREE* tree)
+ long parse_integer(ANTLR3_BASE_TREE* tree)
{
return tree->getText(tree)->toInt32(tree->getText(tree));
}
@@ -524,7 +524,7 @@ var_ref [bool double_quoted] returns[std::string libbash_value]
}
|^(VAR_REF libbash_string=array_name) { walker->get_all_elements_IFS_joined(libbash_string, $libbash_value); }
|^(VAR_REF POUND) { $libbash_value = boost::lexical_cast<std::string>(walker->get_array_length("*")); }
- |^(VAR_REF QMARK) { $libbash_value = walker->get_status<std::string>(); }
+ |^(VAR_REF QMARK) { $libbash_value = boost::lexical_cast<std::string>(walker->get_status()); }
|^(VAR_REF BANG) { std::cerr << "$! has not been implemented yet" << std::endl; }
|^(VAR_REF libbash_string=var_expansion) { $libbash_value = libbash_string; };
@@ -836,7 +836,7 @@ for_expr
for_initilization
:^(FOR_INIT arithmetics);
-for_condition returns[int libbash_value]
+for_condition returns[long libbash_value]
:^(FOR_COND condition=arithmetics) { libbash_value = condition; };
for_modification
@@ -1017,7 +1017,8 @@ primary returns[std::string libbash_value, unsigned index]
};
// shell arithmetic
-arithmetics returns[int value]
+// http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04
+arithmetics returns[long value]
:^(LOGICOR l=arithmetics {
if(l)
{
@@ -1073,23 +1074,23 @@ arithmetics returns[int value]
}
|^(PRE_INCR primary) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) + 1,
+ walker->resolve<long>($primary.libbash_value, $primary.index) + 1,
$primary.index);
}
|^(PRE_DECR primary) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) - 1,
+ walker->resolve<long>($primary.libbash_value, $primary.index) - 1,
$primary.index);
}
|^(POST_INCR primary) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) + 1,
+ walker->resolve<long>($primary.libbash_value, $primary.index) + 1,
$primary.index);
--$value;
}
|^(POST_DECR primary) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) - 1,
+ walker->resolve<long>($primary.libbash_value, $primary.index) - 1,
$primary.index);
++$value;
}
@@ -1098,55 +1099,55 @@ arithmetics returns[int value]
}
|^(MUL_ASSIGN primary l=arithmetics) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) * l,
+ walker->resolve<long>($primary.libbash_value, $primary.index) * l,
$primary.index);
}
|^(DIVIDE_ASSIGN primary l=arithmetics) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) / l,
+ walker->resolve<long>($primary.libbash_value, $primary.index) / l,
$primary.index);
}
|^(MOD_ASSIGN primary l=arithmetics) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) \% l,
+ walker->resolve<long>($primary.libbash_value, $primary.index) \% l,
$primary.index);
}
|^(PLUS_ASSIGN primary l=arithmetics) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) + l,
+ walker->resolve<long>($primary.libbash_value, $primary.index) + l,
$primary.index);
}
|^(MINUS_ASSIGN primary l=arithmetics) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) - l,
+ walker->resolve<long>($primary.libbash_value, $primary.index) - l,
$primary.index);
}
|^(LSHIFT_ASSIGN primary l=arithmetics) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) << l,
+ walker->resolve<long>($primary.libbash_value, $primary.index) << l,
$primary.index);
}
|^(RSHIFT_ASSIGN primary l=arithmetics) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) >> l,
+ walker->resolve<long>($primary.libbash_value, $primary.index) >> l,
$primary.index);
}
|^(AND_ASSIGN primary l=arithmetics) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) & l,
+ walker->resolve<long>($primary.libbash_value, $primary.index) & l,
$primary.index);
}
|^(XOR_ASSIGN primary l=arithmetics) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) ^ l,
+ walker->resolve<long>($primary.libbash_value, $primary.index) ^ l,
$primary.index);
}
|^(OR_ASSIGN primary l=arithmetics) {
$value = walker->set_value($primary.libbash_value,
- walker->resolve<int>($primary.libbash_value, $primary.index) | l,
+ walker->resolve<long>($primary.libbash_value, $primary.index) | l,
$primary.index);
}
- | NUMBER { $value =parse_int($NUMBER);}
- | DIGIT { $value = parse_int($DIGIT);}
- | ^(VAR_REF libbash_string=var_expansion) { $value = boost::lexical_cast<int>(libbash_string); }
+ | NUMBER { $value = parse_integer($NUMBER);}
+ | DIGIT { $value = parse_integer($DIGIT);}
+ | ^(VAR_REF libbash_string = var_expansion) { $value = boost::lexical_cast<long>(libbash_string); }
;
diff --git a/src/builtins/inherit_builtin.cpp b/src/builtins/inherit_builtin.cpp
index 54ba4ac..1490e5b 100644
--- a/src/builtins/inherit_builtin.cpp
+++ b/src/builtins/inherit_builtin.cpp
@@ -58,7 +58,7 @@ inline bool inherit_builtin::hasq(const std::string& value, const std::string& n
// We do not support any QA warning
int inherit_builtin::exec(const std::vector<std::string>& bash_args)
{
- _walker.set_value("ECLASS_DEPTH", _walker.resolve<int>("ECLASS_DEPTH") + 1);
+ _walker.set_value("ECLASS_DEPTH", _walker.resolve<long>("ECLASS_DEPTH") + 1);
// find eclass directory
std::string eclassdir;
@@ -114,8 +114,8 @@ int inherit_builtin::exec(const std::vector<std::string>& bash_args)
_walker.set_value("INHERITED", _walker.resolve<std::string>("INHERITED") + " " + *iter);
}
- _walker.set_value("ECLASS_DEPTH", _walker.resolve<int>("ECLASS_DEPTH") - 1);
- if(_walker.resolve<int>("ECLASS_DEPTH") > 0)
+ _walker.set_value("ECLASS_DEPTH", _walker.resolve<long>("ECLASS_DEPTH") - 1);
+ if(_walker.resolve<long>("ECLASS_DEPTH") > 0)
{
_walker.set_value("ECLASS", PECLASS);
}
diff --git a/src/core/bash_ast.cpp b/src/core/bash_ast.cpp
index 45cec7c..56aef8c 100644
--- a/src/core/bash_ast.cpp
+++ b/src/core/bash_ast.cpp
@@ -176,7 +176,7 @@ void bash_ast::walker_start(plibbashWalker tree_parser)
tree_parser->start(tree_parser);
}
-int bash_ast::walker_arithmetics(plibbashWalker tree_parser)
+long bash_ast::walker_arithmetics(plibbashWalker tree_parser)
{
return tree_parser->arithmetics(tree_parser);
}
diff --git a/src/core/bash_ast.h b/src/core/bash_ast.h
index ae6bb0f..f79608d 100644
--- a/src/core/bash_ast.h
+++ b/src/core/bash_ast.h
@@ -75,7 +75,7 @@ public:
static void walker_start(plibbashWalker tree_parser);
- static int walker_arithmetics(plibbashWalker tree_parser);
+ static long walker_arithmetics(plibbashWalker tree_parser);
static void call_function(plibbashWalker tree_parser,
ANTLR3_MARKER index);
diff --git a/src/core/interpreter.cpp b/src/core/interpreter.cpp
index 267183a..ed9f626 100644
--- a/src/core/interpreter.cpp
+++ b/src/core/interpreter.cpp
@@ -118,7 +118,7 @@ interpreter::interpreter(): _out(&std::cout), _err(&std::cerr), _in(&std::cin),
{'P', false},
{'T', false},
}
- )
+ ), status(0)
{
define("IFS", " \t\n");
// We do not support the options set by the shell itself (such as the -i option)
@@ -430,7 +430,7 @@ void interpreter::set_additional_option(const std::string& name, bool value)
iter->second = value;
}
-int interpreter::eval_arithmetic(const std::string& expression)
+long interpreter::eval_arithmetic(const std::string& expression)
{
bash_ast ast(std::stringstream(expression), &bash_ast::parser_arithmetics);
return ast.interpret_with(*this, &bash_ast::walker_arithmetics);
diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index d44ede4..b0cfda5 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -73,6 +73,10 @@ class interpreter: public boost::noncopyable
// as bash implementation.
std::map<char, bool> options;
+ /// \var private::status
+ /// \brief the return status of the last command
+ int status;
+
/// \brief calculate the correct offset when offset < 0 and check whether
/// the real offset is in legal range
/// \param[in,out] a value/result argument referring to offset
@@ -180,7 +184,7 @@ public:
_out = &std::cout;
}
- /// \brief resolve string/int variable, local scope will be
+ /// \brief resolve string/long variable, local scope will be
/// checked first, then global scope
/// \param variable name
/// \param array index, use index=0 if it's not an array
@@ -245,17 +249,16 @@ public:
/// \brief set the return status of the last command
/// \param the value of the return status
- void set_status(int status)
+ void set_status(int s)
{
- set_value("?", status);
+ status = s;
}
/// \brief get the return status of the last command
/// \param the value of the return status
- template <typename T=int>
- T get_status(void) const
+ int get_status(void) const
{
- return resolve<T>("?");
+ return status;
}
/// \brief unset a variable
@@ -483,7 +486,7 @@ public:
/// \brief evaluate arithmetic expression and return the result
/// \param the arithmetic expression
/// \return the evaluated result
- int eval_arithmetic(const std::string& expression);
+ long eval_arithmetic(const std::string& expression);
/// \brief perform expansion like ${var//foo/bar}
/// \param the value to be expanded
diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
index a5e2e1d..8c6dec7 100644
--- a/src/core/symbols.hpp
+++ b/src/core/symbols.hpp
@@ -46,33 +46,33 @@ class converter: public boost::static_visitor<T>
///
/// \class converter
-/// \brief specialized converter for int
+/// \brief specialized converter for long
///
template<>
-class converter<int>: public boost::static_visitor<int>
+class converter<long>: public boost::static_visitor<long>
{
public:
- /// \brief converter for int value
+ /// \brief converter for long value
/// \param the value to be converted
- /// \return the converted int
- int operator() (const int value) const
+ /// \return the converted long
+ long operator() (const long value) const
{
return value;
}
/// \brief converter for string value
/// \param the value to be converted
- /// \return the converted int
- int operator() (const std::string& value) const
+ /// \return the converted long
+ long operator() (const std::string& value) const
{
- int result = 0;
+ long result = 0;
try
{
- result = boost::lexical_cast<int>(value);
+ result = boost::lexical_cast<long>(value);
}
catch(boost::bad_lexical_cast& e)
{
- std::cerr << "can't cast " << value << " to int" << std::endl;
+ std::cerr << "can't cast " << value << " to long" << std::endl;
}
return result;
}
@@ -87,10 +87,10 @@ class converter<std::string>:
public boost::static_visitor<std::string>
{
public:
- /// \brief converter for int value
+ /// \brief converter for long value
/// \param the value to be converted
/// \return the converted string
- std::string operator() (const int value) const
+ std::string operator() (const long value) const
{
return boost::lexical_cast<std::string>(value);
}
@@ -115,17 +115,17 @@ class variable
std::string name;
/// \var private::value
- /// \brief actual value of the variable. We put string in front of int
+ /// \brief actual value of the variable. We put string in front of long
/// because we want "" as default string value; Otherwise we
/// will get "0".
- std::map<unsigned, boost::variant<std::string, int>> value;
+ std::map<unsigned, boost::variant<std::string, long>> value;
/// \var private::readonly
/// \brief whether the variable is readonly
bool readonly;
public:
- typedef std::map<unsigned, boost::variant<std::string, int>>::size_type size_type;
+ typedef std::map<unsigned, boost::variant<std::string, long>>::size_type size_type;
/// \brief retrieve variable name
/// \return const string value of variable name
diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index c449e3c..d20697b 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -31,9 +31,9 @@ TEST(interpreter, define_resolve_int)
{
interpreter walker;
walker.define("aint", 4);
- EXPECT_EQ(4, walker.resolve<int>("aint"));
- EXPECT_EQ(0, walker.resolve<int>("undefined"));
- EXPECT_EQ(0, walker.resolve<int>(""));
+ EXPECT_EQ(4, walker.resolve<long>("aint"));
+ EXPECT_EQ(0, walker.resolve<long>("undefined"));
+ EXPECT_EQ(0, walker.resolve<long>(""));
}
TEST(interpreter, define_resolve_string)
@@ -57,7 +57,7 @@ TEST(interpreter, define_resolve_array)
walker.define("partial", 10, false, 8);
EXPECT_EQ(1, walker.get_array_length("partial"));
- EXPECT_EQ(10, walker.resolve<int>("partial", 8));
+ EXPECT_EQ(10, walker.resolve<long>("partial", 8));
EXPECT_EQ(0, walker.get_array_length("not exist"));
}
@@ -91,14 +91,14 @@ TEST(interpreter, set_int_value)
interpreter walker;
walker.define("aint", 4);
EXPECT_EQ(10, walker.set_value("aint", 10));
- EXPECT_EQ(10, walker.resolve<int>("aint"));
+ EXPECT_EQ(10, walker.resolve<long>("aint"));
EXPECT_EQ(10, walker.set_value("undefined", 10));
- EXPECT_EQ(10, walker.resolve<int>("undefined"));
+ EXPECT_EQ(10, walker.resolve<long>("undefined"));
walker.define("aint_ro", 4, true);
EXPECT_THROW(walker.set_value("aint_ro", 10),
libbash::readonly_exception);
- EXPECT_EQ(4, walker.resolve<int>("aint_ro"));
+ EXPECT_EQ(4, walker.resolve<long>("aint_ro"));
}
TEST(interpreter, set_string_value)
@@ -138,7 +138,7 @@ TEST(interpreter, get_array_values)
std::map<unsigned, std::string> values = {{0, "1"}, {1, "2"}, {2, "3"}};
walker.define("array", values);
- std::vector<int> array_values;
+ std::vector<long> array_values;
EXPECT_TRUE(walker.resolve_array("array", array_values));
EXPECT_EQ(1, array_values[0]);
EXPECT_EQ(2, array_values[1]);
diff --git a/src/core/tests/symbols_test.cpp b/src/core/tests/symbols_test.cpp
index 1410a05..e5b4649 100644
--- a/src/core/tests/symbols_test.cpp
+++ b/src/core/tests/symbols_test.cpp
@@ -32,14 +32,14 @@ TEST(symbol_test, int_variable)
// readonly integer
variable ro_integer("integer", 10, true);
EXPECT_STREQ("integer", ro_integer.get_name().c_str());
- EXPECT_EQ(10, ro_integer.get_value<int>());
+ EXPECT_EQ(10, ro_integer.get_value<long>());
EXPECT_THROW(ro_integer.set_value(100), libbash::interpreter_exception);
- EXPECT_EQ(10, ro_integer.get_value<int>());
+ EXPECT_EQ(10, ro_integer.get_value<long>());
// normal only integer
variable normal_integer("integer", 10);
normal_integer.set_value(100);
- EXPECT_EQ(100, normal_integer.get_value<int>());
+ EXPECT_EQ(100, normal_integer.get_value<long>());
// get string value of an integer
EXPECT_STREQ("100", normal_integer.get_value<string>().c_str());
@@ -61,9 +61,9 @@ TEST(symbol_test, string_variable)
// string contains integer value
variable int_string("string", "123");
- EXPECT_EQ(123, int_string.get_value<int>());
+ EXPECT_EQ(123, int_string.get_value<long>());
int_string.set_value("abc");
- EXPECT_EQ(0, int_string.get_value<int>());
+ EXPECT_EQ(0, int_string.get_value<long>());
}
TEST(symbol_test, array_variable)
@@ -92,7 +92,7 @@ TEST(symbol_test, array_variable)
EXPECT_STREQ("5", normal_array.get_value<string>(4).c_str());
// get integer value
- EXPECT_EQ(3, normal_array.get_value<int>(2));
+ EXPECT_EQ(3, normal_array.get_value<long>(2));
}
TEST(symbol_test, get_all_values)
@@ -114,7 +114,7 @@ TEST(symbol_test, get_all_values)
EXPECT_STREQ("1", string_values[0].c_str());
variable an_int("foo", 10);
- vector<int> int_values;
+ vector<long> int_values;
an_int.get_all_values(int_values);
EXPECT_EQ(1, int_values.size());
EXPECT_EQ(10, int_values[0]);
diff --git a/utils/variable_printer.cpp b/utils/variable_printer.cpp
index a8a948f..d44dc35 100644
--- a/utils/variable_printer.cpp
+++ b/utils/variable_printer.cpp
@@ -33,7 +33,7 @@
static const std::vector<std::string> special_variables
{
- "IFS", "?", "*", "0", "-"
+ "IFS", "*", "0", "-"
};
static std::string get_src_dir()
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2011-06-26 13:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-26 13:38 [gentoo-commits] proj/libbash:master commit in: src/core/, bashast/, src/core/tests/, utils/, src/builtins/ Petteri Räty
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox