FileCheck.cpp revision 5d6a05f4d4faea0c0c96fbf2bb57655df2839b34
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 1981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/CommandLine.h" 2081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/MemoryBuffer.h" 2181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/PrettyStackTrace.h" 22528700863adefca8de461ce28a7d903729fb96b4Chris Lattner#include "llvm/Support/Regex.h" 2381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/SourceMgr.h" 2481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/raw_ostream.h" 2581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/System/Signals.h" 2681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerusing namespace llvm; 2781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 2881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 2981cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required); 3081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3281cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerInputFilename("input-file", cl::desc("File to check (defaults to stdin)"), 3381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::init("-"), cl::value_desc("filename")); 3481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3681cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckPrefix("check-prefix", cl::init("CHECK"), 3781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::desc("Prefix to use from check file (defaults to 'CHECK')")); 3881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattnerstatic cl::opt<bool> 4088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris LattnerNoCanonicalizeWhiteSpace("strict-whitespace", 4188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner cl::desc("Do not treat all horizontal whitespace as equivalent")); 4288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 43a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 44a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Pattern Handling Code. 45a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 46a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 479fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerclass Pattern { 485d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// FixedStr - If non-empty, this pattern is a fixed string match with the 495d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// specified fixed string. 502702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner StringRef FixedStr; 515d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 525d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// RegEx - If non-empty, this is a regex pattern. 535d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner std::string RegExStr; 549fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerpublic: 559fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 56a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Pattern() { } 57a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 58a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner bool ParsePattern(StringRef PatternStr, SourceMgr &SM); 599fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 609fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Match - Match the pattern string against the input buffer Buffer. This 619fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// returns the position that is matched or npos if there is no match. If 629fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// there is a match, the size of the matched string is returned in MatchLen. 63528700863adefca8de461ce28a7d903729fb96b4Chris Lattner size_t Match(StringRef Buffer, size_t &MatchLen) const; 645d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 655d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattnerprivate: 665d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner void AddFixedStringToRegEx(StringRef FixedStr); 679fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner}; 689fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 69a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattnerbool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) { 70a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Ignore trailing whitespace. 71a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner while (!PatternStr.empty() && 72a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner (PatternStr.back() == ' ' || PatternStr.back() == '\t')) 73a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner PatternStr = PatternStr.substr(0, PatternStr.size()-1); 74a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 75a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Check that there is something on the line. 76a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (PatternStr.empty()) { 77a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 78a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner "found empty check string with prefix '"+CheckPrefix+":'", 79a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner "error"); 80a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner return true; 81a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 82528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 832702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner // Check to see if this is a fixed string, or if it has regex pieces. 842702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner if (PatternStr.size() < 2 || PatternStr.find("{{") == StringRef::npos) { 852702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner FixedStr = PatternStr; 862702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner return false; 872702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner } 882702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner 895d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Otherwise, there is at least one regex piece. Build up the regex pattern 905d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // by escaping scary characters in fixed strings, building up one big regex. 91528700863adefca8de461ce28a7d903729fb96b4Chris Lattner while (!PatternStr.empty()) { 92528700863adefca8de461ce28a7d903729fb96b4Chris Lattner // Handle fixed string matches. 93528700863adefca8de461ce28a7d903729fb96b4Chris Lattner if (PatternStr.size() < 2 || 94528700863adefca8de461ce28a7d903729fb96b4Chris Lattner PatternStr[0] != '{' || PatternStr[1] != '{') { 95528700863adefca8de461ce28a7d903729fb96b4Chris Lattner // Find the end, which is the start of the next regex. 96528700863adefca8de461ce28a7d903729fb96b4Chris Lattner size_t FixedMatchEnd = PatternStr.find("{{"); 975d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd)); 98528700863adefca8de461ce28a7d903729fb96b4Chris Lattner PatternStr = PatternStr.substr(FixedMatchEnd); 99528700863adefca8de461ce28a7d903729fb96b4Chris Lattner continue; 100528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 101528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 102528700863adefca8de461ce28a7d903729fb96b4Chris Lattner // Otherwise, this is the start of a regex match. Scan for the }}. 103528700863adefca8de461ce28a7d903729fb96b4Chris Lattner size_t End = PatternStr.find("}}"); 104528700863adefca8de461ce28a7d903729fb96b4Chris Lattner if (End == StringRef::npos) { 105528700863adefca8de461ce28a7d903729fb96b4Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 106528700863adefca8de461ce28a7d903729fb96b4Chris Lattner "found start of regex string with no end '}}'", "error"); 107528700863adefca8de461ce28a7d903729fb96b4Chris Lattner return true; 108528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 109528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 1105d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner StringRef RegexStr = PatternStr.substr(2, End-2); 1115d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner Regex R(RegexStr); 112528700863adefca8de461ce28a7d903729fb96b4Chris Lattner std::string Error; 113528700863adefca8de461ce28a7d903729fb96b4Chris Lattner if (!R.isValid(Error)) { 114528700863adefca8de461ce28a7d903729fb96b4Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()+2), 115528700863adefca8de461ce28a7d903729fb96b4Chris Lattner "invalid regex: " + Error, "error"); 116528700863adefca8de461ce28a7d903729fb96b4Chris Lattner return true; 117528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 118528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 1195d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner RegExStr += RegexStr.str(); 120528700863adefca8de461ce28a7d903729fb96b4Chris Lattner PatternStr = PatternStr.substr(End+2); 121528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 122528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 123528700863adefca8de461ce28a7d903729fb96b4Chris Lattner return false; 124528700863adefca8de461ce28a7d903729fb96b4Chris Lattner} 125adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 1265d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattnervoid Pattern::AddFixedStringToRegEx(StringRef FixedStr) { 1275d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Add the characters from FixedStr to the regex, escaping as needed. This 1285d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // avoids "leaning toothpicks" in common patterns. 1295d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner for (unsigned i = 0, e = FixedStr.size(); i != e; ++i) { 1305d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner switch (FixedStr[i]) { 1315d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // These are the special characters matched in "p_ere_exp". 1325d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '(': 1335d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case ')': 1345d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '^': 1355d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '$': 1365d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '|': 1375d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '*': 1385d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '+': 1395d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '?': 1405d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '.': 1415d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '[': 1425d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '\\': 1435d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '{': 1445d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner RegExStr += '\\'; 1455d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // FALL THROUGH. 1465d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner default: 1475d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner RegExStr += FixedStr[i]; 1485d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner break; 1495d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner } 1505d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner } 1515d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner} 1525d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 1535d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 154528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// Match - Match the pattern string against the input buffer Buffer. This 155528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// returns the position that is matched or npos if there is no match. If 156528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// there is a match, the size of the matched string is returned in MatchLen. 157528700863adefca8de461ce28a7d903729fb96b4Chris Lattnersize_t Pattern::Match(StringRef Buffer, size_t &MatchLen) const { 1582702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner // If this is a fixed string pattern, just match it now. 1592702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner if (!FixedStr.empty()) { 1602702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner MatchLen = FixedStr.size(); 1612702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner return Buffer.find(FixedStr); 1622702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner } 1632702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner 1645d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Regex match. 1655d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner SmallVector<StringRef, 4> MatchInfo; 1665d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner if (!Regex(RegExStr, Regex::Sub|Regex::Newline).match(Buffer, &MatchInfo)) 1675d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner return StringRef::npos; 168a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 1695d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Successful regex match. 1705d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner assert(!MatchInfo.empty() && "Didn't get any match"); 1715d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner StringRef FullMatch = MatchInfo[0]; 172528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 1735d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner MatchLen = FullMatch.size(); 1745d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner return FullMatch.data()-Buffer.data(); 175a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner} 176a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 177a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 178a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 179a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Check Strings. 180a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 1819fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 1829fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner/// CheckString - This is a check that we found in the input file. 1839fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerstruct CheckString { 1849fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Pat - The pattern to match. 1859fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Pattern Pat; 186207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 187207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner /// Loc - The location in the match file that the check string was specified. 188207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner SMLoc Loc; 189207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 1905dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed 1915dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// to a CHECK: directive. 1925dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner bool IsCheckNext; 1935dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 194f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// NotStrings - These are all of the strings that are disallowed from 195f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// occurring between this match string and the previous one (or start of 196f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// file). 197a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner std::vector<std::pair<SMLoc, Pattern> > NotStrings; 198f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 1999fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner CheckString(const Pattern &P, SMLoc L, bool isCheckNext) 2009fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner : Pat(P), Loc(L), IsCheckNext(isCheckNext) {} 201207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner}; 202207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 203adea46ed617982ea07fc3266d52717496c0076ceChris Lattner/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified 204adea46ed617982ea07fc3266d52717496c0076ceChris Lattner/// memory buffer, free it, and return a new one. 205adea46ed617982ea07fc3266d52717496c0076ceChris Lattnerstatic MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) { 206adea46ed617982ea07fc3266d52717496c0076ceChris Lattner SmallVector<char, 16> NewFile; 207adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.reserve(MB->getBufferSize()); 208adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 209adea46ed617982ea07fc3266d52717496c0076ceChris Lattner for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd(); 210adea46ed617982ea07fc3266d52717496c0076ceChris Lattner Ptr != End; ++Ptr) { 211adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // If C is not a horizontal whitespace, skip it. 212adea46ed617982ea07fc3266d52717496c0076ceChris Lattner if (*Ptr != ' ' && *Ptr != '\t') { 213adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(*Ptr); 214adea46ed617982ea07fc3266d52717496c0076ceChris Lattner continue; 215adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 216adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 217adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Otherwise, add one space and advance over neighboring space. 218adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(' '); 219adea46ed617982ea07fc3266d52717496c0076ceChris Lattner while (Ptr+1 != End && 220adea46ed617982ea07fc3266d52717496c0076ceChris Lattner (Ptr[1] == ' ' || Ptr[1] == '\t')) 221adea46ed617982ea07fc3266d52717496c0076ceChris Lattner ++Ptr; 222adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 223adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 224adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Free the old buffer and return a new one. 225adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MemoryBuffer *MB2 = 226adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MemoryBuffer::getMemBufferCopy(NewFile.data(), 227adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.data() + NewFile.size(), 228adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MB->getBufferIdentifier()); 229adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 230adea46ed617982ea07fc3266d52717496c0076ceChris Lattner delete MB; 231adea46ed617982ea07fc3266d52717496c0076ceChris Lattner return MB2; 232adea46ed617982ea07fc3266d52717496c0076ceChris Lattner} 233adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 23481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 23581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// ReadCheckFile - Read the check file, which specifies the sequence of 23681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// expected strings. The strings are added to the CheckStrings vector. 23781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic bool ReadCheckFile(SourceMgr &SM, 238207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> &CheckStrings) { 23981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the check file, and tell SourceMgr about it. 24081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner std::string ErrorStr; 24181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer *F = 24281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr); 24381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (F == 0) { 24481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner errs() << "Could not open check file '" << CheckFilename << "': " 24581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner << ErrorStr << '\n'; 24681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 24781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 248adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 249adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // If we want to canonicalize whitespace, strip excess whitespace from the 250adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // buffer containing the CHECK lines. 251adea46ed617982ea07fc3266d52717496c0076ceChris Lattner if (!NoCanonicalizeWhiteSpace) 252adea46ed617982ea07fc3266d52717496c0076ceChris Lattner F = CanonicalizeInputFile(F); 253adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 25481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 25581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 256d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Find all instances of CheckPrefix followed by : in the file. 25796077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 25881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 259a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner std::vector<std::pair<SMLoc, Pattern> > NotMatches; 260f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 26181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (1) { 26281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // See if Prefix occurs in the memory buffer. 26396077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(Buffer.find(CheckPrefix)); 26481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 26581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // If we didn't find a match, we're done. 26696077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer.empty()) 26781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner break; 26881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 26996077036f06478d96c123283a50cfba49858fd40Chris Lattner const char *CheckPrefixStart = Buffer.data(); 2705dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2715dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // When we find a check prefix, keep track of whether we find CHECK: or 2725dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // CHECK-NEXT: 273f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner bool IsCheckNext = false, IsCheckNot = false; 2745dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 275d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Verify that the : is present after the prefix. 27696077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer[CheckPrefix.size()] == ':') { 27796077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+1); 27896077036f06478d96c123283a50cfba49858fd40Chris Lattner } else if (Buffer.size() > CheckPrefix.size()+6 && 27996077036f06478d96c123283a50cfba49858fd40Chris Lattner memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) { 28096077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+7); 2815dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext = true; 282f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } else if (Buffer.size() > CheckPrefix.size()+5 && 283f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) { 284f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+6); 285f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner IsCheckNot = true; 2865dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } else { 28796077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(1); 288d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner continue; 289d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner } 290d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner 29181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, we found the prefix, yay. Remember the rest of the line, but 29281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // ignore leading and trailing whitespace. 293f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t")); 29481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 29581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Scan ahead to the end of line. 29696077036f06478d96c123283a50cfba49858fd40Chris Lattner size_t EOL = Buffer.find_first_of("\n\r"); 297a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 298a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Parse the pattern. 299a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Pattern P; 300a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (P.ParsePattern(Buffer.substr(0, EOL), SM)) 30181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 30281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 303a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Buffer = Buffer.substr(EOL); 304a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 305f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 3065dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Verify that CHECK-NEXT lines have at least one CHECK line before them. 3075dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (IsCheckNext && CheckStrings.empty()) { 3085dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart), 3095dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "found '"+CheckPrefix+"-NEXT:' without previous '"+ 3105dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+ ": line", "error"); 3115dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return true; 3125dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 3135dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 314a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Handle CHECK-NOT. 315a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (IsCheckNot) { 316a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()), 317a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner P)); 318a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner continue; 319a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 320a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 3219fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 32281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, add the string we captured to the output vector and move on. 3239fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner CheckStrings.push_back(CheckString(P, 32496077036f06478d96c123283a50cfba49858fd40Chris Lattner SMLoc::getFromPointer(Buffer.data()), 3255dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext)); 326f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner std::swap(NotMatches, CheckStrings.back().NotStrings); 32781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 32881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 32981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (CheckStrings.empty()) { 330d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner errs() << "error: no check strings found with prefix '" << CheckPrefix 331d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner << ":'\n"; 33281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 33381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 33481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 335f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner if (!NotMatches.empty()) { 336f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner errs() << "error: '" << CheckPrefix 337f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner << "-NOT:' not supported after last check line.\n"; 338f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner return true; 339f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } 340f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 34181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return false; 34281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 34381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3445dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattnerstatic void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr, 34596077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer) { 3465dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Otherwise, we have an error, emit an error message. 3475dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(CheckStr.Loc, "expected string not found in input", 3485dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 3495dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 3505dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Print the "scanning from here" line. If the current position is at the 3515dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // end of a line, advance to the start of the next line. 35296077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r")); 3535dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 35496077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here", 3555dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "note"); 3565dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 3575dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 3583711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// CountNumNewlinesBetween - Count the number of newlines in the specified 3593711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// range. 3603711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattnerstatic unsigned CountNumNewlinesBetween(StringRef Range) { 3615dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner unsigned NumNewLines = 0; 3623711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner while (1) { 3635dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Scan for newline. 3643711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(Range.find_first_of("\n\r")); 3653711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.empty()) return NumNewLines; 3665dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 3675dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner ++NumNewLines; 3685dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 3695dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Handle \n\r and \r\n as a single newline. 3703711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.size() > 1 && 3713711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[1] == '\n' || Range[1] == '\r') && 3723711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[0] != Range[1])) 3733711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 3743711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 3755dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 3765dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 3775dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 37881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerint main(int argc, char **argv) { 37981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner sys::PrintStackTraceOnErrorSignal(); 38081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner PrettyStackTraceProgram X(argc, argv); 38181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::ParseCommandLineOptions(argc, argv); 38281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 38381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SourceMgr SM; 38481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 38581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Read the expected strings from the check file. 386207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> CheckStrings; 38781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (ReadCheckFile(SM, CheckStrings)) 38881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 2; 38981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 39081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the file to check and add it to SourceMgr. 39181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner std::string ErrorStr; 39281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer *F = 39381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr); 39481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (F == 0) { 39581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner errs() << "Could not open input file '" << InputFilename << "': " 39681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner << ErrorStr << '\n'; 39781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 39881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 39988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 40088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Remove duplicate spaces in the input file if requested. 40188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (!NoCanonicalizeWhiteSpace) 40288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner F = CanonicalizeInputFile(F); 40388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 40481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 40581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 40681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Check that we have all of the expected strings, in order, in the input 40781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // file. 40896077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 40981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 410f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner const char *LastMatch = Buffer.data(); 411f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 41281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) { 413207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner const CheckString &CheckStr = CheckStrings[StrNo]; 41481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 41596077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef SearchFrom = Buffer; 41696077036f06478d96c123283a50cfba49858fd40Chris Lattner 41781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Find StrNo in the file. 4189fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner size_t MatchLen = 0; 4199fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Buffer = Buffer.substr(CheckStr.Pat.Match(Buffer, MatchLen)); 42081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 4215dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // If we didn't find a match, reject the input. 42296077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer.empty()) { 42396077036f06478d96c123283a50cfba49858fd40Chris Lattner PrintCheckFailed(SM, CheckStr, SearchFrom); 4245dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 42581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 4263711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner 4273711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch); 4283711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner 4295dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // If this check is a "CHECK-NEXT", verify that the previous match was on 4305dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // the previous line (i.e. that there is one newline between them). 4315dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (CheckStr.IsCheckNext) { 4325dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Count the number of newlines between the previous match and this one. 433f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner assert(LastMatch != F->getBufferStart() && 434f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner "CHECK-NEXT can't be the first check in a file"); 4355dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 4363711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion); 4375dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (NumNewLines == 0) { 4380b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner SM.PrintMessage(CheckStr.Loc, 4395dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+"-NEXT: is on the same line as previous match", 4405dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 44196077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), 4420b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner "'next' match was here", "note"); 4435dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch), 4445dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "previous match was here", "note"); 4455dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 4465dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 4475dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 4485dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (NumNewLines != 1) { 4490b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner SM.PrintMessage(CheckStr.Loc, 4505dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+ 4515dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "-NEXT: is not on the line after the previous match", 4525dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 45396077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), 4540b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner "'next' match was here", "note"); 4555dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch), 4565dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "previous match was here", "note"); 4575dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 4585dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 4595dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 460f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 461f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner // If this match had "not strings", verify that they don't exist in the 462f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner // skipped region. 463528700863adefca8de461ce28a7d903729fb96b4Chris Lattner for (unsigned ChunkNo = 0, e = CheckStr.NotStrings.size(); ChunkNo != e; ++ChunkNo) { 464a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner size_t MatchLen = 0; 465528700863adefca8de461ce28a7d903729fb96b4Chris Lattner size_t Pos = CheckStr.NotStrings[ChunkNo].second.Match(SkippedRegion, MatchLen); 466f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner if (Pos == StringRef::npos) continue; 467f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 468f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos), 469f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner CheckPrefix+"-NOT: string occurred!", "error"); 470528700863adefca8de461ce28a7d903729fb96b4Chris Lattner SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first, 471f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner CheckPrefix+"-NOT: pattern specified here", "note"); 472f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner return 1; 473f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } 474f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 4755dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 47681115765218f1c1505ab6faf843ee4baf292d45fChris Lattner // Otherwise, everything is good. Step over the matched text and remember 47781115765218f1c1505ab6faf843ee4baf292d45fChris Lattner // the position after the match as the end of the last match. 4789fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Buffer = Buffer.substr(MatchLen); 47981115765218f1c1505ab6faf843ee4baf292d45fChris Lattner LastMatch = Buffer.data(); 48081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 48181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 48281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 0; 48381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 484