summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrzemyslaw Pawelczyk <przemyslaw@pawelczyk.it>2009-08-28 02:11:47 +0200
committerJosh Stone <jistone@redhat.com>2009-08-28 11:21:24 -0700
commit2d7881bf6e14d14fa1394f65f11b4d1dce4e2623 (patch)
tree85ca79b32737d42779c3b02fe0d290f6f9f25579
parenta4433a9da1f21c6536266531308ba231e5efae81 (diff)
downloadsystemtap-steved-2d7881bf6e14d14fa1394f65f11b4d1dce4e2623.tar.gz
systemtap-steved-2d7881bf6e14d14fa1394f65f11b4d1dce4e2623.tar.xz
systemtap-steved-2d7881bf6e14d14fa1394f65f11b4d1dce4e2623.zip
Support || and && in preprocessor's conditions.
* parse.cxx (parser::scan_pp): Add || and &&. * stap.1.in: Document || and && in PREPROCESSING. * testsuite/parseok/twenty.stp: Test case. * testsuite/parseko/preprocess14.stp: Ditto. * testsuite/parseko/preprocess15.stp: Ditto. Signed-off-by: Josh Stone <jistone@redhat.com>
-rw-r--r--parse.cxx46
-rw-r--r--stap.1.in5
-rwxr-xr-xtestsuite/parseko/preprocess14.stp4
-rwxr-xr-xtestsuite/parseko/preprocess15.stp4
-rwxr-xr-xtestsuite/parseok/twenty.stp12
5 files changed, 54 insertions, 17 deletions
diff --git a/parse.cxx b/parse.cxx
index 41a13ca5..a2e2b656 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -321,27 +321,41 @@ parser::scan_pp (bool wildcard)
// We have a %( - it's time to throw a preprocessing party!
- const token *l, *op, *r;
- l = input.scan (false); // NB: not recursive, though perhaps could be
- op = input.scan (false);
- r = input.scan (false);
- if (l == 0 || op == 0 || r == 0)
- throw parse_error ("incomplete condition after '%('", t);
- // NB: consider generalizing to consume all tokens until %?, and
- // passing that as a vector to an evaluator.
-
- // Do not evaluate the condition if we haven't expanded everything.
- // This may occur when having several recursive conditionals.
- bool result = eval_pp_conditional (session, l, op, r);
- delete l;
- delete op;
- delete r;
+ bool result = false;
+ bool and_result = true;
+ const token *n = NULL;
+ do {
+ const token *l, *op, *r;
+ l = input.scan (false); // NB: not recursive, though perhaps could be
+ op = input.scan (false);
+ r = input.scan (false);
+ if (l == 0 || op == 0 || r == 0)
+ throw parse_error ("incomplete condition after '%('", t);
+ // NB: consider generalizing to consume all tokens until %?, and
+ // passing that as a vector to an evaluator.
+
+ // Do not evaluate the condition if we haven't expanded everything.
+ // This may occur when having several recursive conditionals.
+ and_result &= eval_pp_conditional (session, l, op, r);
+ delete l;
+ delete op;
+ delete r;
+ delete n;
+
+ n = input.scan ();
+ if (n && n->type == tok_operator && n->content == "&&")
+ continue;
+ result |= and_result;
+ and_result = true;
+ if (! (n && n->type == tok_operator && n->content == "||"))
+ break;
+ } while (true);
/*
clog << "PP eval (" << *t << ") == " << result << endl;
*/
- const token *m = input.scan (); // NB: not recursive
+ const token *m = n; // NB: not recursive
if (! (m && m->type == tok_operator && m->content == "%?"))
throw parse_error ("expected '%?' marker for conditional", t);
delete m; // "%?"
diff --git a/stap.1.in b/stap.1.in
index aafd2d7d..3ac1c398 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -309,7 +309,10 @@ ternary operator:
.ESAMPLE
The CONDITION is either an expression whose format is determined by its
first keyword, or a string literals comparison or a numeric literals
-comparison.
+comparison. It can be also composed of many alternatives and conjunctions
+of CONDITIONs (meant as in previous sentence) using || and && respectively.
+However, parentheses are not supported yet, so remembering that conjunction
+takes precedence over alternative is important.
.PP
If the first part is the identifier
.BR kernel_vr " or " kernel_v
diff --git a/testsuite/parseko/preprocess14.stp b/testsuite/parseko/preprocess14.stp
new file mode 100755
index 00000000..7946f0e4
--- /dev/null
+++ b/testsuite/parseko/preprocess14.stp
@@ -0,0 +1,4 @@
+#! stap -p1
+
+# incomplete compound condition
+%( arch == "2.6" && %? probe begin() { } %)
diff --git a/testsuite/parseko/preprocess15.stp b/testsuite/parseko/preprocess15.stp
new file mode 100755
index 00000000..c4aaa9ce
--- /dev/null
+++ b/testsuite/parseko/preprocess15.stp
@@ -0,0 +1,4 @@
+#! stap -p1
+
+# bad compound condition
+%( arch == "2.6" && || arch == "2.66" %? probe begin() { } %)
diff --git a/testsuite/parseok/twenty.stp b/testsuite/parseok/twenty.stp
new file mode 100755
index 00000000..d474ad5d
--- /dev/null
+++ b/testsuite/parseok/twenty.stp
@@ -0,0 +1,12 @@
+#! stap -p1
+
+global
+%( kernel_v > "2.6" && kernel_vr != "2.9.77-2873NOTHING" && kernel_v <= "3.5" && kernel_vr == "2.3.5-2.43.54.2" %? "FAIL1" %: PASS %)
+
+global
+%( arch == "i386" || arch == "i686" || arch == "x86_64" %? x86 %: other %)
+
+global
+%( $# != 2 && @# < "1" && @# == "0" && $# >= 3 %?
+ %( $2 >= "12" %? $3 FAIL2 %: $2 FAIL3 %) #This line must not be evaluated
+%: PASS2 %)