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: Thu, 14 Apr 2011 04:50:14 +0000 (UTC) [thread overview]
Message-ID: <60fe984fb2c868848a8fb71fe2272a24a78d350a.betelgeuse@gentoo> (raw)
commit: 60fe984fb2c868848a8fb71fe2272a24a78d350a
Author: Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Tue Apr 12 13:44:06 2011 +0000
Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Wed Apr 13 02:46:03 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=60fe984f
Implement array element reference for variable expansion
---
bashast/libbashWalker.g | 21 +++++++++++------
scripts/var_expansion.ebuild | 13 +++++++++++
scripts/var_expansion.ebuild.result | 14 ++++++++++++
src/core/interpreter.h | 41 ++++++++++++++++++++++++----------
src/core/symbols.hpp | 23 +++++++++----------
src/core/tests/interpreter_test.cpp | 13 ++++++++--
6 files changed, 90 insertions(+), 35 deletions(-)
diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g
index 45034c2..ddeffa0 100644
--- a/bashast/libbashWalker.g
+++ b/bashast/libbashWalker.g
@@ -116,23 +116,28 @@ var_name returns[std::string libbash_value, unsigned index]
var_expansion returns[std::string libbash_value]:
^(USE_DEFAULT var_name libbash_word=word) {
- libbash_value = walker->do_default_expansion($var_name.libbash_value, libbash_word);
+ libbash_value = walker->do_default_expansion($var_name.libbash_value, libbash_word, $var_name.index);
}
|^(ASSIGN_DEFAULT var_name libbash_word=word) {
- libbash_value = walker->do_assign_expansion($var_name.libbash_value, libbash_word);
+ libbash_value = walker->do_assign_expansion($var_name.libbash_value, libbash_word, $var_name.index);
}
|^(USE_ALTERNATE var_name libbash_word=word) {
- libbash_value = walker->do_alternate_expansion($var_name.libbash_value, libbash_word);
+ libbash_value = walker->do_alternate_expansion($var_name.libbash_value, libbash_word, $var_name.index);
}
|(^(OFFSET var_name arithmetics arithmetics)) => ^(OFFSET var_name offset=arithmetics length=arithmetics) {
- libbash_value = walker->do_substring_expansion($var_name.libbash_value, offset, length);
+ libbash_value = walker->do_substring_expansion($var_name.libbash_value, offset, length, $var_name.index);
}
|^(OFFSET var_name offset=arithmetics) {
- libbash_value = walker->do_substring_expansion($var_name.libbash_value, offset);
- }
- |^(POUND var_name) {
- libbash_value = boost::lexical_cast<std::string>(walker->get_length($var_name.libbash_value));
- };
+ libbash_value = walker->do_substring_expansion($var_name.libbash_value, offset, $var_name.index);
+ }
+ |^(POUND(
+ var_name {
+ libbash_value = boost::lexical_cast<std::string>(walker->get_length($var_name.libbash_value, $var_name.index));
+ }
+ |^(libbash_name=name_base ARRAY_SIZE) {
+ libbash_value = boost::lexical_cast<std::string>(walker->get_array_length(libbash_name));
+ }
+ ));
word returns[std::string libbash_value]:
|(num) => libbash_string=num { $libbash_value = libbash_string; }
diff --git a/scripts/var_expansion.ebuild b/scripts/var_expansion.ebuild
index 0045b5e..96b6bf2 100644
--- a/scripts/var_expansion.ebuild
+++ b/scripts/var_expansion.ebuild
@@ -1,3 +1,4 @@
+ARRAY=(hi hello 1 2 3)
EAPI="3"
EAPI4="$(($EAPI+1))"
FOO001="${EAPI:-hello}"
@@ -24,3 +25,15 @@ FOO022=${FOO009: -2:100}
FOO023=${NOT_EXIST:0:2}
FOO024=${#FOO009}
FOO025=${#NOT_EXIST}
+FOO026="${ARRAY[0]:-hello}"
+FOO028="${ARRAY[5]:-hello}"
+FOO029="${ARRAY2[0]:=hello}"
+FOO030="${ARRAY2[0]:=hi}"
+FOO031="${ARRAY2[0]:+hi}"
+FOO032="${ARRAY2[1]:+hi}"
+FOO033="${ARRAY[1]:1}"
+FOO034="${ARRAY[1]:1:3}"
+FOO035="${#ARRAY[0]}"
+FOO036="${#ARRAY[@]}"
+FOO037="${#ARRAY[*]}"
+FOO038="${#ARRAY}"
diff --git a/scripts/var_expansion.ebuild.result b/scripts/var_expansion.ebuild.result
index e7b767a..8bea3b8 100644
--- a/scripts/var_expansion.ebuild.result
+++ b/scripts/var_expansion.ebuild.result
@@ -1,3 +1,5 @@
+ARRAY=hi hello 1 2 3
+ARRAY2=hello
EAPI=3
EAPI4=4
FOO001=3
@@ -25,3 +27,15 @@ FOO022=lo
FOO023=
FOO024=5
FOO025=0
+FOO026=hi
+FOO028=hello
+FOO029=hello
+FOO030=hello
+FOO031=hi
+FOO032=
+FOO033=ello
+FOO034=ell
+FOO035=2
+FOO036=5
+FOO037=5
+FOO038=2
diff --git a/src/core/interpreter.h b/src/core/interpreter.h
index 5c75bf0..9166379 100644
--- a/src/core/interpreter.h
+++ b/src/core/interpreter.h
@@ -392,11 +392,11 @@ public:
/// if the variable is undefined
/// \param variable name
/// \return whether the value of the variable is null
- bool is_unset_or_null(const std::string& name)
+ bool is_unset_or_null(const std::string& name, const unsigned index)
{
std::shared_ptr<variable> value = members.resolve(name);
if(value)
- return value->is_null();
+ return value->is_null(index);
else
return true;
}
@@ -449,9 +449,11 @@ public:
/// \param the value of the word
/// \return the expansion result
const std::string do_default_expansion(const std::string& name,
- const std::string& value)
+ const std::string& value,
+ const unsigned index)
{
- return (is_unset_or_null(name)? value : resolve<std::string>(name));
+ return (is_unset_or_null(name, index)?
+ value : resolve<std::string>(name, index));
}
/// \brief perform ${parameter:=word} expansion
@@ -459,9 +461,11 @@ public:
/// \param the value of the word
/// \return the expansion result
const std::string do_assign_expansion(const std::string& name,
- const std::string& value)
+ const std::string& value,
+ const unsigned index)
{
- return (is_unset_or_null(name)? set_value(name, value) : resolve<std::string>(name));
+ return (is_unset_or_null(name, index)?
+ set_value(name, value, index) : resolve<std::string>(name, index));
}
/// \brief perform ${parameter:+word} expansion
@@ -469,18 +473,20 @@ public:
/// \param the value of the word
/// \return the expansion result
const std::string do_alternate_expansion(const std::string& name,
- const std::string& value)
+ const std::string& value,
+ const unsigned index)
{
- return (is_unset_or_null(name)? "" : value);
+ return (is_unset_or_null(name, index)? "" : value);
}
/// \brief perform substring expansion
/// \param the offset of the substring
/// \return the expansion result
const std::string do_substring_expansion(const std::string& name,
- int offset)
+ int offset,
+ const unsigned index)
{
- std::string value = resolve<std::string>(name);
+ std::string value = resolve<std::string>(name, index);
if(!get_real_offset(offset, value))
return "";
return value.substr(offset);
@@ -492,11 +498,12 @@ public:
/// \return the expansion result
const std::string do_substring_expansion(const std::string& name,
int offset,
- int length)
+ int length,
+ const unsigned index)
{
if(length < 0)
throw interpreter_exception("length of substring expression should be greater or equal to zero");
- std::string value = resolve<std::string>(name);
+ std::string value = resolve<std::string>(name, index);
if(!get_real_offset(offset, value))
return "";
return value.substr(offset, length);
@@ -513,5 +520,15 @@ public:
return value->get_length(index);
}
+ /// \brief get the length of an array
+ /// \param the name of the array
+ /// \return the length of the array
+ unsigned get_array_length(const std::string& name)
+ {
+ std::shared_ptr<variable> value = members.resolve(name);
+ if(!value)
+ return 0;
+ return value->get_array_length();
+ }
};
#endif
diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
index 5992a67..7654ebe 100644
--- a/src/core/symbols.hpp
+++ b/src/core/symbols.hpp
@@ -125,10 +125,6 @@ class variable
/// \brief whether the variable is readonly
bool readonly;
- /// \var private::null_value
- /// \brief whether the variable is null
- bool null_value;
-
public:
/// \brief retrieve variable name
/// \return const string value of variable name
@@ -142,9 +138,10 @@ public:
const T& v,
bool ro=false,
bool is_null=false)
- : name(name), readonly(ro), null_value(is_null)
+ : name(name), readonly(ro)
{
- value[0] = v;
+ if(!is_null)
+ value[0] = v;
}
/// \brief retrieve actual value of the variable, if index is out of bound,
@@ -190,8 +187,10 @@ public:
if(readonly)
throw interpreter_exception(get_name() + " is readonly variable");
- null_value = is_null;
- value[index] = new_value;
+ if(is_null)
+ value.erase(index);
+ else
+ value[index] = new_value;
}
/// \brief get the length of a variable
@@ -211,9 +210,9 @@ public:
/// \brief check whether the value of the variable is null
/// \return whether the value of the variable is null
- bool is_null() const
+ bool is_null(const unsigned index=0) const
{
- return null_value;
+ return value.find(index) == value.end();
}
};
@@ -222,8 +221,8 @@ 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)
+ bool)
+ : 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 9bb561a..fbf073e 100644
--- a/src/core/tests/interpreter_test.cpp
+++ b/src/core/tests/interpreter_test.cpp
@@ -59,9 +59,16 @@ TEST(interpreter, is_unset_or_null)
{
interpreter walker;
walker.define("foo", "hello");
- EXPECT_FALSE(walker.is_unset_or_null("foo"));
+ EXPECT_FALSE(walker.is_unset_or_null("foo", 0));
walker.define("foo", "hello", false, true);
- EXPECT_TRUE(walker.is_unset_or_null("foo"));
+ EXPECT_TRUE(walker.is_unset_or_null("foo", 0));
+
+ std::map<int, std::string> values = {{0, "1"}, {1, "2"}, {2, "3"}};
+ walker.define("bar", values);
+ EXPECT_FALSE(walker.is_unset_or_null("bar", 0));
+ EXPECT_FALSE(walker.is_unset_or_null("bar", 1));
+ EXPECT_FALSE(walker.is_unset_or_null("bar", 2));
+ EXPECT_TRUE(walker.is_unset_or_null("bar", 3));
}
TEST(interpreter, is_unset)
@@ -134,5 +141,5 @@ TEST(interpreter, get_array_values)
TEST(interperter, substring_expansion_exception)
{
interpreter walker;
- EXPECT_THROW(walker.do_substring_expansion("", 0, -1), interpreter_exception);
+ EXPECT_THROW(walker.do_substring_expansion("", 0, -1, 0), interpreter_exception);
}
next reply other threads:[~2011-04-14 4:50 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-14 4:50 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-23 14:34 Petteri Räty
2011-05-22 21:00 Petteri Räty
2011-04-28 6:19 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=60fe984fb2c868848a8fb71fe2272a24a78d350a.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