summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2010-02-18 23:22:18 +0100
committerMark Wielaard <mjw@redhat.com>2010-02-19 12:48:17 +0100
commit717a457b697a46b8904792d59cf568d848fb2a73 (patch)
tree124c5d034b201b1f438d3f89fc037d8acbae0080
parent215c7a01b0d88eae2b0e3529412f3d95525b8ede (diff)
downloadsystemtap-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.cxx43
-rwxr-xr-xtestsuite/semok/config_number.stp20
2 files changed, 51 insertions, 12 deletions
diff --git a/parse.cxx b/parse.cxx
index 2688d6db..a7b3ebd7 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -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()
+}