aboutsummaryrefslogtreecommitdiff
path: root/utils/FileCheck/FileCheck.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-11-22 22:08:06 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-11-22 22:08:06 +0000
commitfafe93c8bcbc538573bc5e890f24f9869a11f846 (patch)
tree9adad9e5c8f6aa1136b70eb5e17397d07895c7ff /utils/FileCheck/FileCheck.cpp
parent4153982375811da8ffe8d8cc45e09d44c6f40642 (diff)
FileCheck: When a string using variable references fails to match, print
additional information about the current definitions of the variables used in the string. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89628 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/FileCheck/FileCheck.cpp')
-rw-r--r--utils/FileCheck/FileCheck.cpp54
1 files changed, 50 insertions, 4 deletions
diff --git a/utils/FileCheck/FileCheck.cpp b/utils/FileCheck/FileCheck.cpp
index 2bd6197e13..c86993d0e7 100644
--- a/utils/FileCheck/FileCheck.cpp
+++ b/utils/FileCheck/FileCheck.cpp
@@ -23,6 +23,7 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Signals.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include <algorithm>
using namespace llvm;
@@ -82,7 +83,12 @@ public:
/// variables and is updated if this match defines new values.
size_t Match(StringRef Buffer, size_t &MatchLen,
StringMap<StringRef> &VariableTable) const;
-
+
+ /// PrintFailureInfo - Print additional information about a failure to match
+ /// involving this pattern.
+ void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
+ const StringMap<StringRef> &VariableTable) const;
+
private:
static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr);
bool AddRegExToRegEx(StringRef RegExStr, unsigned &CurParen, SourceMgr &SM);
@@ -276,9 +282,15 @@ size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
unsigned InsertOffset = 0;
for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
+ StringMap<StringRef>::iterator it =
+ VariableTable.find(VariableUses[i].first);
+ // If the variable is undefined, return an error.
+ if (it == VariableTable.end())
+ return StringRef::npos;
+
// Look up the value and escape it so that we can plop it into the regex.
std::string Value;
- AddFixedStringToRegEx(VariableTable[VariableUses[i].first], Value);
+ AddFixedStringToRegEx(it->second, Value);
// Plop it into the regex at the adjusted offset.
TmpStr.insert(TmpStr.begin()+VariableUses[i].second+InsertOffset,
@@ -310,6 +322,36 @@ size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
return FullMatch.data()-Buffer.data();
}
+void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
+ const StringMap<StringRef> &VariableTable) const{
+ // If this is a fixed string, do nothing.
+ if (!FixedStr.empty())
+ return;
+
+ // If this was a regular expression using variables, print the current
+ // variable values.
+ if (!VariableUses.empty()) {
+ for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
+ StringRef Var = VariableUses[i].first;
+ StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
+ SmallString<256> Msg;
+ raw_svector_ostream OS(Msg);
+
+ // Check for undefined variable references.
+ if (it == VariableTable.end()) {
+ OS << "uses undefined variable \"";
+ OS.write_escaped(Var) << "\"";;
+ } else {
+ OS << "with variable \"";
+ OS.write_escaped(Var) << "\" equal to \"";
+ OS.write_escaped(it->second) << "\"";
+ }
+
+ SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), OS.str(), "note",
+ /*ShowLine=*/false);
+ }
+ }
+}
//===----------------------------------------------------------------------===//
// Check Strings.
@@ -478,7 +520,8 @@ static bool ReadCheckFile(SourceMgr &SM,
}
static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
- StringRef Buffer) {
+ StringRef Buffer,
+ StringMap<StringRef> &VariableTable) {
// Otherwise, we have an error, emit an error message.
SM.PrintMessage(CheckStr.Loc, "expected string not found in input",
"error");
@@ -489,6 +532,9 @@ static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here",
"note");
+
+ // Allow the pattern to print additional information if desired.
+ CheckStr.Pat.PrintFailureInfo(SM, Buffer, VariableTable);
}
/// CountNumNewlinesBetween - Count the number of newlines in the specified
@@ -559,7 +605,7 @@ int main(int argc, char **argv) {
// If we didn't find a match, reject the input.
if (Buffer.empty()) {
- PrintCheckFailed(SM, CheckStr, SearchFrom);
+ PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
return 1;
}