diff options
author | Mark Wielaard <mjw@redhat.com> | 2010-02-18 23:22:18 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2010-02-19 12:48:17 +0100 |
commit | 717a457b697a46b8904792d59cf568d848fb2a73 (patch) | |
tree | 124c5d034b201b1f438d3f89fc037d8acbae0080 | |
parent | 215c7a01b0d88eae2b0e3529412f3d95525b8ede (diff) | |
download | systemtap-steved-717a457b697a46b8904792d59cf568d848fb2a73.tar.gz systemtap-steved-717a457b697a46b8904792d59cf568d848fb2a73.tar.xz systemtap-steved-717a457b697a46b8904792d59cf568d848fb2a73.zip |
Allow CONFIG_foo COMPARISON-OP number in preprocessor conditionals.
* parse.cxx (eval_pp_conditional): Handle r->type == tok_number when
l->type == tok_identifier.
* testsuite/semok/config_number.stp: New test.
-rw-r--r-- | parse.cxx | 43 | ||||
-rwxr-xr-x | testsuite/semok/config_number.stp | 20 |
2 files changed, 51 insertions, 12 deletions
@@ -184,6 +184,7 @@ bool eval_comparison (const OPERAND& lhs, const token* op, const OPERAND& rhs) // where CONDITION is: kernel_v[r] COMPARISON-OP "version-string" // or: arch COMPARISON-OP "arch-string" // or: CONFIG_foo COMPARISON-OP "config-string" +// or: CONFIG_foo COMPARISON-OP number // or: "string1" COMPARISON-OP "string2" // or: number1 COMPARISON-OP number2 // The %: ELSE-TOKENS part is optional. @@ -272,22 +273,40 @@ bool eval_pp_conditional (systemtap_session& s, return result; } - else if (l->type == tok_identifier && l->content.substr(0,7) == "CONFIG_" && r->type == tok_string) + else if (l->type == tok_identifier && l->content.substr(0,7) == "CONFIG_") { - string lhs = s.kernel_config[l->content]; // may be empty - string rhs = r->content; + if (r->type == tok_string) + { + string lhs = s.kernel_config[l->content]; // may be empty + string rhs = r->content; - int nomatch = fnmatch (rhs.c_str(), lhs.c_str(), FNM_NOESCAPE); // still spooky + int nomatch = fnmatch (rhs.c_str(), lhs.c_str(), FNM_NOESCAPE); // still spooky - bool result; - if (op->type == tok_operator && op->content == "==") - result = !nomatch; - else if (op->type == tok_operator && op->content == "!=") - result = nomatch; - else - throw parse_error ("expected '==' or '!='", op); + bool result; + if (op->type == tok_operator && op->content == "==") + result = !nomatch; + else if (op->type == tok_operator && op->content == "!=") + result = nomatch; + else + throw parse_error ("expected '==' or '!='", op); - return result; + return result; + } + else if (r->type == tok_number) + { + const char* startp = s.kernel_config[l->content].c_str (); + char* endp = (char*) startp; + errno = 0; + int64_t lhs = (int64_t) strtoll (startp, & endp, 0); + if (errno == ERANGE || errno == EINVAL || *endp != '\0') + throw parse_error ("Config option value not a number", l); + + int64_t rhs = lex_cast<int64_t>(r->content); + return eval_comparison (lhs, op, rhs); + } + else + throw parse_error ("expected string or number literal as right value", + r); } else if (l->type == tok_string && r->type == tok_string) { diff --git a/testsuite/semok/config_number.stp b/testsuite/semok/config_number.stp new file mode 100755 index 00000000..b384c3e5 --- /dev/null +++ b/testsuite/semok/config_number.stp @@ -0,0 +1,20 @@ +#! stap -p2 + +# check that number comparisons work in CONFIG checks +probe + %( CONFIG_NR_CPUS == 13 %? + noprobe + %: + %( CONFIG_NR_CPUS < 1 %? + nonoprobe + %: + %( CONFIG_NR_CPUS >= 0 %? + begin + %: + nononoprobe + %) + %) + %) +{ + exit() +} |