public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-03-30 12:48 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-03-30 12:48 UTC (permalink / raw
  To: gentoo-commits

commit:     f6170deb407d04d2e5f823ec1e15e9777754b488
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Mon Mar 28 13:03:29 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Tue Mar 29 04:34:47 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=f6170deb

Change the logic when setting a variable value

When setting a variable's value, will define it if it doesn't exist,
and then return the default value. Otherwise return the original
value.

---
 src/core/interpreter.h              |   18 ++++++++++++++----
 src/core/tests/interpreter_test.cpp |   14 +++++++-------
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index b494b6a..0833e02 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -303,16 +303,26 @@ public:
   }
 
   /// \brief update the variable value, raise interpreter_exception if
-  ///        it's readonly, do thing if the variable doesn't exist
+  ///        it's readonly, will define the variable if it doesn't exist
   /// \param variable name
   /// \param new value
+  /// \return the original value of the variable, will call default
+  ///         constructor if the variable doesn't exist
   template <typename T>
-  void set_value(const std::string& name, const T& new_value)
+  T set_value(const std::string& name, const T& new_value)
   {
     std::shared_ptr<symbol> value = members.resolve(name);
+    T old_value{};
     if(!value)
-      return;
-    std::static_pointer_cast<variable>(value)->set_value(new_value);
+    {
+      define(name, new_value, false);
+    }
+    else
+    {
+      old_value = std::static_pointer_cast<variable>(value)->get_value<T>();
+      std::static_pointer_cast<variable>(value)->set_value(new_value);
+    }
+    return old_value;
   }
 
   /// \brief define a new variable

diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index 0dbeedc..b183b0b 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -48,10 +48,10 @@ TEST(interpreter, set_int_value)
 {
   interpreter walker;
   walker.define("aint", 4);
-  walker.set_value("aint", 10);
+  EXPECT_EQ(4, walker.set_value("aint", 10));
   EXPECT_EQ(10, walker.resolve<int>("aint"));
-  walker.set_value("undefined", 10);
-  EXPECT_EQ(0, walker.resolve<int>("undefined"));
+  EXPECT_EQ(0, walker.set_value("undefined", 10));
+  EXPECT_EQ(10, walker.resolve<int>("undefined"));
 
   walker.define("aint_ro", 4, true);
   EXPECT_THROW(walker.set_value("aint_ro", 10),
@@ -63,13 +63,13 @@ TEST(interpreter, set_string_value)
 {
   interpreter walker;
   walker.define("astring", "hi");
-  walker.set_value("astring", "hello");
+  EXPECT_STREQ("hi", walker.set_value<string>("astring", "hello").c_str());
   EXPECT_STREQ("hello", walker.resolve<string>("astring").c_str());
-  walker.set_value("undefined", "hello");
-  EXPECT_STREQ("", walker.resolve<string>("undefined").c_str());
+  EXPECT_STREQ("", walker.set_value<string>("undefined", "hello").c_str());
+  EXPECT_STREQ("hello", walker.resolve<string>("undefined").c_str());
 
   walker.define("astring_ro", "hi", true);
-  EXPECT_THROW(walker.set_value("astring_ro", "hello"),
+  EXPECT_THROW(walker.set_value<string>("astring_ro", "hello"),
                interpreter_exception);
   EXPECT_STREQ("hi", walker.resolve<string>("astring_ro").c_str());
 }



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-04-04 15:52 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-04-04 15:52 UTC (permalink / raw
  To: gentoo-commits

commit:     8b4e14c2089780faa5e5d705821491648cfc926e
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Mon Apr  4 05:16:55 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Mon Apr  4 09:49:41 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=8b4e14c2

Add a member indicating whether a variable is null

---
 src/core/interpreter.h              |   19 +++++++++++++++++--
 src/core/symbols.hpp                |   22 +++++++++++++++++++---
 src/core/tests/interpreter_test.cpp |    9 +++++++++
 src/core/tests/symbols_test.cpp     |    9 +++++++++
 4 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index ef95caa..858916e 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -358,6 +358,19 @@ public:
     return std::static_pointer_cast<variable>(value)->get_value<T>();
   }
 
+  /// \brief check whether the value of the variable is null, return true
+  ///        if the variable is undefined
+  /// \param variable name
+  /// \return whether the value of the variable is null
+  bool is_null(const std::string& name)
+  {
+    std::shared_ptr<symbol> value = members.resolve(name);
+    if(value)
+      return std::static_pointer_cast<variable>(value)->is_null();
+    else
+      return true;
+  }
+
   /// \brief update the variable value, raise interpreter_exception if
   ///        it's readonly, will define the variable if it doesn't exist
   /// \param variable name
@@ -378,13 +391,15 @@ public:
   /// \param the name of the variable
   /// \param the value of the variable
   /// \param whether it's readonly, default is false
+  /// \param whether it's null, default is false
   template <typename T>
   void define(const std::string& name,
               const T& value,
-              bool readonly=false)
+              bool readonly=false,
+              bool is_null=false)
   {
     std::shared_ptr<variable> target(
-        new variable(name, value, readonly));
+        new variable(name, value, readonly, is_null));
     members.define(target);
   }
 };

diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
index 53b699e..a4ae514 100644
--- a/src/core/symbols.hpp
+++ b/src/core/symbols.hpp
@@ -141,10 +141,17 @@ class variable: public symbol
   /// \brief whether the symbol is readonly
   bool readonly;
 
+  /// \var private::null_value
+  /// \brief whether the symbol is null 
+  bool null_value;
+
 public:
   template <typename T>
-  variable(const std::string& name, T v, bool ro=false)
-    : symbol(name), value(v), readonly(ro){}
+  variable(const std::string& name,
+           T v,
+           bool ro=false,
+           bool is_null=false)
+    : symbol(name), value(v), readonly(ro), null_value(is_null){}
 
   /// \brief retrieve actual value of the symbol
   /// \return the value of the symbol
@@ -157,13 +164,22 @@ public:
 
   /// \brief set the value of the symbol, raise exception if it's readonly
   /// \param the new value to be set
+  /// \param whether to set the variable to null value, default is false
   template <typename T>
-  void set_value(T new_value)
+  void set_value(T new_value, bool is_null=false)
   {
     if(readonly)
       throw interpreter_exception(get_name() + " is readonly variable");
+    null_value = is_null;
     value = new_value;
   }
+
+  /// \brief check whether the value of the variable is null
+  /// \return whether the value of the variable is null
+  bool is_null() const
+  {
+    return null_value;
+  }
 };
 
 ///

diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index e5976e5..c3f7888 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -44,6 +44,15 @@ TEST(interpreter, define_resolve_string)
   EXPECT_STREQ("", walker.resolve<string>("undefined").c_str());
 }
 
+TEST(interpreter, is_null)
+{
+  interpreter walker;
+  walker.define("foo", "hello");
+  EXPECT_FALSE(walker.is_null("foo"));
+  walker.define("foo", "hello", false, true);
+  EXPECT_TRUE(walker.is_null("foo"));
+}
+
 TEST(interpreter, set_int_value)
 {
   interpreter walker;

diff --git a/src/core/tests/symbols_test.cpp b/src/core/tests/symbols_test.cpp
index 891e9cb..7620be0 100644
--- a/src/core/tests/symbols_test.cpp
+++ b/src/core/tests/symbols_test.cpp
@@ -65,6 +65,15 @@ TEST(symbol_test, string_variable)
   EXPECT_EQ(123, int_string.get_value<int>());
 }
 
