diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | parse.cxx | 25 | ||||
-rw-r--r-- | stap.1.in | 5 | ||||
-rw-r--r-- | stapex.5.in | 8 | ||||
-rw-r--r-- | staptree.cxx | 9 | ||||
-rw-r--r-- | staptree.h | 2 | ||||
-rwxr-xr-x | testsuite/buildok/twentyone.stp | 27 | ||||
-rwxr-xr-x | testsuite/parseko/fifteen.stp | 6 | ||||
-rwxr-xr-x | testsuite/parseko/fourteen.stp | 2 | ||||
-rwxr-xr-x | testsuite/parseok/thirteen.stp | 8 | ||||
-rw-r--r-- | translate.cxx | 6 |
11 files changed, 102 insertions, 7 deletions
@@ -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 @@ -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 ')'"); @@ -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); } @@ -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 |