This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/2] 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.
---
 parse.cxx                          |   46 +++++++++++++++++++++++------------
 stap.1.in                          |    5 +++-
 testsuite/parseko/preprocess14.stp |    4 +++
 testsuite/parseko/preprocess15.stp |    4 +++
 testsuite/parseok/twenty.stp       |   12 +++++++++
 5 files changed, 54 insertions(+), 17 deletions(-)
 create mode 100755 testsuite/parseko/preprocess14.stp
 create mode 100755 testsuite/parseko/preprocess15.stp
 create mode 100755 testsuite/parseok/twenty.stp

diff --git a/parse.cxx b/parse.cxx
index 41a13ca..a2e2b65 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 aafd2d7..3ac1c39 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 0000000..7946f0e
--- /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 0000000..c4aaa9c
--- /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 0000000..d474ad5
--- /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 %)
-- 
1.5.6.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]