+TEST(symbol_test, is_null)
+{
+  variable var("foo", 10);
+  EXPECT_FALSE(var.is_null());
+  var.set_value("bar", true);
+  EXPECT_TRUE(var.is_null());
+  EXPECT_TRUE(variable("foo", "", false, true).is_null());
+}
+
 TEST(scope_test, define_resolve)
 {
   scope members;



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-04-04 15:52 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-04-04 15:52 UTC (permalink / raw
  To: gentoo-commits

commit:     dc956e48bb51489eccf1be4793d556490aac2278
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Mon Apr  4 05:29:06 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Mon Apr  4 15:09:07 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=dc956e48

Add a method indicating whether a variable is unset

---
 src/core/interpreter.h              |    8 ++++++++
 src/core/tests/interpreter_test.cpp |    8 ++++++++
 2 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index 858916e..1ce1076 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -371,6 +371,14 @@ public:
       return true;
   }
 
+  /// \brief check whether the value of the variable is unset
+  /// \param variable name
+  /// \return whether the value of the variable is unset
+  bool is_unset(const std::string& name)
+  {
+    return !members.resolve(name);
+  }
+
   /// \brief update the variable value, raise interpreter_exception if
   ///        it's readonly, will define the variable if it doesn't exist
   /// \param variable name

diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index c3f7888..6f8d0c4 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -53,6 +53,14 @@ TEST(interpreter, is_null)
   EXPECT_TRUE(walker.is_null("foo"));
 }
 
+TEST(interpreter, is_unset)
+{
+  interpreter walker;
+  walker.define("foo", "hello");
+  EXPECT_FALSE(walker.is_unset("foo"));
+  EXPECT_TRUE(walker.is_unset("bar"));
+}
+
 TEST(interpreter, set_int_value)
 {
   interpreter walker;



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-04-04 16:09 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-04-04 16:09 UTC (permalink / raw
  To: gentoo-commits

commit:     2d27dd160050b05cb4309a7eeec4bde936079033
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Mon Apr  4 08:53:30 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Mon Apr  4 15:57:03 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=2d27dd16

Fix a bug in resolving non-exist symbols

We should return an empty shared_ptr if the symbol doesn't exist.

---
 src/core/symbols.hpp            |    3 ++-
 src/core/tests/symbols_test.cpp |    1 +
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
index a4ae514..8734548 100644
--- a/src/core/symbols.hpp
+++ b/src/core/symbols.hpp
@@ -252,7 +252,8 @@ public:
   /// \return target symbol passed by reference
   std::shared_ptr<symbol> resolve(const std::string& name)
   {
-    return members[name];
+    auto iter = members.find(name);
+    return (iter == members.end()? std::shared_ptr<symbol>() : iter->second);
   }
 protected:
   /// \var protected::member

diff --git a/src/core/tests/symbols_test.cpp b/src/core/tests/symbols_test.cpp
index 7620be0..73a6a9c 100644
--- a/src/core/tests/symbols_test.cpp
+++ b/src/core/tests/symbols_test.cpp
@@ -80,4 +80,5 @@ TEST(scope_test, define_resolve)
   auto an_int = shared_ptr<variable>(new variable("integer_symbol", 100));
   members.define(an_int);
   EXPECT_EQ(an_int, members.resolve("integer_symbol"));
+  EXPECT_FALSE(members.resolve("not exist"));
 }



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-04-06  7:43 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-04-06  7:43 UTC (permalink / raw
  To: gentoo-commits

commit:     951bb1b72491976c03939ac186c9cfe4a236fb84
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Tue Apr  5 11:38:06 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Tue Apr  5 11:38:06 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=951bb1b7

Rename is_null to is_unset_or_null

is_null method will always check if the variable is unset. So
change the name to a more proper one.

---
 src/core/interpreter.h              |    4 ++--
 src/core/tests/interpreter_test.cpp |    6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index c0cc12d..ab6b9e8 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -366,7 +366,7 @@ public:
   ///        if the variable is undefined
   /// \param variable name
   /// \return whether the value of the variable is null
-  bool is_null(const std::string& name)
+  bool is_unset_or_null(const std::string& name)
   {
     std::shared_ptr<variable> value = members.resolve(name);
     if(value)
@@ -422,7 +422,7 @@ public:
   const std::string do_default_expansion(const std::string& name,
                                          const std::string& value)
   {
-    return (is_null(name)? value : resolve<std::string>(name));
+    return (is_unset_or_null(name)? value : resolve<std::string>(name));
   }
 };
 #endif

diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index 6f8d0c4..2d46e62 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -44,13 +44,13 @@ TEST(interpreter, define_resolve_string)
   EXPECT_STREQ("", walker.resolve<string>("undefined").c_str());
 }
 
-TEST(interpreter, is_null)
+TEST(interpreter, is_unset_or_null)
 {
   interpreter walker;
   walker.define("foo", "hello");
-  EXPECT_FALSE(walker.is_null("foo"));
+  EXPECT_FALSE(walker.is_unset_or_null("foo"));
   walker.define("foo", "hello", false, true);
-  EXPECT_TRUE(walker.is_null("foo"));
+  EXPECT_TRUE(walker.is_unset_or_null("foo"));
 }
 
 TEST(interpreter, is_unset)



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-04-12 18:29 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-04-12 18:29 UTC (permalink / raw
  To: gentoo-commits

commit:     eccb906c8fd1df61fc1f554485e560bcb4f8d1eb
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Tue Apr 12 01:07:45 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Tue Apr 12 07:22:49 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=eccb906c

Implement get_length and get_array_length for variable

get_length can use one optional argument to specify array index.
get_array_length returns the internal map size.

---
 src/core/interpreter.h          |    7 +++++--
 src/core/symbols.hpp            |   15 +++++++++++++++
 src/core/tests/symbols_test.cpp |   14 ++++++++++++++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index 7155639..43f816b 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -492,9 +492,12 @@ public:
   /// \brief get the length of a string variable
   /// \param the name of the variable
   /// \return the length
-  int get_length(const std::string& name)
+  unsigned get_length(const std::string& name, const unsigned index=0)
   {
-    return resolve<std::string>(name).size();
+    std::shared_ptr<variable> value = members.resolve(name);
+    if(!value)
+      return 0;
+    return value->get_length(index);
   }
 
 };

diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
index f645047..9bb0b98 100644
--- a/src/core/symbols.hpp
+++ b/src/core/symbols.hpp
@@ -178,6 +178,21 @@ public:
     value[index] = new_value;
   }
 
+  /// \brief get the length of a variable
+  /// \param the index of the variable, use 0 if it's not an array
+  /// \return the length of the variable
+  unsigned get_length(const unsigned index=0) const
+  {
+    return get_value<std::string>(index).size();
+  }
+
+  /// \brief get the length of an array variable
+  /// \return the length of the array
+  unsigned get_array_length() const
+  {
+    return value.size();
+  }
+
   /// \brief check whether the value of the variable is null
   /// \return whether the value of the variable is null
   bool is_null() const

diff --git a/src/core/tests/symbols_test.cpp b/src/core/tests/symbols_test.cpp
index 2b7a65e..1602f52 100644
--- a/src/core/tests/symbols_test.cpp
+++ b/src/core/tests/symbols_test.cpp
@@ -103,6 +103,20 @@ TEST(symbol_test, is_null)
   EXPECT_TRUE(variable("foo", "", false, true).is_null());
 }
 
