diff options
-rw-r--r-- | parse.cxx | 46 | ||||
-rw-r--r-- | stap.1.in | 5 | ||||
-rwxr-xr-x | testsuite/parseko/preprocess14.stp | 4 | ||||
-rwxr-xr-x | testsuite/parseko/preprocess15.stp | 4 | ||||
-rwxr-xr-x | testsuite/parseok/twenty.stp | 12 |
5 files changed, 54 insertions, 17 deletions
@@ -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; // "%?" @@ -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 %) |