FileCheck.cpp revision 5dafafdeb4d89b37c6b7efbeabaa7d818c7023fe
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" 2281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/SourceMgr.h" 2381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/raw_ostream.h" 2481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/System/Signals.h" 2581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerusing namespace llvm; 2681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 2781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 2881cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required); 2981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3181cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerInputFilename("input-file", cl::desc("File to check (defaults to stdin)"), 3281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::init("-"), cl::value_desc("filename")); 3381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3581cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckPrefix("check-prefix", cl::init("CHECK"), 3681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::desc("Prefix to use from check file (defaults to 'CHECK')")); 3781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattnerstatic cl::opt<bool> 3988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris LattnerNoCanonicalizeWhiteSpace("strict-whitespace", 4088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner cl::desc("Do not treat all horizontal whitespace as equivalent")); 4188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 42207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner/// CheckString - This is a check that we found in the input file. 43207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattnerstruct CheckString { 44207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner /// Str - The string to match. 45207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::string Str; 46207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 47207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner /// Loc - The location in the match file that the check string was specified. 48207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner SMLoc Loc; 49207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 505dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed 515dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// to a CHECK: directive. 525dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner bool IsCheckNext; 535dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 545dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckString(const std::string &S, SMLoc L, bool isCheckNext) 555dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner : Str(S), Loc(L), IsCheckNext(isCheckNext) {} 56207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner}; 57207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 5881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 597bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner/// FindFixedStringInBuffer - This works like strstr, except for two things: 607bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner/// 1) it handles 'nul' characters in memory buffers. 2) it returns the end of 617bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner/// the memory buffer on match failure instead of null. 627bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattnerstatic const char *FindFixedStringInBuffer(StringRef Str, const char *CurPtr, 637bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner const MemoryBuffer &MB) { 647bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner assert(!Str.empty() && "Can't find an empty string"); 657bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner const char *BufEnd = MB.getBufferEnd(); 6681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 677bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner while (1) { 687bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner // Scan for the first character in the match string. 697bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner CurPtr = (char*)memchr(CurPtr, Str[0], BufEnd-CurPtr); 707bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner 717bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner // If we didn't find the first character of the string, then we failed to 727bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner // match. 737bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner if (CurPtr == 0) return BufEnd; 747bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner 757bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner // If the match string is one character, then we win. 767bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner if (Str.size() == 1) return CurPtr; 777bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner 787bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner // Otherwise, verify that the rest of the string matches. 797bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner if (Str.size() <= unsigned(BufEnd-CurPtr) && 807bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner memcmp(CurPtr+1, Str.data()+1, Str.size()-1) == 0) 817bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner return CurPtr; 8281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 837bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner // If not, advance past this character and try again. 847bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner ++CurPtr; 857bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner } 8681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 8781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 8881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// ReadCheckFile - Read the check file, which specifies the sequence of 8981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// expected strings. The strings are added to the CheckStrings vector. 9081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic bool ReadCheckFile(SourceMgr &SM, 91207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> &CheckStrings) { 9281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the check file, and tell SourceMgr about it. 9381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner std::string ErrorStr; 9481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer *F = 9581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr); 9681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (F == 0) { 9781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner errs() << "Could not open check file '" << CheckFilename << "': " 9881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner << ErrorStr << '\n'; 9981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 10081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 10181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 10281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 103d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Find all instances of CheckPrefix followed by : in the file. 10481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner const char *CurPtr = F->getBufferStart(), *BufferEnd = F->getBufferEnd(); 10581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 10681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (1) { 10781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // See if Prefix occurs in the memory buffer. 108d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner const char *Ptr = FindFixedStringInBuffer(CheckPrefix, CurPtr, *F); 10981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 11081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // If we didn't find a match, we're done. 11181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (Ptr == BufferEnd) 11281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner break; 11381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 1145dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner const char *CheckPrefixStart = Ptr; 1155dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 1165dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // When we find a check prefix, keep track of whether we find CHECK: or 1175dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // CHECK-NEXT: 1185dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner bool IsCheckNext; 1195dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 120d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Verify that the : is present after the prefix. 1215dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (Ptr[CheckPrefix.size()] == ':') { 1225dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner Ptr += CheckPrefix.size()+1; 1235dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext = false; 1245dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } else if (BufferEnd-Ptr > 6 && 1255dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner memcmp(Ptr+CheckPrefix.size(), "-NEXT:", 6) == 0) { 1265dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner Ptr += CheckPrefix.size()+7; 1275dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext = true; 1285dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } else { 129d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner CurPtr = Ptr+1; 130d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner continue; 131d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner } 132d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner 13381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, we found the prefix, yay. Remember the rest of the line, but 13481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // ignore leading and trailing whitespace. 13581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (*Ptr == ' ' || *Ptr == '\t') 13681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner ++Ptr; 13781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 13881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Scan ahead to the end of line. 13981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner CurPtr = Ptr; 14081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (CurPtr != BufferEnd && *CurPtr != '\n' && *CurPtr != '\r') 14181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner ++CurPtr; 14281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 14381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Ignore trailing whitespace. 14481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (CurPtr[-1] == ' ' || CurPtr[-1] == '\t') 14581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner --CurPtr; 14681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 14781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Check that there is something on the line. 14881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (Ptr >= CurPtr) { 14981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(CurPtr), 150d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner "found empty check string with prefix '"+CheckPrefix+":'", 15181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner "error"); 15281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 15381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 15481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 1555dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Verify that CHECK-NEXT lines have at least one CHECK line before them. 1565dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (IsCheckNext && CheckStrings.empty()) { 1575dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart), 1585dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "found '"+CheckPrefix+"-NEXT:' without previous '"+ 1595dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+ ": line", "error"); 1605dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return true; 1615dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 1625dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 16381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, add the string we captured to the output vector and move on. 164207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner CheckStrings.push_back(CheckString(std::string(Ptr, CurPtr), 1655dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SMLoc::getFromPointer(Ptr), 1665dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext)); 16781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 16881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 16981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (CheckStrings.empty()) { 170d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner errs() << "error: no check strings found with prefix '" << CheckPrefix 171d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner << ":'\n"; 17281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 17381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 17481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 17581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return false; 17681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 17781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 17888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner// CanonicalizeCheckStrings - Replace all sequences of horizontal whitespace in 17988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner// the check strings with a single space. 180207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattnerstatic void CanonicalizeCheckStrings(std::vector<CheckString> &CheckStrings) { 18188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner for (unsigned i = 0, e = CheckStrings.size(); i != e; ++i) { 182207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::string &Str = CheckStrings[i].Str; 18388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 18488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner for (unsigned C = 0; C != Str.size(); ++C) { 18588a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // If C is not a horizontal whitespace, skip it. 18688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (Str[C] != ' ' && Str[C] != '\t') 18788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner continue; 18888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 18988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Replace the character with space, then remove any other space 19088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // characters after it. 19188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner Str[C] = ' '; 19288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 19388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner while (C+1 != Str.size() && 19488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner (Str[C+1] == ' ' || Str[C+1] == '\t')) 19588a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner Str.erase(Str.begin()+C+1); 19688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner } 19788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner } 19888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner} 19988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 20088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified 20188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner/// memory buffer, free it, and return a new one. 20288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattnerstatic MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) { 2036f69aa356136ada3d414d04cfab4341e87b63165Daniel Dunbar SmallVector<char, 16> NewFile; 20488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner NewFile.reserve(MB->getBufferSize()); 20588a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 20688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd(); 20788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner Ptr != End; ++Ptr) { 20888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // If C is not a horizontal whitespace, skip it. 20988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (*Ptr != ' ' && *Ptr != '\t') { 21088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner NewFile.push_back(*Ptr); 21188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner continue; 21288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner } 21388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 21488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Otherwise, add one space and advance over neighboring space. 21588a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner NewFile.push_back(' '); 21688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner while (Ptr+1 != End && 21788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner (Ptr[1] == ' ' || Ptr[1] == '\t')) 21888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner ++Ptr; 21988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner } 22088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 22188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Free the old buffer and return a new one. 22288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner MemoryBuffer *MB2 = 2236f69aa356136ada3d414d04cfab4341e87b63165Daniel Dunbar MemoryBuffer::getMemBufferCopy(NewFile.data(), 2246f69aa356136ada3d414d04cfab4341e87b63165Daniel Dunbar NewFile.data() + NewFile.size(), 22588a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner MB->getBufferIdentifier()); 22688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 22788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner delete MB; 22888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner return MB2; 22988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner} 23088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 23181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 2325dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattnerstatic void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr, 2335dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner const char *CurPtr, const char *BufferEnd) { 2345dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Otherwise, we have an error, emit an error message. 2355dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(CheckStr.Loc, "expected string not found in input", 2365dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 2375dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2385dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Print the "scanning from here" line. If the current position is at the 2395dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // end of a line, advance to the start of the next line. 2405dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner const char *Scan = CurPtr; 2415dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner while (Scan != BufferEnd && 2425dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner (*Scan == ' ' || *Scan == '\t')) 2435dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner ++Scan; 2445dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (*Scan == '\n' || *Scan == '\r') 2455dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CurPtr = Scan+1; 2465dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2475dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2485dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(CurPtr), "scanning from here", 2495dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "note"); 2505dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 2515dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2525dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattnerstatic unsigned CountNumNewlinesBetween(const char *Start, const char *End) { 2535dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner unsigned NumNewLines = 0; 2545dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner for (; Start != End; ++Start) { 2555dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Scan for newline. 2565dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (Start[0] != '\n' && Start[0] != '\r') 2575dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner continue; 2585dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2595dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner ++NumNewLines; 2605dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2615dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Handle \n\r and \r\n as a single newline. 2625dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (Start+1 != End && 2635dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner (Start[0] == '\n' || Start[0] == '\r') && 2645dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner (Start[0] != Start[1])) 2655dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner ++Start; 2665dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 2675dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2685dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return NumNewLines; 2695dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 2705dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 27181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerint main(int argc, char **argv) { 27281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner sys::PrintStackTraceOnErrorSignal(); 27381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner PrettyStackTraceProgram X(argc, argv); 27481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::ParseCommandLineOptions(argc, argv); 27581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 27681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SourceMgr SM; 27781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 27881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Read the expected strings from the check file. 279207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> CheckStrings; 28081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (ReadCheckFile(SM, CheckStrings)) 28181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 2; 28281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 28388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Remove duplicate spaces in the check strings if requested. 28488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (!NoCanonicalizeWhiteSpace) 28588a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner CanonicalizeCheckStrings(CheckStrings); 28688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 28781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the file to check and add it to SourceMgr. 28881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner std::string ErrorStr; 28981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer *F = 29081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr); 29181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (F == 0) { 29281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner errs() << "Could not open input file '" << InputFilename << "': " 29381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner << ErrorStr << '\n'; 29481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 29581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 29688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 29788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Remove duplicate spaces in the input file if requested. 29888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (!NoCanonicalizeWhiteSpace) 29988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner F = CanonicalizeInputFile(F); 30088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 30181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 30281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 30381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Check that we have all of the expected strings, in order, in the input 30481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // file. 30581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner const char *CurPtr = F->getBufferStart(), *BufferEnd = F->getBufferEnd(); 30681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3075dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner const char *LastMatch = 0; 30881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) { 309207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner const CheckString &CheckStr = CheckStrings[StrNo]; 31081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 31181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Find StrNo in the file. 3127bee3271e883acf2d07b48f3796a7cdc158112dbChris Lattner const char *Ptr = FindFixedStringInBuffer(CheckStr.Str, CurPtr, *F); 31381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3145dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // If we didn't find a match, reject the input. 3155dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (Ptr == BufferEnd) { 3165dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner PrintCheckFailed(SM, CheckStr, CurPtr, BufferEnd); 3175dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 31881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 31981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3205dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // If this check is a "CHECK-NEXT", verify that the previous match was on 3215dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // the previous line (i.e. that there is one newline between them). 3225dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (CheckStr.IsCheckNext) { 3235dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Count the number of newlines between the previous match and this one. 3245dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner assert(LastMatch && "CHECK-NEXT can't be the first check in a file"); 3255dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 3265dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner unsigned NumNewLines = CountNumNewlinesBetween(LastMatch, Ptr); 3275dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (NumNewLines == 0) { 3285dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(Ptr), 3295dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+"-NEXT: is on the same line as previous match", 3305dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 3315dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch), 3325dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "previous match was here", "note"); 3335dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 3345dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 3355dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 3365dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (NumNewLines != 1) { 3375dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(Ptr), 3385dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+ 3395dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "-NEXT: is not on the line after the previous match", 3405dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 3415dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch), 3425dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "previous match was here", "note"); 3435dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 3445dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 3455dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 3465dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 3475dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Otherwise, everything is good. Remember this as the last match and move 3485dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // on to the next one. 3495dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner LastMatch = Ptr; 3505dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CurPtr = Ptr + CheckStr.Str.size(); 35181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 35281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 35381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 0; 35481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 355