+TEST(symbol_test, get_length)
+{
+  variable an_int("foo", 10);
+  EXPECT_EQ(2, an_int.get_length());
+
+  variable an_string("bar", "hello world");
+  EXPECT_EQ(11, an_string.get_length());
+
+  map<int, string> values = {{0, "1"}, {1, "2"}, {2, "hello"}};
+  variable array("array", values);
+  EXPECT_EQ(5, array.get_length(2));
+  EXPECT_EQ(3, array.get_array_length());
+}
+
 TEST(scope_test, define_resolve)
 {
   scope members;



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-04-12 18:29 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-04-12 18:29 UTC (permalink / raw
  To: gentoo-commits

commit:     b37f97adcfaf9aea824aa5f1bacae4c326973434
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Mon Apr 11 13:25:42 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Tue Apr 12 07:22:36 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=b37f97ad

Implement array symbol

Bash uses normal variables and arrays interchangeably. So we use
an internal map no matter if it's an array or variable.

---
 src/core/interpreter.h              |   12 ++++++---
 src/core/symbols.hpp                |   44 +++++++++++++++++++++++++++-------
 src/core/tests/interpreter_test.cpp |   27 +++++++++++++++++++++
 src/core/tests/symbols_test.cpp     |   31 +++++++++++++++++++++++-
 4 files changed, 100 insertions(+), 14 deletions(-)

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index 8fcab60..7155639 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -363,15 +363,16 @@ public:
 
   /// \brief resolve any variable
   /// \param variable name
+  /// \param array index, use index=0 if it's not an array
   /// \return the value of the variable, call default constructor if
   //          it's undefined
   template <typename T>
-  T resolve(const std::string& name)
+  T resolve(const std::string& name, const unsigned index=0)
   {
     std::shared_ptr<variable> value = members.resolve(name);
     if(!value)
       return T();
-    return value->get_value<T>();
+    return value->get_value<T>(index);
   }
 
   /// \brief check whether the value of the variable is null, return true
@@ -399,15 +400,18 @@ public:
   ///        it's readonly, will define the variable if it doesn't exist
   /// \param variable name
   /// \param new value
+  /// \param array index, use index=0 if it's not an array
   /// \return the new value of the variable
   template <typename T>
-  const T& set_value(const std::string& name, const T& new_value)
+  const T& set_value(const std::string& name,
+                     const T& new_value,
+                     const unsigned index=0)
   {
     std::shared_ptr<variable> value = members.resolve(name);
     if(!value)
       define(name, new_value, false);
     else
-      value->set_value(new_value);
+      value->set_value(new_value, index);
     return new_value;
   }
 

diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
index 077065e..f645047 100644
--- a/src/core/symbols.hpp
+++ b/src/core/symbols.hpp
@@ -25,6 +25,7 @@
 #ifndef LIBBASH_CORE_SYMBOLS_HPP_
 #define LIBBASH_CORE_SYMBOLS_HPP_
 
+#include <map>
 #include <memory>
 #include <sstream>
 #include <string>
@@ -115,8 +116,10 @@ class variable
   std::string name;
 
   /// \var private::value
-  /// \brief actual value of the variable
-  boost::variant<int, std::string> value;
+  /// \brief actual value of the variable. We put string in front of int
+  ///        because we want "" as default string value; Otherwise we
+  ///        will get "0".
+  std::map<int, boost::variant<std::string, int>> value;
 
   /// \var private::readonly
   /// \brief whether the variable is readonly
@@ -136,30 +139,43 @@ public:
 
   template <typename T>
   variable(const std::string& name,
-           T v,
+           const T& v,
            bool ro=false,
            bool is_null=false)
-    : name(name), value(v), readonly(ro), null_value(is_null){}
+    : name(name), readonly(ro), null_value(is_null)
+  {
+    value[0] = v;
+  }
 
-  /// \brief retrieve actual value of the variable
+  /// \brief retrieve actual value of the variable, if index is out of bound,
+  ///        will return the default value of type T
   /// \return the value of the variable
   template<typename T>
-  T get_value() const
+  T get_value(const unsigned index=0) const
   {
     static converter<T> visitor;
-    return boost::apply_visitor(visitor, value);
+
+    auto iter = value.find(index);
+    if(iter == value.end())
+        return T{};
+
+    return boost::apply_visitor(visitor, iter->second);
   }
 
   /// \brief set the value of the variable, raise exception if it's readonly
   /// \param the new value to be set
+  /// \param array index, use index=0 if it's not an array
   /// \param whether to set the variable to null value, default is false
   template <typename T>
-  void set_value(T new_value, bool is_null=false)
+  void set_value(const T& new_value,
+                 const unsigned index=0,
+                 bool is_null=false)
   {
     if(readonly)
       throw interpreter_exception(get_name() + " is readonly variable");
+
     null_value = is_null;
-    value = new_value;
+    value[index] = new_value;
   }
 
   /// \brief check whether the value of the variable is null
@@ -170,6 +186,16 @@ public:
   }
 };
 
+// specialization for arrays
+template <>
+inline variable::variable<>(const std::string& name,
+                            const std::map<int, std::string>& v,
+                            bool ro,
+                            bool is_null)
+    : name(name), value(v.begin(), v.end()), readonly(ro), null_value(is_null)
+{
+}
+
 ///
 /// class scope
 /// \brief implementation for symbol table

diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index 6cc2df9..28f8d35 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -44,6 +44,17 @@ TEST(interpreter, define_resolve_string)
   EXPECT_STREQ("", walker.resolve<string>("undefined").c_str());
 }
 
+TEST(interpreter, define_resolve_array)
+{
+  interpreter walker;
+  std::map<int, std::string> values = {{0, "1"}, {1, "2"}, {2, "3"}};
+  walker.define("array", values);
+  EXPECT_STREQ("1", walker.resolve<string>("array", 0).c_str());
+  EXPECT_STREQ("2", walker.resolve<string>("array", 1).c_str());
+  EXPECT_STREQ("3", walker.resolve<string>("array", 2).c_str());
+  EXPECT_STREQ("", walker.resolve<string>("undefined",100).c_str());
+}
+
 TEST(interpreter, is_unset_or_null)
 {
   interpreter walker;
@@ -91,6 +102,22 @@ TEST(interpreter, set_string_value)
   EXPECT_STREQ("hi", walker.resolve<string>("astring_ro").c_str());
 }
 
+TEST(interpreter, set_array_value)
+{
+  interpreter walker;
+  std::map<int, std::string> values = {{0, "1"}, {1, "2"}, {2, "3"}};
+  walker.define("array", values);
+  EXPECT_STREQ("2", walker.set_value<string>("array", "2", 0).c_str());
+  EXPECT_STREQ("2", walker.resolve<string>("array", 0).c_str());
+  EXPECT_STREQ("out_of_bound", walker.set_value<string>("array", "out_of_bound", 10).c_str());
+  EXPECT_STREQ("out_of_bound", walker.resolve<string>("array",10).c_str());
+
+  walker.define("ro_array", values, true);
+  EXPECT_THROW(walker.set_value<string>("ro_array", "hello", 1),
+               interpreter_exception);
+  EXPECT_STREQ("2", walker.resolve<string>("ro_array", 1).c_str());
+}
+
 TEST(interperter, substring_expansion_exception)
 {
   interpreter walker;

diff --git a/src/core/tests/symbols_test.cpp b/src/core/tests/symbols_test.cpp
index 73a6a9c..2b7a65e 100644
--- a/src/core/tests/symbols_test.cpp
+++ b/src/core/tests/symbols_test.cpp
@@ -65,11 +65,40 @@ TEST(symbol_test, string_variable)
   EXPECT_EQ(123, int_string.get_value<int>());
 }
 
