diff options
author | Mark Wielaard <mjw@redhat.com> | 2010-02-19 00:11:18 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2010-02-19 12:48:17 +0100 |
commit | 4227f98d2100dbae5009a39e05177c090886ed3f (patch) | |
tree | 92d8a2b5f91b47a9fa7647ffccafb2b4a5434962 | |
parent | 717a457b697a46b8904792d59cf568d848fb2a73 (diff) | |
download | systemtap-steved-4227f98d2100dbae5009a39e05177c090886ed3f.tar.gz systemtap-steved-4227f98d2100dbae5009a39e05177c090886ed3f.tar.xz systemtap-steved-4227f98d2100dbae5009a39e05177c090886ed3f.zip |
Allow CONFIG_foo COMPARISON-OP CONFIG_bar in preprocessor conditionals.
* parse.cxx (eval_pp_conditional): If rhs and lhs are both CONFIG_...
identifiers try to convert them both to numbers or otherwise threat
them both as strings for eval_comparison.
* testsuite/semok/config_config.stp: New test.
-rw-r--r-- | parse.cxx | 28 | ||||
-rwxr-xr-x | testsuite/semok/config_config.stp | 17 |
2 files changed, 43 insertions, 2 deletions
@@ -185,6 +185,7 @@ bool eval_comparison (const OPERAND& lhs, const token* op, const OPERAND& rhs) // or: arch COMPARISON-OP "arch-string" // or: CONFIG_foo COMPARISON-OP "config-string" // or: CONFIG_foo COMPARISON-OP number +// or: CONFIG_foo COMPARISON-OP CONFIG_bar // or: "string1" COMPARISON-OP "string2" // or: number1 COMPARISON-OP number2 // The %: ELSE-TOKENS part is optional. @@ -304,9 +305,32 @@ bool eval_pp_conditional (systemtap_session& s, int64_t rhs = lex_cast<int64_t>(r->content); return eval_comparison (lhs, op, rhs); } + else if (r->type == tok_identifier + && r->content.substr(0,7) == "CONFIG_") + { + // First try to convert both to numbers, + // otherwise threat both as strings. + const char* startp = s.kernel_config[l->content].c_str (); + char* endp = (char*) startp; + errno = 0; + int64_t val = (int64_t) strtoll (startp, & endp, 0); + if (errno != ERANGE && errno != EINVAL && *endp == '\0') + { + int64_t lhs = val; + startp = s.kernel_config[r->content].c_str (); + endp = (char*) startp; + errno = 0; + int64_t rhs = (int64_t) strtoll (startp, & endp, 0); + if (errno != ERANGE && errno != EINVAL && *endp == '\0') + return eval_comparison (lhs, op, rhs); + } + + string lhs = s.kernel_config[l->content]; + string rhs = s.kernel_config[r->content]; + return eval_comparison (lhs, op, rhs); + } else - throw parse_error ("expected string or number literal as right value", - r); + throw parse_error ("expected string, number literal or other CONFIG_... as right value", r); } else if (l->type == tok_string && r->type == tok_string) { diff --git a/testsuite/semok/config_config.stp b/testsuite/semok/config_config.stp new file mode 100755 index 00000000..287931e2 --- /dev/null +++ b/testsuite/semok/config_config.stp @@ -0,0 +1,17 @@ +#! stap -p2 + +# check that CONFIGs can match other CONFIGS. +probe + %( CONFIG_HZ == CONFIG_NR_CPUS + || CONFIG_NR_CPUS > CONFIG_HZ + || CONFIG_NR_CPUS < CONFIG_HZ %? + %( CONFIG_NFSD == CONFIG_NFS_COMMON + || CONFIG_NFS_COMMON != CONFIG_NFSD + %? begin + %: noprobe + %) + %: nonoprobe + %) +{ + exit() +} |