summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--parse.cxx25
-rw-r--r--stap.1.in5
-rw-r--r--stapex.5.in8
-rw-r--r--staptree.cxx9
-rw-r--r--staptree.h2
-rwxr-xr-xtestsuite/buildok/twentyone.stp27
-rwxr-xr-xtestsuite/parseko/fifteen.stp6
-rwxr-xr-xtestsuite/parseko/fourteen.stp2
-rwxr-xr-xtestsuite/parseok/thirteen.stp8
-rw-r--r--translate.cxx6
11 files changed, 102 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 4a1c18b3..c87915ff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2005-10-07 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 1366.
+ * staptree.h (foreach_loop): Add sort_column, sort_direction fields.
+ * parse.cxx (parse_foreach_loop): Parse "+"/"-" suffix operators.
+ * stap.1.in, stapex.5.in: Document them.
+ * staptree.cxx (foreach_loop print, copy): Propagate them.
+ * translate.cxx (visit_foreach_loop): Support them.
+ * testsuite/parseok/fifteen.stp, parseko/thirteen.stp,
+ buildok/twentyone.stp: Test them.
+
2005-10-07 Kevin Stafford <kevinrs@us.ibm.com>
* tapset/system_calls.stp: All 281 syscalls *prototyped*. They
diff --git a/parse.cxx b/parse.cxx
index 9f714359..bbb209b8 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -1148,6 +1148,7 @@ parser::parse_foreach_loop ()
throw parse_error ("expected 'foreach'");
foreach_loop* s = new foreach_loop;
s->tok = t;
+ s->sort_direction = 0;
t = next ();
if (! (t->type == tok_operator && t->content == "("))
@@ -1173,9 +1174,20 @@ parser::parse_foreach_loop ()
sym->name = t->content;
s->indexes.push_back (sym);
+ t = peek ();
+ if (t && t->type == tok_operator &&
+ (t->content == "+" || t->content == "-"))
+ {
+ if (s->sort_direction)
+ throw parse_error ("multiple sort directives");
+ s->sort_direction = (t->content == "+") ? 1 : -1;
+ s->sort_column = s->indexes.size();
+ next();
+ }
+
if (parenthesized)
{
- const token* t = peek ();
+ t = peek ();
if (t && t->type == tok_operator && t->content == ",")
{
next ();
@@ -1202,6 +1214,17 @@ parser::parse_foreach_loop ()
throw parse_error ("expected identifier");
s->base = t->content;
+ t = peek ();
+ if (t && t->type == tok_operator &&
+ (t->content == "+" || t->content == "-"))
+ {
+ if (s->sort_direction)
+ throw parse_error ("multiple sort directives");
+ s->sort_direction = (t->content == "+") ? 1 : -1;
+ s->sort_column = 0;
+ next();
+ }
+
t = next ();
if (! (t->type == tok_operator && t->content == ")"))
throw parse_error ("expected ')'");
diff --git a/stap.1.in b/stap.1.in
index 0c697498..ef82efb1 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -217,9 +217,14 @@ STMT, then the iteration expression EXP1.
.BR foreach " (VAR " in " ARRAY) STMT"
Loop over each element of the named global array, assigning current
key to VAR. The array may not be modified within the statement.
+By adding a single
+.BR + " or " -
+operator after the VAR or the ARRAY identifier, the iteration will
+proceed in a sorted order, by ascending or descending index or value.
.TP
.BR foreach " ([VAR1, VAR2, ...] " in " ARRAY) STMT"
Same as above, used when the array is indexed with a tuple of keys.
+A sorting suffix may be used on at most one VAR or ARRAY identifier.
.TP
.BR break ", " continue
Exit or iterate the innermost nesting loop
diff --git a/stapex.5.in b/stapex.5.in
index f62eb112..d19c37e5 100644
--- a/stapex.5.in
+++ b/stapex.5.in
@@ -35,10 +35,10 @@ probe begin {
}
probe end {
- foreach (x in odds) {
+ foreach (x+ in odds) {
log("odds[" . string(x) . "] = " . string(odds[x]))
}
- foreach (x in evens) {
+ foreach (x in evens-) {
log("evens[" . string(x) . "] = " . string(evens[x]))
}
}
@@ -49,9 +49,9 @@ odds[1] = 1
odds[3] = 5
odds[4] = 7
odds[5] = 9
-evens[2] = 2
-evens[4] = 6
evens[5] = 8
+evens[4] = 6
+evens[2] = 2
.ESAMPLE
Note that the evens[1] key is missing, since its value was zero. Any
array element with an "empty" value (zero or empty string) is
diff --git a/staptree.cxx b/staptree.cxx
index a1e82158..94fd540d 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -359,8 +359,13 @@ void foreach_loop::print (ostream& o) const
{
if (i > 0) o << ", ";
indexes[i]->print (o);
+ if (sort_direction != 0 && sort_column == i+1)
+ o << (sort_direction > 0 ? "+" : "-");
}
- o << "] in " << base << ") ";
+ o << "] in " << base;
+ if (sort_direction != 0 && sort_column == 0)
+ o << (sort_direction > 0 ? "+" : "-");
+ o << ") ";
block->print (o);
}
@@ -1185,6 +1190,8 @@ deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
}
n->base = s->base;
n->base_referent = NULL;
+ n->sort_direction = s->sort_direction;
+ n->sort_column = s->sort_column;
require <statement*> (this, &(n->block), s->block);
provide <foreach_loop*> (this, n);
}
diff --git a/staptree.h b/staptree.h
index fd19bd99..8bc901d5 100644
--- a/staptree.h
+++ b/staptree.h
@@ -312,6 +312,8 @@ struct foreach_loop: public statement
std::vector<symbol*> indexes;
std::string base;
vardecl* base_referent;
+ int sort_direction; // -1: decreasing, 0: none, 1: increasing
+ unsigned sort_column; // 0: value, 1..N: index
statement* block;
void print (std::ostream& o) const;
diff --git a/testsuite/buildok/twentyone.stp b/testsuite/buildok/twentyone.stp
new file mode 100755
index 00000000..052c3a17
--- /dev/null
+++ b/testsuite/buildok/twentyone.stp
@@ -0,0 +1,27 @@
+#! stap -p4
+
+global a
+
+probe begin {
+ a[5] = 0
+ a[4] = 2
+ a[3] = 5
+ a[2] = 8
+ a[1] = 1
+ a[0] = -4
+ exit ()
+}
+
+probe end {
+ log ("x+ in a")
+ foreach (x+ in a) log ("a[" . string(x) . "]=" . string(a[x]))
+
+ log ("x- in a")
+ foreach (x- in a) log ("a[" . string(x) . "]=" . string(a[x]))
+
+ log ("x in a+")
+ foreach (x in a+) log ("a[" . string(x) . "]=" . string(a[x]))
+
+ log ("x in a-")
+ foreach (x in a-) log ("a[" . string(x) . "]=" . string(a[x]))
+}
diff --git a/testsuite/parseko/fifteen.stp b/testsuite/parseko/fifteen.stp
new file mode 100755
index 00000000..35208740
--- /dev/null
+++ b/testsuite/parseko/fifteen.stp
@@ -0,0 +1,6 @@
+#! stap -p1
+
+probe begin
+{
+ foreach ([x+,y-] in a) {}
+}
diff --git a/testsuite/parseko/fourteen.stp b/testsuite/parseko/fourteen.stp
index b646f8b6..32a8979a 100755
--- a/testsuite/parseko/fourteen.stp
+++ b/testsuite/parseko/fourteen.stp
@@ -1,4 +1,4 @@
-#! stap -p2
+#! stap -p1
function zoo () %{ /* invalid embedded code */ %}
diff --git a/testsuite/parseok/thirteen.stp b/testsuite/parseok/thirteen.stp
new file mode 100755
index 00000000..7c8c5d4b
--- /dev/null
+++ b/testsuite/parseok/thirteen.stp
@@ -0,0 +1,8 @@
+#! stap -p1
+
+probe one
+{
+ foreach ([x+,y] in a) ;
+ foreach ([x,y-] in a) ;
+ foreach ([x,y] in a+) ;
+}
diff --git a/translate.cxx b/translate.cxx
index 276382e5..bd1f576a 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -1538,6 +1538,12 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
//
// varlock_r guard (*this, mv);
+ // sort array if desired
+ if (s->sort_direction)
+ o->newline() << "_stp_map_sort (" << mv.qname() << ", "
+ << s->sort_column << ", " << - s->sort_direction << ");";
+ // NB: sort direction sense is opposite in runtime, thus the negation
+
o->newline() << iv << " = " << iv.start (mv) << ";";
// condition