+TEST(symbol_test, array_variable)
+{
+  map<int, string> values = {{0, "1"}, {1, "2"}, {2, "3"}};
+
+  // readonly array
+  variable ro_array("foo", values, true);
+  EXPECT_STREQ("foo", ro_array.get_name().c_str());
+  EXPECT_STREQ("1", ro_array.get_value<string>(0).c_str());
+  EXPECT_STREQ("2", ro_array.get_value<string>(1).c_str());
+  EXPECT_STREQ("3", ro_array.get_value<string>(2).c_str());
+  EXPECT_THROW(ro_array.set_value("4", 0), interpreter_exception);
+  EXPECT_STREQ("1", ro_array.get_value<string>(0).c_str());
+
+  // out of bound
+  EXPECT_STREQ("", ro_array.get_value<string>(100).c_str());
+
+  // normal array
+  variable normal_array("foo", values);
+  normal_array.set_value("5", 4);
+  EXPECT_STREQ("1", normal_array.get_value<string>(0).c_str());
+  EXPECT_STREQ("2", normal_array.get_value<string>(1).c_str());
+  EXPECT_STREQ("3", normal_array.get_value<string>(2).c_str());
+  EXPECT_STREQ("", normal_array.get_value<string>(3).c_str());
+  EXPECT_STREQ("5", normal_array.get_value<string>(4).c_str());
+
+  // get integer value
+  EXPECT_EQ(3, normal_array.get_value<int>(2));
+}
+
 TEST(symbol_test, is_null)
 {
   variable var("foo", 10);
   EXPECT_FALSE(var.is_null());
-  var.set_value("bar", true);
+  var.set_value("bar", 0, true);
   EXPECT_TRUE(var.is_null());
   EXPECT_TRUE(variable("foo", "", false, true).is_null());
 }



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-04-12 18:29 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-04-12 18:29 UTC (permalink / raw
  To: gentoo-commits

commit:     0f7c0723157eab83f7f0716c09764cc5004a63a3
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Tue Apr 12 01:43:13 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Tue Apr 12 07:22:49 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=0f7c0723

Support getting all values of an array

---
 src/core/interpreter.h              |   17 +++++++++++++++--
 src/core/symbols.hpp                |   16 ++++++++++++++++
 src/core/tests/interpreter_test.cpp |   13 +++++++++++++
 src/core/tests/symbols_test.cpp     |   24 ++++++++++++++++++++++++
 4 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index 43f816b..5c75bf0 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -361,11 +361,11 @@ public:
     return new_value;
   }
 
-  /// \brief resolve any variable
+  /// \brief resolve string/int variable
   /// \param variable name
   /// \param array index, use index=0 if it's not an array
   /// \return the value of the variable, call default constructor if
-  //          it's undefined
+  ///         it's undefined
   template <typename T>
   T resolve(const std::string& name, const unsigned index=0)
   {
@@ -375,6 +375,19 @@ public:
     return value->get_value<T>(index);
   }
 
+  /// \brief resolve array variable
+  /// \param variable name
+  /// \param[out] vector that stores all array values
+  template <typename T>
+  void resolve_array(const std::string& name, std::vector<T>& values)
+  {
+    std::shared_ptr<variable> value = members.resolve(name);
+    if(!value)
+      return;
+
+    value->get_all_values(values);
+  }
+
   /// \brief check whether the value of the variable is null, return true
   ///        if the variable is undefined
   /// \param variable name

diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
index 9bb0b98..5992a67 100644
--- a/src/core/symbols.hpp
+++ b/src/core/symbols.hpp
@@ -162,6 +162,22 @@ public:
     return boost::apply_visitor(visitor, iter->second);
   }
 
+  /// \brief retrieve all values of the array
+  /// \param[out] vector that stores all array values, values in the arrays will
+  ///             be cleared first
+  template<typename T>
+  void get_all_values(std::vector<T>& all_values) const
+  {
+    static converter<T> visitor;
+
+    all_values.clear();
+
+    for(auto iter = value.begin(); iter != value.end(); ++iter)
+        all_values.push_back(
+                boost::apply_visitor(visitor, iter->second));
+  }
+
+
   /// \brief set the value of the variable, raise exception if it's readonly
   /// \param the new value to be set
   /// \param array index, use index=0 if it's not an array

diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index 28f8d35..9bb561a 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -118,6 +118,19 @@ TEST(interpreter, set_array_value)
   EXPECT_STREQ("2", walker.resolve<string>("ro_array", 1).c_str());
 }
 
+TEST(interpreter, get_array_values)
+{
+  interpreter walker;
+  std::map<int, std::string> values = {{0, "1"}, {1, "2"}, {2, "3"}};
+  walker.define("array", values);
+
+  std::vector<int> array_values;
+  walker.resolve_array("array", array_values);
+  EXPECT_EQ(1, array_values[0]);
+  EXPECT_EQ(2, array_values[1]);
+  EXPECT_EQ(3, array_values[2]);
+}
+
 TEST(interperter, substring_expansion_exception)
 {
   interpreter walker;

diff --git a/src/core/tests/symbols_test.cpp b/src/core/tests/symbols_test.cpp
index 1602f52..b45d286 100644
--- a/src/core/tests/symbols_test.cpp
+++ b/src/core/tests/symbols_test.cpp
@@ -94,6 +94,30 @@ TEST(symbol_test, array_variable)
   EXPECT_EQ(3, normal_array.get_value<int>(2));
 }
 
