public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Petteri Räty" <betelgeuse@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/libbash:master commit in: scripts/, src/core/, bashast/, src/core/tests/
Date: Mon, 23 May 2011 14:34:21 +0000 (UTC)	[thread overview]
Message-ID: <1b777e0ff35171fc0778e051c55e782d5eb4a0ad.betelgeuse@gentoo> (raw)

commit:     1b777e0ff35171fc0778e051c55e782d5eb4a0ad
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Sat May 21 05:04:53 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=1b777e0f

Walker: support ${*:x:y} expansion

We don't support $0 for now so ${*:0:x} will give you a wrong script
name.

---
 bashast/bashast.g                 |    8 +++---
 bashast/libbashWalker.g           |    3 +-
 scripts/var_expansion.bash        |    9 +++++++
 scripts/var_expansion.bash.result |    6 ++++
 src/core/interpreter.cpp          |   49 +++++++++++++++++++++++++++++++------
 src/core/interpreter.h            |   10 +++++--
 src/core/symbols.hpp              |    5 +---
 src/core/tests/symbols_test.cpp   |    5 ++-
 8 files changed, 73 insertions(+), 22 deletions(-)

diff --git a/bashast/bashast.g b/bashast/bashast.g
index 404de43..693ee96 100644
--- a/bashast/bashast.g
+++ b/bashast/bashast.g
@@ -280,9 +280,7 @@ var_exp	:	var_name (
 					 | LSQUARE (op=TIMES|op=AT) RSQUARE -> ^(LIST_EXPAND var_name_for_bang $op)
 					 | -> ^(VAR_REF var_name_for_bang)
 					)
-	|	var_size_ref
-	|	TIMES
-	|	AT;
+	|	var_size_ref;
 parameter_delete_operator
 	:	POUND -> LAZY_REMOVE_AT_START
 	|	POUNDPOUND -> REPLACE_AT_START
@@ -312,7 +310,9 @@ parameter_replace_operator
 //either directly or through array
 var_name
 	:	num
-	|	var_name_no_digit;
+	|	var_name_no_digit
+	|	TIMES
+	|	AT;
 //Inside arithmetic we can't allow digits
 var_name_no_digit
 	:	name^ LSQUARE! (AT|TIMES|explicit_arithmetic) RSQUARE!

diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g
index 07d0f84..55aab88 100644
--- a/bashast/libbashWalker.g
+++ b/bashast/libbashWalker.g
@@ -327,7 +327,8 @@ var_name returns[std::string libbash_value, unsigned index]
 	|name {
 		$libbash_value = $name.libbash_value;
 		$index = $name.index;
-	};
+	}
+	|TIMES { $libbash_value = "*"; };
 
 var_expansion returns[std::string libbash_value]
 @declarations {

diff --git a/scripts/var_expansion.bash b/scripts/var_expansion.bash
index 8db702d..8fcb943 100644
--- a/scripts/var_expansion.bash
+++ b/scripts/var_expansion.bash
@@ -82,3 +82,12 @@ FOO080=${FOO039/@([a-c]|[k-m])}
 FOO081=${FOO039//@([a-c]|[k-m])}
 target="abc123abc"
 FOO082="${target##+(ab[c])*([[:digit:]])}"
+function positional_parameter_test(){
+    FOO083=${*}
+    FOO084=${*:1}
+    FOO085=${*:1:2}
+    FOO086=${*: -1}
+    FOO087=${*: -2:5}
+    FOO088=${*:0}
+}
+positional_parameter_test 1 2 3 4 5

diff --git a/scripts/var_expansion.bash.result b/scripts/var_expansion.bash.result
index c01e769..5ec7c65 100644
--- a/scripts/var_expansion.bash.result
+++ b/scripts/var_expansion.bash.result
@@ -83,4 +83,10 @@ FOO079=H Wrd
 FOO080=Helo World
 FOO081=Heo Word
 FOO082=abc
+FOO083=1 2 3 4 5
+FOO084=1 2 3 4 5
+FOO085=1 2
+FOO086=5
+FOO087=4 5
+FOO088=filename 1 2 3 4 5
 target=abc123abc

diff --git a/src/core/interpreter.cpp b/src/core/interpreter.cpp
index 80bc8be..7e7de9c 100644
--- a/src/core/interpreter.cpp
+++ b/src/core/interpreter.cpp
@@ -89,14 +89,49 @@ bool interpreter::is_unset_or_null(const std::string& name,
     return i->second->is_null(index);
 }
 
+// This method temporarily supports array offset expansion for $* and $@.
+// That logic will be refactored and applied to normal array variables in future.
+std::string interpreter::get_substring(const std::string& name,
+                                       int offset,
+                                       int length,
+                                       const unsigned index) const
+{
+  if(name != "*" && name != "@")
+  {
+    std::string value = resolve<std::string>(name, index);
+    if(!get_real_offset(offset, value.size()))
+      return "";
+    return value.substr(offset, length);
+  }
+  else
+  {
+    std::vector<std::string> array;
+    // ${*:1} has the same content as ${*}, ${*:0} contains current script name as the first element
+    if(offset > 0)
+      offset--;
+    else if(offset == 0)
+      // Need to replace this with the real script name
+      array.push_back("filename");
+    if(resolve_array(name, array) && get_real_offset(offset, array.size()))
+    {
+      int max_length = array.size() - offset;
+      if(length == -1 || length > max_length)
+        length = max_length;
+      return boost::algorithm::join(
+          std::vector<std::string>(array.begin() + offset,
+                                   array.begin() + offset + length),
+          resolve<std::string>("IFS").substr(0, 1));
+    }
+    else
+      return "";
+  }
+}
+
 const std::string interpreter::do_substring_expansion(const std::string& name,
                                                       int offset,
                                                       const unsigned index) const
 {
-  std::string value = resolve<std::string>(name, index);
-  if(!get_real_offset(offset, value))
-    return "";
-  return value.substr(offset);
+  return get_substring(name, offset, -1, index);
 }
 
 const std::string interpreter::do_substring_expansion(const std::string& name,
@@ -106,10 +141,8 @@ const std::string interpreter::do_substring_expansion(const std::string& name,
 {
   if(length < 0)
     throw interpreter_exception("length of substring expression should be greater or equal to zero");
-  std::string value = resolve<std::string>(name, index);
-  if(!get_real_offset(offset, value))
-    return "";
-  return value.substr(offset, length);
+
+  return get_substring(name, offset, length, index);
 }
 
 std::string interpreter::do_replace_expansion(const std::string& name,

diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index aa13b4e..4c6f69c 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -73,10 +73,10 @@ class interpreter
   /// \param[in,out] a value/result argument referring to offset
   /// \param[in] the original string
   /// \return whether the real offset is in legal range
-  bool get_real_offset(int& offset, const std::string& str) const
+  bool get_real_offset(int& offset, const int size) const
   {
-    offset = (offset >= 0? offset : str.size() + offset);
-    return !(offset < 0 || offset >= static_cast<int>(str.size()));
+    offset = (offset >= 0? offset : size + offset);
+    return !(offset < 0 || offset >= size);
   }
 
   void get_all_elements_joined(const std::string& name,
@@ -88,6 +88,10 @@ class interpreter
   void define_function_arguments(scope& current_stack,
                                  const std::vector<std::string>& arguments);
 
+  std::string get_substring(const std::string& name,
+                            int offset,
+                            int length,
+                            const unsigned index) const;
 public:
 
   ///

diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
index 2d6b6a5..8ceb25a 100644
--- a/src/core/symbols.hpp
+++ b/src/core/symbols.hpp
@@ -159,15 +159,12 @@ public:
   }
 
   /// \brief retrieve all values of the array
-  /// \param[out] vector that stores all array values, values in the arrays will
-  ///             be cleared first
+  /// \param[out] vector that stores all array values
   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));

diff --git a/src/core/tests/symbols_test.cpp b/src/core/tests/symbols_test.cpp
index 5853a4f..358f5b6 100644
--- a/src/core/tests/symbols_test.cpp
+++ b/src/core/tests/symbols_test.cpp
@@ -109,9 +109,10 @@ TEST(symbol_test, get_all_values)
   EXPECT_STREQ("3", string_values[2].c_str());
 
   variable a_string("foo", 10);
+  // Won't clear the original vector
   a_string.get_all_values(string_values);
-  EXPECT_EQ(1, string_values.size());
-  EXPECT_STREQ("10", string_values[0].c_str());
+  EXPECT_EQ(4, string_values.size());
+  EXPECT_STREQ("1", string_values[0].c_str());
 
   variable an_int("foo", 10);
   vector<int> int_values;



             reply	other threads:[~2011-05-23 14:35 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-23 14:34 Petteri Räty [this message]
  -- strict thread matches above, loose matches on Subject: below --
2012-06-03  9:08 [gentoo-commits] proj/libbash:master commit in: scripts/, src/core/, bashast/, src/core/tests/ Petteri Räty
2011-06-03 12:43 Petteri Räty
2011-05-22 21:00 Petteri Räty
2011-04-28  6:19 Petteri Räty
2011-04-14  4:50 Petteri Räty
2011-04-06 15:07 Petteri Räty

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1b777e0ff35171fc0778e051c55e782d5eb4a0ad.betelgeuse@gentoo \
    --to=betelgeuse@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox