summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2010-02-19 00:11:18 +0100
committerMark Wielaard <mjw@redhat.com>2010-02-19 12:48:17 +0100
commit4227f98d2100dbae5009a39e05177c090886ed3f (patch)
tree92d8a2b5f91b47a9fa7647ffccafb2b4a5434962
parent717a457b697a46b8904792d59cf568d848fb2a73 (diff)
downloadsystemtap-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.cxx28
-rwxr-xr-xtestsuite/semok/config_config.stp17
2 files changed, 43 insertions, 2 deletions
diff --git a/parse.cxx b/parse.cxx
index a7b3ebd7..ad4f93f0 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -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()
+}