+TEST(symbol_test, get_all_values)
+{
+  map<int, string> values = {{0, "1"}, {1, "2"}, {2, "3"}};
+  variable array("foo", values);
+  vector<string> string_values;
+  array.get_all_values(string_values);
+
+  EXPECT_EQ(3, string_values.size());
+  EXPECT_STREQ("1", string_values[0].c_str());
+  EXPECT_STREQ("2", string_values[1].c_str());
+  EXPECT_STREQ("3", string_values[2].c_str());
+
+  variable a_string("foo", 10);
+  a_string.get_all_values(string_values);
+  EXPECT_EQ(1, string_values.size());
+  EXPECT_STREQ("10", string_values[0].c_str());
+
+  variable an_int("foo", 10);
+  vector<int> int_values;
+  an_int.get_all_values(int_values);
+  EXPECT_EQ(1, int_values.size());
+  EXPECT_EQ(10, int_values[0]);
+}
+
 TEST(symbol_test, is_null)
 {
   variable var("foo", 10);



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-04-14  4:50 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-04-14  4:50 UTC (permalink / raw
  To: gentoo-commits

commit:     03e539766db9f149e5ca8657b75704edf09480af
Author:     Petteri Räty <petsku <AT> petteriraty <DOT> eu>
AuthorDate: Wed Apr 13 12:32:06 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Wed Apr 13 12:32:06 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=03e53976

Remove class scope

Scope was just a wrapper for the underlying container. I do not see any
value in the abstraction so now the interpreter has a unordered_map
member directly.

---
 src/core/interpreter.h          |   38 ++++++++++---------
 src/core/symbols.hpp            |   78 ---------------------------------------
 src/core/tests/symbols_test.cpp |    9 ----
 3 files changed, 20 insertions(+), 105 deletions(-)

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index 5c75bf0..3baf029 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -41,6 +41,8 @@
 /// \brief implementation for bash interpreter
 ///
 class interpreter{
+  typedef std::unordered_map<std::string, std::shared_ptr<variable>> scope;
+
   /// \var private::members
   /// \brief global symbol table
   scope members;
@@ -369,10 +371,10 @@ public:
   template <typename T>
   T resolve(const std::string& name, const unsigned index=0)
   {
-    std::shared_ptr<variable> value = members.resolve(name);
-    if(!value)
+    auto i = members.find(name);
+    if(i == members.end())
       return T();
-    return value->get_value<T>(index);
+    return i->second->get_value<T>(index);
   }
 
   /// \brief resolve array variable
@@ -381,11 +383,11 @@ public:
   template <typename T>
   void resolve_array(const std::string& name, std::vector<T>& values)
   {
-    std::shared_ptr<variable> value = members.resolve(name);
-    if(!value)
+    auto i = members.find(name);
+    if(i == members.end())
       return;
 
-    value->get_all_values(values);
+    i->second->get_all_values(values);
   }
 
   /// \brief check whether the value of the variable is null, return true
@@ -394,11 +396,11 @@ public:
   /// \return whether the value of the variable is null
   bool is_unset_or_null(const std::string& name)
   {
-    std::shared_ptr<variable> value = members.resolve(name);
-    if(value)
-      return value->is_null();
-    else
+    auto i = members.find(name);
+    if(i == members.end())
       return true;
+    else
+      return i->second->is_null();
   }
 
   /// \brief check whether the value of the variable is unset
@@ -406,7 +408,7 @@ public:
   /// \return whether the value of the variable is unset
   bool is_unset(const std::string& name)
   {
-    return !members.resolve(name);
+    return members.find(name) == members.end();
   }
 
   /// \brief update the variable value, raise interpreter_exception if
@@ -420,11 +422,11 @@ public:
                      const T& new_value,
                      const unsigned index=0)
   {
-    std::shared_ptr<variable> value = members.resolve(name);
-    if(!value)
+    auto i = members.find(name);
+    if(i == members.end())
       define(name, new_value, false);
     else
-      value->set_value(new_value, index);
+      i->second->set_value(new_value, index);
     return new_value;
   }
 
@@ -441,7 +443,7 @@ public:
   {
     std::shared_ptr<variable> target(
         new variable(name, value, readonly, is_null));
-    members.define(target);
+    members[name] = target;
   }
 
   /// \brief perform ${parameter:−word} expansion
@@ -507,10 +509,10 @@ public:
   /// \return the length
   unsigned get_length(const std::string& name, const unsigned index=0)
   {
-    std::shared_ptr<variable> value = members.resolve(name);
-    if(!value)
+    auto i = members.find(name);
+    if(i == members.end())
       return 0;
-    return value->get_length(index);
+    return i->second->get_length(index);
   }
 
 };

diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
index 5992a67..6fcedc1 100644
--- a/src/core/symbols.hpp
+++ b/src/core/symbols.hpp
@@ -227,82 +227,4 @@ inline variable::variable<>(const std::string& name,
 {
 }
 
-///
-/// class scope
-/// \brief implementation for symbol table
-///
-class scope
-{
-public:
-  typedef std::unordered_map<std::string, std::shared_ptr<variable>>
-    table_type;
-  typedef table_type::iterator iterator;
-  typedef table_type::const_iterator const_iterator;
-  typedef table_type::size_type size_type;
-  typedef table_type::value_type value_type;
-
-  ///
-  /// \brief return the number of variables in current scope
-  /// \return the number of variables
-  size_type size()
-  {
-    return members.size();
-  }
-
-  ///
-  /// \brief return an iterator referring to the first variable
-  /// \return iterator referring to the first variable
-  iterator begin()
-  {
-    return members.begin();
-  }
-
-  ///
-  /// \brief return a const iterator referring to the first variable
-  /// \return const iterator referring to the first variable
-  const_iterator begin() const
-  {
-    return members.begin();
-  }
-
-  ///
-  /// \brief return an iterator referring to the next element after
-  ///        the last variable in current scope
-  /// \return iterator referring to he next element after the last
-  ///         variable in current scope
-  iterator end()
-  {
-    return members.end();
-  }
-
-  ///
-  /// \brief return a const iterator referring to the next element
-  ///        after the last variable in current scope
-  /// \return const iterator referring to he next element after the
-  ///         last variable in current scope
-  const_iterator end() const
-  {
-    return members.end();
-  }
-
-  /// \brief define a new variable
-  /// \param the new variable
-  void define(std::shared_ptr<variable> s)
-  {
-    members[s->get_name()] = s;
-  }
-
-  /// \brief resolve a variable
-  /// \param the variable name
-  /// \return target variable passed by reference
-  std::shared_ptr<variable> resolve(const std::string& name)
-  {
-    auto iter = members.find(name);
-    return (iter == members.end()? std::shared_ptr<variable>() : iter->second);
-  }
-protected:
-  /// \var protected::member
-  /// \brief symbol table data structure
-  table_type members;
-};
 #endif

diff --git a/src/core/tests/symbols_test.cpp b/src/core/tests/symbols_test.cpp
index b45d286..d614947 100644
--- a/src/core/tests/symbols_test.cpp
+++ b/src/core/tests/symbols_test.cpp
@@ -140,12 +140,3 @@ TEST(symbol_test, get_length)
   EXPECT_EQ(5, array.get_length(2));
   EXPECT_EQ(3, array.get_array_length());
 }
-
-TEST(scope_test, define_resolve)
-{
-  scope members;
-  auto an_int = shared_ptr<variable>(new variable("integer_symbol", 100));
-  members.define(an_int);
-  EXPECT_EQ(an_int, members.resolve("integer_symbol"));
-  EXPECT_FALSE(members.resolve("not exist"));
-}



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-04-14  4:50 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-04-14  4:50 UTC (permalink / raw
  To: gentoo-commits

commit:     2722b084923c5d52b24399e8fe278f4ea7598d41
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Wed Apr 13 08:51:46 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Thu Apr 14 01:20:34 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=2722b084

Fix variable definition with non-zero index

We should be able to declare an array with non-zero index like
foo[5]=10. This array would contain 0 and 10 before this commit.
Now an extra index argument is added to fix this issue.

---
 src/core/interpreter.h              |    7 ++++---
 src/core/symbols.hpp                |    7 ++++---
 src/core/tests/interpreter_test.cpp |    4 ++++
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index 40663c0..4d51d5b 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -432,7 +432,7 @@ public:
   {
     std::shared_ptr<variable> value = members.resolve(name);
     if(!value)
-      define(name, new_value, false, is_null);
+      define(name, new_value, false, is_null, index);
     else
       value->set_value(new_value, index, is_null);
     return new_value;
@@ -447,10 +447,11 @@ public:
   void define(const std::string& name,
               const T& value,
               bool readonly=false,
-              bool is_null=false)
+              bool is_null=false,
+              const unsigned index=0)
   {
     std::shared_ptr<variable> target(
-        new variable(name, value, readonly, is_null));
+        new variable(name, value, readonly, is_null, index));
     members.define(target);
   }
 

diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
index 7654ebe..21638a0 100644
--- a/src/core/symbols.hpp
+++ b/src/core/symbols.hpp
@@ -137,11 +137,12 @@ public:
   variable(const std::string& name,
            const T& v,
            bool ro=false,
-           bool is_null=false)
+           bool is_null=false,
+           const unsigned index=0)
     : name(name), readonly(ro)
   {
     if(!is_null)
-        value[0] = v;
+        value[index] = v;
   }
 
   /// \brief retrieve actual value of the variable, if index is out of bound,
@@ -221,7 +222,7 @@ template <>
 inline variable::variable<>(const std::string& name,
                             const std::map<int, std::string>& v,
                             bool ro,
-                            bool)
+                            bool, unsigned)
     : name(name), value(v.begin(), v.end()), readonly(ro)
 {
 }

diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index fbf073e..ce9d4ad 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -53,6 +53,10 @@ TEST(interpreter, define_resolve_array)
   EXPECT_STREQ("2", walker.resolve<string>("array", 1).c_str());
   EXPECT_STREQ("3", walker.resolve<string>("array", 2).c_str());
   EXPECT_STREQ("", walker.resolve<string>("undefined",100).c_str());
+
+  walker.define("partial", 10, false, false, 8);
+  EXPECT_EQ(1, walker.get_array_length("partial"));
+  EXPECT_EQ(10, walker.resolve<int>("partial", 8));
 }
 
 TEST(interpreter, is_unset_or_null)



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-04-27 15:11 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-04-27 15:11 UTC (permalink / raw
  To: gentoo-commits

commit:     8b62986248d9d7aa758f2b0e4d6b2a0a65a83987
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Fri Apr 22 07:29:13 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Fri Apr 22 07:33:30 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=8b629862

Core: fix bug in word splitting

Word splitting wouldn't trim leading and trailing IFS characters.
Now it's fixed.

---
 src/core/interpreter.cpp            |    8 +++++++-
 src/core/tests/interpreter_test.cpp |   14 ++++++++++++++
 2 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/src/core/interpreter.cpp b/src/core/interpreter.cpp
index f7e8f64..58b1495 100644
--- a/src/core/interpreter.cpp
+++ b/src/core/interpreter.cpp
@@ -69,7 +69,13 @@ void interpreter::get_all_elements_IFS_joined(const std::string& name,
 void interpreter::split_word(const std::string& word, std::vector<std::string>& output)
 {
   const std::string& delimeter = resolve<std::string>("IFS");
-  boost::split(output, word, boost::is_any_of(delimeter), boost::token_compress_on);
+  std::string trimmed(word);
+  boost::trim_if(trimmed, boost::is_any_of(delimeter));
+
+  if(trimmed == "")
+    return;
+
+  boost::split(output, trimmed, boost::is_any_of(delimeter), boost::token_compress_on);
 }
 
 inline void define_function_arguments(std::unique_ptr<scope>& current_stack,

diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index ce9d4ad..2e92a22 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -147,3 +147,17 @@ TEST(interperter, substring_expansion_exception)
   interpreter walker;
   EXPECT_THROW(walker.do_substring_expansion("", 0, -1, 0), interpreter_exception);
 }
+
+TEST(interpreter, word_split)
+{
+  interpreter walker;
+  std::vector<std::string> splitted_values;
+  walker.split_word(" \n\t", splitted_values);
+  EXPECT_EQ(0, splitted_values.size());
+
+  splitted_values.clear();
+  walker.split_word(" \tfoo\n bar \n", splitted_values);
+  EXPECT_EQ(2, splitted_values.size());
+  EXPECT_STREQ("foo", splitted_values[0].c_str());
+  EXPECT_STREQ("bar", splitted_values[1].c_str());
+}



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-05-08 13:07 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-05-08 13:07 UTC (permalink / raw
  To: gentoo-commits

commit:     c15de9151925dd3ede93ac00ebac07e629c86b6c
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Fri Apr 29 08:45:05 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Sat May  7 07:03:23 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=c15de915

Core: return 0 if boost::lexical_cast<int> fails

Instead of throw an exception, we should return 0 as bash does. The
exact bash implementation is a bit different so we need to
specialize boost::lexical_cast<int> in future.

---
 src/core/symbols.hpp            |    2 +-
 src/core/tests/symbols_test.cpp |    2 ++
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
index 89fd657..2d6b6a5 100644
--- a/src/core/symbols.hpp
+++ b/src/core/symbols.hpp
@@ -73,7 +73,7 @@ public:
     }
     catch(boost::bad_lexical_cast& e)
     {
-      throw interpreter_exception("can't cast " + value + " to int");
+      std::cerr << "can't cast " << value << " to int" << std::endl;
     }
     return result;
   }

diff --git a/src/core/tests/symbols_test.cpp b/src/core/tests/symbols_test.cpp
index f151318..5853a4f 100644
--- a/src/core/tests/symbols_test.cpp
+++ b/src/core/tests/symbols_test.cpp
@@ -63,6 +63,8 @@ TEST(symbol_test, string_variable)
   // string contains integer value
   variable int_string("string", "123");
   EXPECT_EQ(123, int_string.get_value<int>());
+  int_string.set_value("abc");
+  EXPECT_EQ(0, int_string.get_value<int>());
 }
 
 TEST(symbol_test, array_variable)



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-05-23 14:34 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-05-23 14:34 UTC (permalink / raw
  To: gentoo-commits

commit:     f802859cbbb82e3376925f2ad7ec3f1ba238f5f8
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Fri May 20 07:08:29 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Mon May 23 15:02:51 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=f802859c

Core: generalize the functionality of bash_ast

The bash_ast class was for building AST from the start rule. Now
its functionality is generalized and the AST can be built and
interpreted from any rule. The bash_ast can be built from
std::string now.

---
 src/core/bash_ast.cpp            |   73 +++++++++++++++++++++----------------
 src/core/bash_ast.h              |   56 +++++++++++++++++++++++++----
 src/core/tests/bash_ast_test.cpp |    9 +++++
 3 files changed, 98 insertions(+), 40 deletions(-)

diff --git a/src/core/bash_ast.cpp b/src/core/bash_ast.cpp
index d70520e..af0205b 100644
--- a/src/core/bash_ast.cpp
+++ b/src/core/bash_ast.cpp
@@ -19,34 +19,22 @@
 ///
 /// \file bash_ast.cpp
 /// \author Mu Qiao
-/// \brief implementation that helps interpret from istream
+/// \brief a wrapper class that helps interpret from istream and string
 ///
 
-#include "core/bash_ast.h"
-
-#include <sstream>
-
 #include "core/interpreter_exception.h"
-#include "core/interpreter.h"
 #include "libbashLexer.h"
 #include "libbashParser.h"
-#include "libbashWalker.h"
 
-bash_ast::bash_ast(std::istream& source): error_count(0)
+#include "core/bash_ast.h"
+
+bash_ast::bash_ast(const std::istream& source,
+                   std::function<pANTLR3_BASE_TREE(plibbashParser)> p): parse(p)
 {
   std::stringstream stream;
   stream << source.rdbuf();
   script = stream.str();
-
-  input = antlr3NewAsciiStringInPlaceStream(
-      reinterpret_cast<pANTLR3_UINT8>(const_cast<char*>(script.c_str())),
-      script.size(),
-      NULL);
-
-  if(input == NULL)
-    throw interpreter_exception("Unable to open file " + script + " due to malloc() failure");
-
-  init_parser();
+  init_parser(script);
 }
 
 bash_ast::~bash_ast()
@@ -58,8 +46,16 @@ bash_ast::~bash_ast()
   input->close(input);
 }
 
-void bash_ast::init_parser()
+void bash_ast::init_parser(const std::string& script)
 {
+  input = antlr3NewAsciiStringInPlaceStream(
+    reinterpret_cast<pANTLR3_UINT8>(const_cast<char*>(script.c_str())),
+    script.size(),
+    NULL);
+
+  if(input == NULL)
+    throw interpreter_exception("Unable to open file " + script + " due to malloc() failure");
+
   lexer = libbashLexerNew(input);
   if ( lexer == NULL )
   {
@@ -85,29 +81,20 @@ void bash_ast::init_parser()
     return;
   }
 
-  ast.reset(new libbashParser_start_return(parser->start(parser)));
+  ast = parse(parser);
   error_count = parser->pParser->rec->getNumberOfSyntaxErrors(parser->pParser->rec);
-  nodes = antlr3CommonTreeNodeStreamNewTree(ast->tree, ANTLR3_SIZE_HINT);
-}
-
-void bash_ast::interpret_with(interpreter& walker)
-{
-  set_interpreter(&walker);
-  plibbashWalker treeparser = libbashWalkerNew(nodes);
-  treeparser->start(treeparser);
-  treeparser->free(treeparser);
+  nodes = antlr3CommonTreeNodeStreamNewTree(ast, ANTLR3_SIZE_HINT);
 }
 
 std::string bash_ast::get_dot_graph()
 {
-  pANTLR3_STRING graph = nodes->adaptor->makeDot(nodes->adaptor, ast->tree);
+  pANTLR3_STRING graph = nodes->adaptor->makeDot(nodes->adaptor, ast);
   return std::string(reinterpret_cast<char*>(graph->chars));
 }
 
 std::string bash_ast::get_string_tree()
 {
-  return std::string(reinterpret_cast<char*>(
-        ast->tree->toStringTree(ast->tree)->chars));
+  return std::string(reinterpret_cast<char*>(ast->toStringTree(ast)->chars));
 }
 
 namespace
