aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Neto <dneto@google.com>2017-05-03 12:51:34 +0200
committerDavid Neto <dneto@google.com>2017-05-03 12:51:34 +0200
commit766bd82f05211f7d9cc59b678eb6188151a044ec (patch)
tree4e7b8eab1144a03e0a5c8794892469e631b68301
parent42f27650258c5817f22e66355b93cd7908190ea8 (diff)
downloadeffcee-766bd82f05211f7d9cc59b678eb6188151a044ec.tar.gz
Undefined variable never matches
-rw-r--r--effcee/check.cc10
-rw-r--r--effcee/check.h4
-rw-r--r--effcee/match_test.cc11
3 files changed, 23 insertions, 2 deletions
diff --git a/effcee/check.cc b/effcee/check.cc
index d927994..28d9227 100644
--- a/effcee/check.cc
+++ b/effcee/check.cc
@@ -76,6 +76,11 @@ Check::Check(Type type, StringPiece param) : type_(type), param_(param) {
parts_.push_back(make_unique<Check::Part>(Part::Type::Fixed, param));
}
+bool Check::Part::MightMatch(const VarMapping& vars) const {
+ return type_ != Type::VarUse ||
+ vars.find(VarUseName().as_string()) != vars.end();
+}
+
std::string Check::Part::Regex(const VarMapping& vars) const {
switch (type_) {
case Type::Fixed:
@@ -90,7 +95,7 @@ std::string Check::Part::Regex(const VarMapping& vars) const {
// Return the escaped form of the current value of the variable.
return RE2::QuoteMeta((*where).second);
} else {
- // The variable is not yet set.
+ // The variable is not yet set. Should not get here.
return "";
}
}
@@ -101,6 +106,9 @@ std::string Check::Part::Regex(const VarMapping& vars) const {
bool Check::Matches(StringPiece* input, StringPiece* captured,
VarMapping* vars) const {
if (parts_.empty()) return false;
+ for (auto& part : parts_) {
+ if (!part->MightMatch(*vars)) return false;
+ }
std::unordered_map<int, std::string> var_def_indices;
diff --git a/effcee/check.h b/effcee/check.h
index fec0d80..005d00c 100644
--- a/effcee/check.h
+++ b/effcee/check.h
@@ -74,6 +74,10 @@ class Check {
expression_(expr),
num_capturing_groups_(CountCapturingGroups()) {}
+ // Returns true if this part might match a target string. The only case where
+ // this is false is for a VarUse part where the variable is not yet defined.
+ bool MightMatch(const VarMapping& vars) const;
+
// Returns a regular expression to match this part, given a mapping of
// variable names to values. If this part is a fixed string or variable use
// then quoting has been applied.
diff --git a/effcee/match_test.cc b/effcee/match_test.cc
index 1824911..d1d0944 100644
--- a/effcee/match_test.cc
+++ b/effcee/match_test.cc
@@ -741,7 +741,7 @@ Begin
}
-// TODO: Statefulness: variable definitions and uses
+// Statefulness: variable definitions and uses
TEST(Match, VarDefFollowedByUse) {
const auto result =
@@ -749,4 +749,13 @@ TEST(Match, VarDefFollowedByUse) {
EXPECT_TRUE(result) << result.message();
}
+TEST(Match, UndefinedVarNeverMatches) {
+ const auto result =
+ Match("Hello HeXllo", "CHECK: He[[X]]llo");
+ EXPECT_FALSE(result) << result.message();
+}
+
+
+// TODO: DAG def after use
+
} // namespace