FileCheck.cpp revision 3ff9563c3e391954b2e224afcf8b2b0fcc3888aa
181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner//===- FileCheck.cpp - Check that File's Contents match what is expected --===// 281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// The LLVM Compiler Infrastructure 481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// This file is distributed under the University of Illinois Open Source 681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// License. See LICENSE.TXT for details. 781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner//===----------------------------------------------------------------------===// 981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 1081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// FileCheck does a line-by line check of a file that validates whether it 1181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// contains the expected content. This is useful for regression tests etc. 1281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 1381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// This program exits with an error status of 2 on error, exit status of 0 if 1481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// the file matched the expected contents, and exit status of 1 if it did not 1581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// contain the expected contents. 1681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 1781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner//===----------------------------------------------------------------------===// 1881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 193ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer#include "llvm/ADT/OwningPtr.h" 2081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/CommandLine.h" 2181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/MemoryBuffer.h" 2281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/PrettyStackTrace.h" 23528700863adefca8de461ce28a7d903729fb96b4Chris Lattner#include "llvm/Support/Regex.h" 2481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/SourceMgr.h" 2581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/raw_ostream.h" 261f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Signals.h" 27333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer#include "llvm/Support/system_error.h" 28fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar#include "llvm/ADT/SmallString.h" 29eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner#include "llvm/ADT/StringMap.h" 30eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner#include <algorithm> 3181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerusing namespace llvm; 3281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3481cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required); 3581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3781cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerInputFilename("input-file", cl::desc("File to check (defaults to stdin)"), 3881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::init("-"), cl::value_desc("filename")); 3981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 4081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 4181cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckPrefix("check-prefix", cl::init("CHECK"), 4281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::desc("Prefix to use from check file (defaults to 'CHECK')")); 4381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 4488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattnerstatic cl::opt<bool> 4588a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris LattnerNoCanonicalizeWhiteSpace("strict-whitespace", 4688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner cl::desc("Do not treat all horizontal whitespace as equivalent")); 4788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 48a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 49a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Pattern Handling Code. 50a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 51a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 529fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerclass Pattern { 5394638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner SMLoc PatternLoc; 547112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 55824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen /// MatchEOF - When set, this pattern only matches the end of file. This is 56824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen /// used for trailing CHECK-NOTs. 57824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen bool MatchEOF; 58824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen 595d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// FixedStr - If non-empty, this pattern is a fixed string match with the 605d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// specified fixed string. 612702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner StringRef FixedStr; 627112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 635d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// RegEx - If non-empty, this is a regex pattern. 645d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner std::string RegExStr; 657112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 66eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// VariableUses - Entries in this vector map to uses of a variable in the 67eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// pattern, e.g. "foo[[bar]]baz". In this case, the RegExStr will contain 68eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// "foobaz" and we'll get an entry in this vector that tells us to insert the 69eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// value of bar at offset 3. 70eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::vector<std::pair<StringRef, unsigned> > VariableUses; 717112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 72eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// VariableDefs - Entries in this vector map to definitions of a variable in 73eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// the pattern, e.g. "foo[[bar:.*]]baz". In this case, the RegExStr will 74eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// contain "foo(.*)baz" and VariableDefs will contain the pair "bar",1. The 75eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// index indicates what parenthesized value captures the variable value. 76eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::vector<std::pair<StringRef, unsigned> > VariableDefs; 777112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 789fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerpublic: 797112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 80824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen Pattern(bool matchEOF = false) : MatchEOF(matchEOF) { } 817112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 82a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner bool ParsePattern(StringRef PatternStr, SourceMgr &SM); 837112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 849fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Match - Match the pattern string against the input buffer Buffer. This 859fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// returns the position that is matched or npos if there is no match. If 869fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// there is a match, the size of the matched string is returned in MatchLen. 87eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// 88eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// The VariableTable StringMap provides the current values of filecheck 89eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// variables and is updated if this match defines new values. 90eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t Match(StringRef Buffer, size_t &MatchLen, 91eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> &VariableTable) const; 92fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 93fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar /// PrintFailureInfo - Print additional information about a failure to match 94fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar /// involving this pattern. 95fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer, 96fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar const StringMap<StringRef> &VariableTable) const; 97fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 985d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattnerprivate: 99eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr); 100eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner bool AddRegExToRegEx(StringRef RegExStr, unsigned &CurParen, SourceMgr &SM); 101ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 102ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of 103ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// matching this pattern at the start of \arg Buffer; a distance of zero 104ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// should correspond to a perfect match. 105ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar unsigned ComputeMatchDistance(StringRef Buffer, 106ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar const StringMap<StringRef> &VariableTable) const; 1079fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner}; 1089fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 109eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 110a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattnerbool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) { 11194638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner PatternLoc = SMLoc::getFromPointer(PatternStr.data()); 1127112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 113a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Ignore trailing whitespace. 114a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner while (!PatternStr.empty() && 115a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner (PatternStr.back() == ' ' || PatternStr.back() == '\t')) 116a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner PatternStr = PatternStr.substr(0, PatternStr.size()-1); 1177112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 118a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Check that there is something on the line. 119a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (PatternStr.empty()) { 12094638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner SM.PrintMessage(PatternLoc, "found empty check string with prefix '" + 12194638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner CheckPrefix+":'", "error"); 122a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner return true; 123a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 1247112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1252702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner // Check to see if this is a fixed string, or if it has regex pieces. 126eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (PatternStr.size() < 2 || 127eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner (PatternStr.find("{{") == StringRef::npos && 128eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr.find("[[") == StringRef::npos)) { 1292702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner FixedStr = PatternStr; 1302702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner return false; 1312702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner } 1327112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 133eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Paren value #0 is for the fully matched string. Any new parenthesized 134eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // values add from their. 135eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner unsigned CurParen = 1; 1367112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1375d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Otherwise, there is at least one regex piece. Build up the regex pattern 1385d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // by escaping scary characters in fixed strings, building up one big regex. 139528700863adefca8de461ce28a7d903729fb96b4Chris Lattner while (!PatternStr.empty()) { 140eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // RegEx matches. 141eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (PatternStr.size() >= 2 && 142eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr[0] == '{' && PatternStr[1] == '{') { 1437112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 144eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Otherwise, this is the start of a regex match. Scan for the }}. 145eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t End = PatternStr.find("}}"); 146eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (End == StringRef::npos) { 147eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 148eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "found start of regex string with no end '}}'", "error"); 149eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 150eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 1517112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 152eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM)) 153eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 154eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr = PatternStr.substr(End+2); 155528700863adefca8de461ce28a7d903729fb96b4Chris Lattner continue; 156528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 1577112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 158eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Named RegEx matches. These are of two forms: [[foo:.*]] which matches .* 159eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // (or some other regex) and assigns it to the FileCheck variable 'foo'. The 160eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // second form is [[foo]] which is a reference to foo. The variable name 161964ac012017451ff24c33e6b749ec3223e1d291aDaniel Dunbar // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject 162eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // it. This is to catch some common errors. 163eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (PatternStr.size() >= 2 && 164eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr[0] == '[' && PatternStr[1] == '[') { 165eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Verify that it is terminated properly. 166eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t End = PatternStr.find("]]"); 167eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (End == StringRef::npos) { 168eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 169eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "invalid named regex reference, no ]] found", "error"); 170eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 171eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 1727112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 173eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringRef MatchStr = PatternStr.substr(2, End-2); 174eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr = PatternStr.substr(End+2); 1757112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 176eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Get the regex name (e.g. "foo"). 177eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t NameEnd = MatchStr.find(':'); 178eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringRef Name = MatchStr.substr(0, NameEnd); 1797112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 180eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (Name.empty()) { 181eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()), 182eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "invalid name in named regex: empty name", "error"); 183eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 184eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 185eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 186eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Verify that the name is well formed. 187eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner for (unsigned i = 0, e = Name.size(); i != e; ++i) 188964ac012017451ff24c33e6b749ec3223e1d291aDaniel Dunbar if (Name[i] != '_' && 189964ac012017451ff24c33e6b749ec3223e1d291aDaniel Dunbar (Name[i] < 'a' || Name[i] > 'z') && 190eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner (Name[i] < 'A' || Name[i] > 'Z') && 191eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner (Name[i] < '0' || Name[i] > '9')) { 192eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i), 193eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "invalid name in named regex", "error"); 194eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 195eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 1967112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 197eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Name can't start with a digit. 198eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (isdigit(Name[0])) { 199eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()), 200eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "invalid name in named regex", "error"); 201eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 202eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 2037112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 204eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle [[foo]]. 205eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (NameEnd == StringRef::npos) { 206eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner VariableUses.push_back(std::make_pair(Name, RegExStr.size())); 207eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner continue; 208eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 2097112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 210eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle [[foo:.*]]. 211eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner VariableDefs.push_back(std::make_pair(Name, CurParen)); 212eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExStr += '('; 213eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner ++CurParen; 2147112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 215eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM)) 216eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 217eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 218eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExStr += ')'; 219528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 2207112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 221eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle fixed string matches. 222eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Find the end, which is the start of the next regex. 223eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t FixedMatchEnd = PatternStr.find("{{"); 224eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[[")); 225eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd), RegExStr); 226eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr = PatternStr.substr(FixedMatchEnd); 227eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner continue; 228528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 229528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 230528700863adefca8de461ce28a7d903729fb96b4Chris Lattner return false; 231528700863adefca8de461ce28a7d903729fb96b4Chris Lattner} 232adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 233eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattnervoid Pattern::AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr) { 2345d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Add the characters from FixedStr to the regex, escaping as needed. This 2355d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // avoids "leaning toothpicks" in common patterns. 2365d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner for (unsigned i = 0, e = FixedStr.size(); i != e; ++i) { 2375d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner switch (FixedStr[i]) { 2385d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // These are the special characters matched in "p_ere_exp". 2395d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '(': 2405d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case ')': 2415d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '^': 2425d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '$': 2435d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '|': 2445d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '*': 2455d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '+': 2465d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '?': 2475d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '.': 2485d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '[': 2495d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '\\': 2505d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '{': 251eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TheStr += '\\'; 2525d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // FALL THROUGH. 2535d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner default: 254eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TheStr += FixedStr[i]; 2555d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner break; 2565d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner } 2575d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner } 2585d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner} 2595d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 260eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattnerbool Pattern::AddRegExToRegEx(StringRef RegexStr, unsigned &CurParen, 261eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SourceMgr &SM) { 262eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner Regex R(RegexStr); 263eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string Error; 264eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!R.isValid(Error)) { 265eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(RegexStr.data()), 266eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "invalid regex: " + Error, "error"); 267eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 268eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 2697112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 270eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExStr += RegexStr.str(); 271eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner CurParen += R.getNumMatches(); 272eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return false; 273eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner} 2745d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 275528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// Match - Match the pattern string against the input buffer Buffer. This 276528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// returns the position that is matched or npos if there is no match. If 277528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// there is a match, the size of the matched string is returned in MatchLen. 278eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattnersize_t Pattern::Match(StringRef Buffer, size_t &MatchLen, 279eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> &VariableTable) const { 280824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen // If this is the EOF pattern, match it immediately. 281824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen if (MatchEOF) { 282824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen MatchLen = 0; 283824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen return Buffer.size(); 284824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen } 285824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen 2862702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner // If this is a fixed string pattern, just match it now. 2872702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner if (!FixedStr.empty()) { 2882702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner MatchLen = FixedStr.size(); 2892702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner return Buffer.find(FixedStr); 2902702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner } 291eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 2925d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Regex match. 2937112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 294eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // If there are variable uses, we need to create a temporary string with the 295eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // actual value. 296eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringRef RegExToMatch = RegExStr; 297eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string TmpStr; 298eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!VariableUses.empty()) { 299eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TmpStr = RegExStr; 3007112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 301eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner unsigned InsertOffset = 0; 302eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) { 303fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringMap<StringRef>::iterator it = 304fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar VariableTable.find(VariableUses[i].first); 305fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // If the variable is undefined, return an error. 306fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar if (it == VariableTable.end()) 307fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar return StringRef::npos; 308fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 309eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Look up the value and escape it so that we can plop it into the regex. 310eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string Value; 311fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar AddFixedStringToRegEx(it->second, Value); 3127112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 313eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Plop it into the regex at the adjusted offset. 314eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TmpStr.insert(TmpStr.begin()+VariableUses[i].second+InsertOffset, 315eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner Value.begin(), Value.end()); 316eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner InsertOffset += Value.size(); 317eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 3187112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 319eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Match the newly constructed regex. 320eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExToMatch = TmpStr; 321eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 3227112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 3237112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 3245d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner SmallVector<StringRef, 4> MatchInfo; 325eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo)) 3265d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner return StringRef::npos; 3277112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 3285d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Successful regex match. 3295d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner assert(!MatchInfo.empty() && "Didn't get any match"); 3305d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner StringRef FullMatch = MatchInfo[0]; 3317112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 332eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // If this defines any variables, remember their values. 333eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner for (unsigned i = 0, e = VariableDefs.size(); i != e; ++i) { 334eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner assert(VariableDefs[i].second < MatchInfo.size() && 335eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "Internal paren error"); 336eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner VariableTable[VariableDefs[i].first] = MatchInfo[VariableDefs[i].second]; 33794638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner } 3387112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 3395d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner MatchLen = FullMatch.size(); 3405d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner return FullMatch.data()-Buffer.data(); 341a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner} 342a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 343ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbarunsigned Pattern::ComputeMatchDistance(StringRef Buffer, 344ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar const StringMap<StringRef> &VariableTable) const { 345ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Just compute the number of matching characters. For regular expressions, we 346ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // just compare against the regex itself and hope for the best. 347ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // 348ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // FIXME: One easy improvement here is have the regex lib generate a single 349ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // example regular expression which matches, and use that as the example 350ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // string. 351ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar StringRef ExampleString(FixedStr); 352ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (ExampleString.empty()) 353ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar ExampleString = RegExStr; 354ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 3550806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar // Only compare up to the first line in the buffer, or the string size. 3560806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar StringRef BufferPrefix = Buffer.substr(0, ExampleString.size()); 3570806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar BufferPrefix = BufferPrefix.split('\n').first; 3580806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar return BufferPrefix.edit_distance(ExampleString); 359ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar} 360ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 361fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbarvoid Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer, 362fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar const StringMap<StringRef> &VariableTable) const{ 363fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // If this was a regular expression using variables, print the current 364fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // variable values. 365fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar if (!VariableUses.empty()) { 366fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) { 367fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringRef Var = VariableUses[i].first; 368fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringMap<StringRef>::const_iterator it = VariableTable.find(Var); 369fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar SmallString<256> Msg; 370fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar raw_svector_ostream OS(Msg); 371fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 372fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // Check for undefined variable references. 373fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar if (it == VariableTable.end()) { 374fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar OS << "uses undefined variable \""; 375fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar OS.write_escaped(Var) << "\"";; 376fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } else { 377fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar OS << "with variable \""; 378fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar OS.write_escaped(Var) << "\" equal to \""; 379fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar OS.write_escaped(it->second) << "\""; 380fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 381fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 382fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), OS.str(), "note", 383fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar /*ShowLine=*/false); 384fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 385fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 386ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 387ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Attempt to find the closest/best fuzzy match. Usually an error happens 388ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // because some string in the output didn't exactly match. In these cases, we 389ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // would like to show the user a best guess at what "should have" matched, to 390ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // save them having to actually check the input manually. 391ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar size_t NumLinesForward = 0; 392ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar size_t Best = StringRef::npos; 393ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar double BestQuality = 0; 394ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 395ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Use an arbitrary 4k limit on how far we will search. 396e3a1e506809acbddceb6840914879c498d454f26Dan Gohman for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) { 397ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (Buffer[i] == '\n') 398ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar ++NumLinesForward; 399ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 400d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman // Patterns have leading whitespace stripped, so skip whitespace when 401d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman // looking for something which looks like a pattern. 402d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman if (Buffer[i] == ' ' || Buffer[i] == '\t') 403d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman continue; 404d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman 405ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Compute the "quality" of this match as an arbitrary combination of the 406ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // match distance and the number of lines skipped to get to this match. 407ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable); 408ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar double Quality = Distance + (NumLinesForward / 100.); 409ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 410ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (Quality < BestQuality || Best == StringRef::npos) { 411ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar Best = i; 412ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar BestQuality = Quality; 413ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 414ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 415ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 4167a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar // Print the "possible intended match here" line if we found something 4177a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar // reasonable and not equal to what we showed in the "scanning from here" 4187a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar // line. 4197a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar if (Best && Best != StringRef::npos && BestQuality < 50) { 4207a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best), 4217a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar "possible intended match here", "note"); 422ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 423ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // FIXME: If we wanted to be really friendly we would show why the match 424ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // failed, as it can be hard to spot simple one character differences. 425ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 426fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar} 427a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 428a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 429a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Check Strings. 430a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 4319fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 4329fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner/// CheckString - This is a check that we found in the input file. 4339fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerstruct CheckString { 4349fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Pat - The pattern to match. 4359fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Pattern Pat; 4367112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 437207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner /// Loc - The location in the match file that the check string was specified. 438207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner SMLoc Loc; 4397112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 4405dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed 4415dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// to a CHECK: directive. 4425dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner bool IsCheckNext; 4437112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 444f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// NotStrings - These are all of the strings that are disallowed from 445f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// occurring between this match string and the previous one (or start of 446f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// file). 447a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner std::vector<std::pair<SMLoc, Pattern> > NotStrings; 4487112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 4499fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner CheckString(const Pattern &P, SMLoc L, bool isCheckNext) 4509fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner : Pat(P), Loc(L), IsCheckNext(isCheckNext) {} 451207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner}; 452207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 453adea46ed617982ea07fc3266d52717496c0076ceChris Lattner/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified 454adea46ed617982ea07fc3266d52717496c0076ceChris Lattner/// memory buffer, free it, and return a new one. 455adea46ed617982ea07fc3266d52717496c0076ceChris Lattnerstatic MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) { 4564c842dda3939c6b9f83ba7e8e19e43445cd9a832Chris Lattner SmallString<128> NewFile; 457adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.reserve(MB->getBufferSize()); 4587112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 459adea46ed617982ea07fc3266d52717496c0076ceChris Lattner for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd(); 460adea46ed617982ea07fc3266d52717496c0076ceChris Lattner Ptr != End; ++Ptr) { 4619f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi // Eliminate trailing dosish \r. 4629f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') { 4639f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi continue; 4649f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi } 4659f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi 466adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // If C is not a horizontal whitespace, skip it. 467adea46ed617982ea07fc3266d52717496c0076ceChris Lattner if (*Ptr != ' ' && *Ptr != '\t') { 468adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(*Ptr); 469adea46ed617982ea07fc3266d52717496c0076ceChris Lattner continue; 470adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 4717112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 472adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Otherwise, add one space and advance over neighboring space. 473adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(' '); 474adea46ed617982ea07fc3266d52717496c0076ceChris Lattner while (Ptr+1 != End && 475adea46ed617982ea07fc3266d52717496c0076ceChris Lattner (Ptr[1] == ' ' || Ptr[1] == '\t')) 476adea46ed617982ea07fc3266d52717496c0076ceChris Lattner ++Ptr; 477adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 4787112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 479adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Free the old buffer and return a new one. 480adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MemoryBuffer *MB2 = 4814c842dda3939c6b9f83ba7e8e19e43445cd9a832Chris Lattner MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier()); 4827112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 483adea46ed617982ea07fc3266d52717496c0076ceChris Lattner delete MB; 484adea46ed617982ea07fc3266d52717496c0076ceChris Lattner return MB2; 485adea46ed617982ea07fc3266d52717496c0076ceChris Lattner} 486adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 48781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 48881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// ReadCheckFile - Read the check file, which specifies the sequence of 48981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// expected strings. The strings are added to the CheckStrings vector. 49081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic bool ReadCheckFile(SourceMgr &SM, 491207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> &CheckStrings) { 49281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the check file, and tell SourceMgr about it. 4933ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> File; 4943ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer if (error_code ec = 4953ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), File)) { 4967112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov errs() << "Could not open check file '" << CheckFilename << "': " 497333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer << ec.message() << '\n'; 49881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 49981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 5003ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer MemoryBuffer *F = File.take(); 5017112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 502adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // If we want to canonicalize whitespace, strip excess whitespace from the 503adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // buffer containing the CHECK lines. 504adea46ed617982ea07fc3266d52717496c0076ceChris Lattner if (!NoCanonicalizeWhiteSpace) 505adea46ed617982ea07fc3266d52717496c0076ceChris Lattner F = CanonicalizeInputFile(F); 5067112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 50781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 50881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 509d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Find all instances of CheckPrefix followed by : in the file. 51096077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 51181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 512a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner std::vector<std::pair<SMLoc, Pattern> > NotMatches; 5137112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 51481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (1) { 51581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // See if Prefix occurs in the memory buffer. 51696077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(Buffer.find(CheckPrefix)); 5177112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 51881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // If we didn't find a match, we're done. 51996077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer.empty()) 52081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner break; 5217112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 52296077036f06478d96c123283a50cfba49858fd40Chris Lattner const char *CheckPrefixStart = Buffer.data(); 5237112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 5245dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // When we find a check prefix, keep track of whether we find CHECK: or 5255dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // CHECK-NEXT: 526f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner bool IsCheckNext = false, IsCheckNot = false; 5277112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 528d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Verify that the : is present after the prefix. 52996077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer[CheckPrefix.size()] == ':') { 53096077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+1); 53196077036f06478d96c123283a50cfba49858fd40Chris Lattner } else if (Buffer.size() > CheckPrefix.size()+6 && 53296077036f06478d96c123283a50cfba49858fd40Chris Lattner memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) { 53396077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+7); 5345dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext = true; 535f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } else if (Buffer.size() > CheckPrefix.size()+5 && 536f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) { 537f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+6); 538f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner IsCheckNot = true; 5395dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } else { 54096077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(1); 541d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner continue; 542d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner } 5437112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 54481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, we found the prefix, yay. Remember the rest of the line, but 54581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // ignore leading and trailing whitespace. 546f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t")); 5477112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 54881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Scan ahead to the end of line. 54996077036f06478d96c123283a50cfba49858fd40Chris Lattner size_t EOL = Buffer.find_first_of("\n\r"); 550a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 551e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman // Remember the location of the start of the pattern, for diagnostics. 552e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data()); 553e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman 554a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Parse the pattern. 555a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Pattern P; 556a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (P.ParsePattern(Buffer.substr(0, EOL), SM)) 55781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 5587112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 559a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Buffer = Buffer.substr(EOL); 560a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 5617112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 5625dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Verify that CHECK-NEXT lines have at least one CHECK line before them. 5635dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (IsCheckNext && CheckStrings.empty()) { 5645dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart), 5655dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "found '"+CheckPrefix+"-NEXT:' without previous '"+ 5665dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+ ": line", "error"); 5675dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return true; 5685dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 5697112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 570a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Handle CHECK-NOT. 571a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (IsCheckNot) { 572a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()), 573a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner P)); 574a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner continue; 575a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 5767112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 5777112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 57881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, add the string we captured to the output vector and move on. 5799fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner CheckStrings.push_back(CheckString(P, 580e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman PatternLoc, 5815dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext)); 582f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner std::swap(NotMatches, CheckStrings.back().NotStrings); 58381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 5847112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 585824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen // Add an EOF pattern for any trailing CHECK-NOTs. 586824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen if (!NotMatches.empty()) { 587824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen CheckStrings.push_back(CheckString(Pattern(true), 588824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen SMLoc::getFromPointer(Buffer.data()), 589824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen false)); 590824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen std::swap(NotMatches, CheckStrings.back().NotStrings); 591824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen } 592824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen 59381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (CheckStrings.empty()) { 594d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner errs() << "error: no check strings found with prefix '" << CheckPrefix 595d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner << ":'\n"; 59681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 59781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 5987112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 59981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return false; 60081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 60181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 6025dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattnerstatic void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr, 603fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringRef Buffer, 604fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringMap<StringRef> &VariableTable) { 6055dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Otherwise, we have an error, emit an error message. 6065dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(CheckStr.Loc, "expected string not found in input", 6075dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 6087112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 6095dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Print the "scanning from here" line. If the current position is at the 6105dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // end of a line, advance to the start of the next line. 61196077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r")); 6127112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 61396077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here", 6145dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "note"); 615fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 616fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // Allow the pattern to print additional information if desired. 617fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar CheckStr.Pat.PrintFailureInfo(SM, Buffer, VariableTable); 6185dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 6195dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 6203711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// CountNumNewlinesBetween - Count the number of newlines in the specified 6213711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// range. 6223711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattnerstatic unsigned CountNumNewlinesBetween(StringRef Range) { 6235dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner unsigned NumNewLines = 0; 6243711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner while (1) { 6255dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Scan for newline. 6263711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(Range.find_first_of("\n\r")); 6273711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.empty()) return NumNewLines; 6287112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 6295dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner ++NumNewLines; 6307112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 6315dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Handle \n\r and \r\n as a single newline. 6323711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.size() > 1 && 6333711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[1] == '\n' || Range[1] == '\r') && 6343711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[0] != Range[1])) 6353711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 6363711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 6375dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 6385dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 6395dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 64081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerint main(int argc, char **argv) { 64181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner sys::PrintStackTraceOnErrorSignal(); 64281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner PrettyStackTraceProgram X(argc, argv); 64381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::ParseCommandLineOptions(argc, argv); 64481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 64581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SourceMgr SM; 6467112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 64781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Read the expected strings from the check file. 648207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> CheckStrings; 64981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (ReadCheckFile(SM, CheckStrings)) 65081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 2; 65181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 65281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the file to check and add it to SourceMgr. 6533ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> File; 6543ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer if (error_code ec = 6553ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) { 6567112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov errs() << "Could not open input file '" << InputFilename << "': " 657333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer << ec.message() << '\n'; 65881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 65981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 6603ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer MemoryBuffer *F = File.take(); 6617112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 66288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Remove duplicate spaces in the input file if requested. 66388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (!NoCanonicalizeWhiteSpace) 66488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner F = CanonicalizeInputFile(F); 6657112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 66681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 6677112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 668eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// VariableTable - This holds all the current filecheck variables. 669eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> VariableTable; 6707112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 67181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Check that we have all of the expected strings, in order, in the input 67281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // file. 67396077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 6747112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 675f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner const char *LastMatch = Buffer.data(); 6767112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 67781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) { 678207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner const CheckString &CheckStr = CheckStrings[StrNo]; 6797112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 68096077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef SearchFrom = Buffer; 6817112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 68281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Find StrNo in the file. 6839fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner size_t MatchLen = 0; 684824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen size_t MatchPos = CheckStr.Pat.Match(Buffer, MatchLen, VariableTable); 685824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen Buffer = Buffer.substr(MatchPos); 6867112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 6875dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // If we didn't find a match, reject the input. 688824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen if (MatchPos == StringRef::npos) { 689fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable); 6905dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 69181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 6923711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner 6933711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch); 6943711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner 6955dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // If this check is a "CHECK-NEXT", verify that the previous match was on 6965dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // the previous line (i.e. that there is one newline between them). 6975dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (CheckStr.IsCheckNext) { 6985dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Count the number of newlines between the previous match and this one. 699f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner assert(LastMatch != F->getBufferStart() && 700f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner "CHECK-NEXT can't be the first check in a file"); 7015dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 7023711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion); 7035dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (NumNewLines == 0) { 7040b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner SM.PrintMessage(CheckStr.Loc, 7055dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+"-NEXT: is on the same line as previous match", 7065dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 70796077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), 7080b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner "'next' match was here", "note"); 7095dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch), 7105dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "previous match was here", "note"); 7115dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 7125dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 7137112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 7145dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (NumNewLines != 1) { 7150b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner SM.PrintMessage(CheckStr.Loc, 7165dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+ 7175dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "-NEXT: is not on the line after the previous match", 7185dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 71996077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), 7200b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner "'next' match was here", "note"); 7215dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch), 7225dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "previous match was here", "note"); 7235dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 7245dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 7255dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 7267112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 727f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner // If this match had "not strings", verify that they don't exist in the 728f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner // skipped region. 729eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner for (unsigned ChunkNo = 0, e = CheckStr.NotStrings.size(); 730eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner ChunkNo != e; ++ChunkNo) { 731a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner size_t MatchLen = 0; 732eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t Pos = CheckStr.NotStrings[ChunkNo].second.Match(SkippedRegion, 733eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner MatchLen, 734eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner VariableTable); 735f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner if (Pos == StringRef::npos) continue; 7367112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 737f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos), 738f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner CheckPrefix+"-NOT: string occurred!", "error"); 739528700863adefca8de461ce28a7d903729fb96b4Chris Lattner SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first, 740f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner CheckPrefix+"-NOT: pattern specified here", "note"); 741f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner return 1; 742f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } 7437112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 7445dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 74581115765218f1c1505ab6faf843ee4baf292d45fChris Lattner // Otherwise, everything is good. Step over the matched text and remember 74681115765218f1c1505ab6faf843ee4baf292d45fChris Lattner // the position after the match as the end of the last match. 7479fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Buffer = Buffer.substr(MatchLen); 74881115765218f1c1505ab6faf843ee4baf292d45fChris Lattner LastMatch = Buffer.data(); 74981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 7507112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 75181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 0; 75281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 753