@@ -161,3 +148,25 @@ std::string bash_ast::get_tokens(std::function<std::string(ANTLR3_INT32)> token_
 
   return result.str();
 }
+
+void bash_ast::walker_start(plibbashWalker tree_parser)
+{
+  tree_parser->start(tree_parser);
+}
+
+int bash_ast::walker_arithmetics(plibbashWalker tree_parser)
+{
+  return tree_parser->arithmetics(tree_parser);
+}
+
+pANTLR3_BASE_TREE bash_ast::parser_start(plibbashParser parser)
+{
+  return parser->start(parser).tree;
+}
+
+pANTLR3_BASE_TREE bash_ast::parser_arithmetics(plibbashParser parser)
+{
+  return parser->arithmetics(parser).tree;
+}
+
+

diff --git a/src/core/bash_ast.h b/src/core/bash_ast.h
index 168d012..33590c8 100644
--- a/src/core/bash_ast.h
+++ b/src/core/bash_ast.h
@@ -19,12 +19,14 @@
 ///
 /// \file bash_ast.h
 /// \author Mu Qiao
-/// \brief a class that helps interpret from istream
+/// \brief a class that helps interpret from istream and string
 ///
 
 #ifndef LIBBASH_CORE_PARSER_BUILDER_H_
 #define LIBBASH_CORE_PARSER_BUILDER_H_
 
+#include <type_traits>
+#include <functional>
 #include <istream>
 #include <memory>
 #include <string>
@@ -32,13 +34,14 @@
 
 #include <antlr3.h>
 
+#include "libbashWalker.h"
+
 struct libbashLexer_Ctx_struct;
 struct libbashParser_Ctx_struct;
-struct libbashParser_start_return_struct;
 class interpreter;
 
 /// \class bash_ast
-/// \brief a wrapper class that helps interpret from istream
+/// \brief a wrapper class that helps interpret from istream and string
 class bash_ast
 {
   pANTLR3_INPUT_STREAM input;
@@ -46,26 +49,63 @@ class bash_ast
   libbashLexer_Ctx_struct* lexer;
   pANTLR3_COMMON_TOKEN_STREAM token_stream;
   libbashParser_Ctx_struct* parser;
-  std::unique_ptr<libbashParser_start_return_struct> ast;
+  pANTLR3_BASE_TREE ast;
   pANTLR3_COMMON_TREE_NODE_STREAM nodes;
   int error_count;
+  std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> parse;
+
+  void init_parser(const std::string& script);
 
-  void init_parser();
 public:
-  explicit bash_ast(std::istream& source);
+  bash_ast(const std::istream& source,
+           std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> p=parser_start);
+
+  bash_ast(const std::string& script,
+           std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> p=parser_start): parse(p)
+  {
+    init_parser(script);
+  }
+
   ~bash_ast();
 
   int get_error_count() const
   {
     return error_count;
   }
+
+  static void walker_start(plibbashWalker tree_parser);
+
+  static int walker_arithmetics(plibbashWalker tree_parser);
+
+  static pANTLR3_BASE_TREE parser_start(libbashParser_Ctx_struct* parser);
+
+  static pANTLR3_BASE_TREE parser_arithmetics(libbashParser_Ctx_struct* parser);
+
   ///
   /// \brief interpret the script with a given interpreter
   /// \param the interpreter object
-  void interpret_with(interpreter& walker);
+  /// \return the interpreted result
+  template<typename Functor>
+  typename std::result_of<Functor(plibbashWalker)>::type
+  interpret_with(interpreter& walker, Functor walk)
+  {
+    set_interpreter(&walker);
+    std::unique_ptr<libbashWalker_Ctx_struct, std::function<void(plibbashWalker)>> p_tree_parser(
+        libbashWalkerNew(nodes),
+        [](plibbashWalker tree_parser) { tree_parser->free(tree_parser); });
+    return walk(p_tree_parser.get());
+  }
+
+  void interpret_with(interpreter& walker)
+  {
+    interpret_with(walker, walker_start);
+  }
+
   std::string get_dot_graph();
+
   std::string get_string_tree();
-  std::string get_tokens(std::function<std::string(ANTLR3_INT32)> token_map);
+
+  std::string get_tokens(std::function<std::string(ANTLR3_INT32)>);
 };
 
 #endif

diff --git a/src/core/tests/bash_ast_test.cpp b/src/core/tests/bash_ast_test.cpp
index 9c4421c..dbf23e8 100644
--- a/src/core/tests/bash_ast_test.cpp
+++ b/src/core/tests/bash_ast_test.cpp
@@ -28,6 +28,7 @@
 #include <gtest/gtest.h>
 
 #include "core/bash_ast.h"
+#include "core/interpreter.h"
 #include "test.h"
 
 TEST(bash_ast, parse_illegal_script)
@@ -47,3 +48,11 @@ TEST(bash_ast, parse_legal_script)
   bash_ast ast2(input2);
   EXPECT_EQ(0, ast2.get_error_count());
 }
