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;
next 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