public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [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