+
+TEST(bash_ast, parse_arithmetics)
+{
+  std::string expr("1 + 2");
+  bash_ast ast(expr, bash_ast::parser_arithmetics);
+  interpreter walker;
+  EXPECT_EQ(3, ast.interpret_with(walker, &bash_ast::walker_arithmetics));
+}



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-05-23 14:34 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-05-23 14:34 UTC (permalink / raw
  To: gentoo-commits

commit:     784193e4e4ba9ac58630eb791757f098492bc5f7
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Sat May 21 03:34:06 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Mon May 23 15:04:45 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=784193e4

Core: refactor get_all_elements_joined to use resolve_array

The resolve_array method is changed to return false if the array
doesn't exist.

---
 src/core/interpreter.cpp            |   12 +++---------
 src/core/interpreter.h              |    5 +++--
 src/core/tests/interpreter_test.cpp |    3 ++-
 3 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/src/core/interpreter.cpp b/src/core/interpreter.cpp
index 85b0ded..80bc8be 100644
--- a/src/core/interpreter.cpp
+++ b/src/core/interpreter.cpp
@@ -143,18 +143,12 @@ void interpreter::get_all_elements_joined(const std::string& name,
                                           const std::string& delim,
                                           std::string& result) const
 {
-  std::vector<std::string> source;
+  std::vector<std::string> array;
 
-  auto i = members.find(name);
-  if(i != members.end())
-  {
-    i->second->get_all_values(source);
-    result = boost::algorithm::join(source, delim);
-  }
+  if(resolve_array(name, array))
+    result = boost::algorithm::join(array, delim);
   else
-  {
     result = "";
-  }
 }
 
 void interpreter::get_all_elements(const std::string& name,

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index 5d9f518..aa13b4e 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -437,13 +437,14 @@ public:
   /// \param variable name
   /// \param[out] vector that stores all array values
   template <typename T>
-  void resolve_array(const std::string& name, std::vector<T>& values) const
+  bool resolve_array(const std::string& name, std::vector<T>& values) const
   {
     auto i = members.find(name);
     if(i == members.end())
-      return;
+      return false;
 
     i->second->get_all_values(values);
+    return true;
   }
 
   /// \brief check whether the value of the variable is null, return true

diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index 54f25b0..a5e4ff9 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -136,10 +136,11 @@ TEST(interpreter, get_array_values)
   walker.define("array", values);
 
   std::vector<int> array_values;
-  walker.resolve_array("array", array_values);
+  EXPECT_TRUE(walker.resolve_array("array", array_values));
   EXPECT_EQ(1, array_values[0]);
   EXPECT_EQ(2, array_values[1]);
   EXPECT_EQ(3, array_values[2]);
+  EXPECT_FALSE(walker.resolve_array("undefined", array_values));
 }
 
 TEST(interpreter, unset_values)



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-05-25 19:42 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-05-25 19:42 UTC (permalink / raw
  To: gentoo-commits

commit:     a4da23bd461a004396138e889ca1111a3cfc5d9d
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Wed May 25 08:22:48 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Wed May 25 10:13:52 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=a4da23bd

Core: support setting and getting bash option

---
 src/core/interpreter.cpp            |   64 +++++++++++++++++++++++++++++++++++
 src/core/interpreter.h              |   18 ++++++++--
 src/core/tests/interpreter_test.cpp |   12 ++++++
 3 files changed, 90 insertions(+), 4 deletions(-)

diff --git a/src/core/interpreter.cpp b/src/core/interpreter.cpp
index 7e7de9c..2337e87 100644
--- a/src/core/interpreter.cpp
+++ b/src/core/interpreter.cpp
@@ -39,6 +39,52 @@
 
 #include "libbashWalker.h"
 
+interpreter::interpreter(): out(&std::cout), err(&std::cerr), in(&std::cin), bash_options(
+    {
+      {"autocd", false},
+      {"cdable_vars", false},
+      {"cdspell", false},
+      {"checkhash", false},
+      {"checkjobs", false},
+      {"checkwinsize", false},
+      {"cmdhist", false},
+      {"compat31", false},
+      {"dirspell", false},
+      {"dotglob", false},
+      {"execfail", false},
+      {"expand_aliases", false},
+      {"extdebug", false},
+      {"extglob", false},
+      {"extquote", false},
+      {"failglob", false},
+      {"force_fignore", false},
+      {"globstar", false},
+      {"gnu_errfmt", false},
+      {"histappend", false},
+      {"histreedit", false},
+      {"histverify", false},
+      {"hostcomplete", false},
+      {"huponexit", false},
+      {"interactive", false},
+      {"lithist", false},
+      {"login_shell", false},
+      {"mailwarn", false},
+      {"no_empty_cmd_completion", false},
+      {"nocaseglob", false},
+      {"nocasematch", false},
+      {"nullglob", false},
+      {"progcomp", false},
+      {"promptvars", false},
+      {"restricted", false},
+      {"shift_verbose", false},
+      {"sourcepath", false},
+      {"xpg_echo", false},
+    }
+    )
+{
+  define("IFS", " \t\n");
+}
+
 std::string interpreter::get_string(pANTLR3_BASE_TREE node)
 {
   pANTLR3_COMMON_TOKEN token = node->getToken(node);
@@ -315,3 +361,21 @@ void interpreter::unset(const std::string& name,
   else
     iter->second->unset_value(index);
 }
+
+bool interpreter::get_option(const std::string& name) const
+{
+  auto iter = bash_options.find(name);
+  if(iter == bash_options.end())
+    throw interpreter_exception("Invalid bash option");
+
+  return iter->second;
+}
+
+void interpreter::set_option(const std::string& name, bool value)
+{
+  auto iter = bash_options.find(name);
+  if(iter == bash_options.end())
+    throw interpreter_exception("Invalid bash option");
+
+  iter->second = value;
+}

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index 4c6f69c..3c85450 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -68,6 +68,8 @@ class interpreter
 
   std::istream* in;
 
+  std::unordered_map<std::string, bool> bash_options;
+
   /// \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
@@ -114,10 +116,7 @@ public:
     }
   };
 
-  interpreter(): out(&std::cout), err(&std::cerr), in(&std::cin)
-  {
-    define("IFS", " \t\n");
-  }
+  interpreter();
 
   ///
   /// \brief return the number of variables
@@ -661,6 +660,17 @@ public:
   //. \param[out] the splitted result will be appended to output
   void split_word(const std::string& word, std::vector<std::string>& output);
 
+  /// \brief get the status of shell optional behavior
+  /// \param the option name
+  /// \return zero unless the name is not a valid shell option
+  bool get_option(const std::string& name) const;
+
+  /// \brief set the status of shell optional behavior
+  /// \param the option name
+  /// \param[in] true if option is enabled, false otherwise
+  /// \return zero unless the name is not a valid shell option
+  void set_option(const std::string& name, bool value);
+
   /// \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/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index a5e4ff9..ab24449 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -189,3 +189,15 @@ TEST(interpreter, word_split)
   EXPECT_STREQ("foo", splitted_values[0].c_str());
   EXPECT_STREQ("bar", splitted_values[1].c_str());
 }
+
+TEST(interpreter, bash_option)
+{
+  interpreter walker;
+
+  EXPECT_THROW(walker.set_option("not exist", false), interpreter_exception);
+  EXPECT_THROW(walker.get_option("not exist"), interpreter_exception);
+
+  EXPECT_FALSE(walker.get_option("extglob"));
+  walker.set_option("extglob", true);
+  EXPECT_TRUE(walker.get_option("extglob"));
+}



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/
@ 2011-05-27 23:03 Petteri Räty
  0 siblings, 0 replies; 16+ messages in thread
From: Petteri Räty @ 2011-05-27 23:03 UTC (permalink / raw
  To: gentoo-commits

commit:     b36f96514be51edfa2fa147157972a627adcc292
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Wed May 25 15:04:32 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Thu May 26 14:56:30 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=b36f9651

Core: return default value when name doesn't exist

The interpreter class would throw an exception if the variable name
was "" and would return the default value if the variable couldn't
be find. Now this behavior is unified by returning the default value.

---
 src/core/interpreter.cpp            |    3 ++-
 src/core/tests/interpreter_test.cpp |    2 ++
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/src/core/interpreter.cpp b/src/core/interpreter.cpp
index 2337e87..c8611d6 100644
--- a/src/core/interpreter.cpp
+++ b/src/core/interpreter.cpp
@@ -101,7 +101,8 @@ std::string interpreter::get_string(pANTLR3_BASE_TREE node)
 std::shared_ptr<variable> interpreter::resolve_variable(const std::string& name) const
 {
   if(name.empty())
-    throw interpreter_exception("Variable name shouldn't be empty");
+    return std::shared_ptr<variable>();
+
   // positional parameter
   if(isdigit(name[0]) && !local_members.empty())
   {

diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
index ab24449..0322a6b 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -34,6 +34,7 @@ TEST(interpreter, define_resolve_int)
   walker.define("aint", 4);
   EXPECT_EQ(4, walker.resolve<int>("aint"));
   EXPECT_EQ(0, walker.resolve<int>("undefined"));
+  EXPECT_EQ(0, walker.resolve<int>(""));
 }
 
 TEST(interpreter, define_resolve_string)
@@ -42,6 +43,7 @@ TEST(interpreter, define_resolve_string)
   walker.define("astring", "hello");
   EXPECT_STREQ("hello", walker.resolve<string>("astring").c_str());
   EXPECT_STREQ("", walker.resolve<string>("undefined").c_str());
+  EXPECT_STREQ("", walker.resolve<string>("").c_str());
 }
 
 TEST(interpreter, define_resolve_array)



^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2011-05-27 23:04 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-04 15:52 [gentoo-commits] proj/libbash:master commit in: src/core/, src/core/tests/ Petteri Räty
  -- strict thread matches above, loose matches on Subject: below --
2011-05-27 23:03 Petteri Räty
2011-05-25 19:42 Petteri Räty
2011-05-23 14:34 Petteri Räty
2011-05-23 14:34 Petteri Räty
2011-05-08 13:07 Petteri Räty
2011-04-27 15:11 Petteri Räty
2011-04-14  4:50 Petteri Räty
2011-04-14  4:50 Petteri Räty
2011-04-12 18:29 Petteri Räty
2011-04-12 18:29 Petteri Räty
2011-04-12 18:29 Petteri Räty
2011-04-06  7:43 Petteri Räty
2011-04-04 16:09 Petteri Räty
2011-04-04 15:52 Petteri Räty
2011-03-30 12:48 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