FileCheck.cpp revision 207e1bcf897d1c732f717b9773029651ecc59ab2
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 50207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner CheckString(const std::string &S, SMLoc L) : Str(S), Loc(L) {} 51207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner}; 52207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 5381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 5481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// FindStringInBuffer - This is basically just a strstr wrapper that differs in 5581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// two ways: first it handles 'nul' characters in memory buffers, second, it 5681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// returns the end of the memory buffer on match failure. 5781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic const char *FindStringInBuffer(const char *Str, const char *CurPtr, 5881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner const MemoryBuffer &MB) { 5981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Check to see if we have a match. If so, just return it. 6081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (const char *Res = strstr(CurPtr, Str)) 6181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return Res; 6281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 6381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // If not, check to make sure we didn't just find an embedded nul in the 6481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // memory buffer. 6581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner const char *Ptr = CurPtr + strlen(CurPtr); 6681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 6781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // If we really reached the end of the file, return it. 6881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (Ptr == MB.getBufferEnd()) 6981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return Ptr; 7081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 7181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Otherwise, just skip this section of the file, including the nul. 7281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return FindStringInBuffer(Str, Ptr+1, MB); 7381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 7481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 7581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// ReadCheckFile - Read the check file, which specifies the sequence of 7681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// expected strings. The strings are added to the CheckStrings vector. 7781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic bool ReadCheckFile(SourceMgr &SM, 78207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> &CheckStrings) { 7981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the check file, and tell SourceMgr about it. 8081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner std::string ErrorStr; 8181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer *F = 8281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr); 8381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (F == 0) { 8481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner errs() << "Could not open check file '" << CheckFilename << "': " 8581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner << ErrorStr << '\n'; 8681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 8781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 8881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 8981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 9081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Find all instances of CheckPrefix followed by : in the file. The 9181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // MemoryBuffer is guaranteed to be nul terminated, but may have nul's 9281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // embedded into it. We don't support check strings with embedded nuls. 9381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner std::string Prefix = CheckPrefix + ":"; 9481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner const char *CurPtr = F->getBufferStart(), *BufferEnd = F->getBufferEnd(); 9581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 9681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (1) { 9781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // See if Prefix occurs in the memory buffer. 9881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner const char *Ptr = FindStringInBuffer(Prefix.c_str(), CurPtr, *F); 9981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 10081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // If we didn't find a match, we're done. 10181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (Ptr == BufferEnd) 10281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner break; 10381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 10481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, we found the prefix, yay. Remember the rest of the line, but 10581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // ignore leading and trailing whitespace. 10681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner Ptr += Prefix.size(); 10781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (*Ptr == ' ' || *Ptr == '\t') 10881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner ++Ptr; 10981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 11081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Scan ahead to the end of line. 11181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner CurPtr = Ptr; 11281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (CurPtr != BufferEnd && *CurPtr != '\n' && *CurPtr != '\r') 11381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner ++CurPtr; 11481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 11581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Ignore trailing whitespace. 11681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (CurPtr[-1] == ' ' || CurPtr[-1] == '\t') 11781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner --CurPtr; 11881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 11981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Check that there is something on the line. 12081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (Ptr >= CurPtr) { 12181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(CurPtr), 12281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner "found empty check string with prefix '"+Prefix+"'", 12381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner "error"); 12481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 12581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 12681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 12781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, add the string we captured to the output vector and move on. 128207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner CheckStrings.push_back(CheckString(std::string(Ptr, CurPtr), 129207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner SMLoc::getFromPointer(Ptr))); 13081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 13181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 13281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (CheckStrings.empty()) { 13381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner errs() << "error: no check strings found with prefix '" << Prefix << "'\n"; 13481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 13581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 13681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 13781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return false; 13881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 13981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 14088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner// CanonicalizeCheckStrings - Replace all sequences of horizontal whitespace in 14188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner// the check strings with a single space. 142207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattnerstatic void CanonicalizeCheckStrings(std::vector<CheckString> &CheckStrings) { 14388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner for (unsigned i = 0, e = CheckStrings.size(); i != e; ++i) { 144207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::string &Str = CheckStrings[i].Str; 14588a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 14688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner for (unsigned C = 0; C != Str.size(); ++C) { 14788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // If C is not a horizontal whitespace, skip it. 14888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (Str[C] != ' ' && Str[C] != '\t') 14988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner continue; 15088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 15188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Replace the character with space, then remove any other space 15288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // characters after it. 15388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner Str[C] = ' '; 15488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 15588a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner while (C+1 != Str.size() && 15688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner (Str[C+1] == ' ' || Str[C+1] == '\t')) 15788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner Str.erase(Str.begin()+C+1); 15888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner } 15988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner } 16088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner} 16188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 16288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified 16388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner/// memory buffer, free it, and return a new one. 16488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattnerstatic MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) { 1656f69aa356136ada3d414d04cfab4341e87b63165Daniel Dunbar SmallVector<char, 16> NewFile; 16688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner NewFile.reserve(MB->getBufferSize()); 16788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 16888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd(); 16988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner Ptr != End; ++Ptr) { 17088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // If C is not a horizontal whitespace, skip it. 17188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (*Ptr != ' ' && *Ptr != '\t') { 17288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner NewFile.push_back(*Ptr); 17388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner continue; 17488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner } 17588a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 17688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Otherwise, add one space and advance over neighboring space. 17788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner NewFile.push_back(' '); 17888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner while (Ptr+1 != End && 17988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner (Ptr[1] == ' ' || Ptr[1] == '\t')) 18088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner ++Ptr; 18188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner } 18288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 18388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Free the old buffer and return a new one. 18488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner MemoryBuffer *MB2 = 1856f69aa356136ada3d414d04cfab4341e87b63165Daniel Dunbar MemoryBuffer::getMemBufferCopy(NewFile.data(), 1866f69aa356136ada3d414d04cfab4341e87b63165Daniel Dunbar NewFile.data() + NewFile.size(), 18788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner MB->getBufferIdentifier()); 18888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 18988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner delete MB; 19088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner return MB2; 19188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner} 19288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 19381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 19481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerint main(int argc, char **argv) { 19581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner sys::PrintStackTraceOnErrorSignal(); 19681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner PrettyStackTraceProgram X(argc, argv); 19781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::ParseCommandLineOptions(argc, argv); 19881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 19981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SourceMgr SM; 20081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 20181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Read the expected strings from the check file. 202207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> CheckStrings; 20381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (ReadCheckFile(SM, CheckStrings)) 20481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 2; 20581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 20688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Remove duplicate spaces in the check strings if requested. 20788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (!NoCanonicalizeWhiteSpace) 20888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner CanonicalizeCheckStrings(CheckStrings); 20988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 21081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the file to check and add it to SourceMgr. 21181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner std::string ErrorStr; 21281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer *F = 21381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr); 21481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (F == 0) { 21581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner errs() << "Could not open input file '" << InputFilename << "': " 21681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner << ErrorStr << '\n'; 21781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 21881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 21988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 22088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Remove duplicate spaces in the input file if requested. 22188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (!NoCanonicalizeWhiteSpace) 22288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner F = CanonicalizeInputFile(F); 22388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 22481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 22581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 22681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Check that we have all of the expected strings, in order, in the input 22781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // file. 22881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner const char *CurPtr = F->getBufferStart(), *BufferEnd = F->getBufferEnd(); 22981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 23081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) { 231207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner const CheckString &CheckStr = CheckStrings[StrNo]; 23281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 23381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Find StrNo in the file. 234207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner const char *Ptr = FindStringInBuffer(CheckStr.Str.c_str(), CurPtr, *F); 23581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 23681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // If we found a match, we're done, move on. 23781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (Ptr != BufferEnd) { 238207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner CurPtr = Ptr + CheckStr.Str.size(); 23981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner continue; 24081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 24181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 24281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Otherwise, we have an error, emit an error message. 243207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner SM.PrintMessage(CheckStr.Loc, "expected string not found in input", 24481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner "error"); 245d7073db1af89c0340eb81740beb78875d3c4a2f8Chris Lattner 246e9e2733a04875bfab6596e362b37acd031f99010Daniel Dunbar // Print the "scanning from here" line. If the current position is at the 247e9e2733a04875bfab6596e362b37acd031f99010Daniel Dunbar // end of a line, advance to the start of the next line. 248d7073db1af89c0340eb81740beb78875d3c4a2f8Chris Lattner const char *Scan = CurPtr; 249d7073db1af89c0340eb81740beb78875d3c4a2f8Chris Lattner while (Scan != BufferEnd && 250d7073db1af89c0340eb81740beb78875d3c4a2f8Chris Lattner (*Scan == ' ' || *Scan == '\t')) 251d7073db1af89c0340eb81740beb78875d3c4a2f8Chris Lattner ++Scan; 252d7073db1af89c0340eb81740beb78875d3c4a2f8Chris Lattner if (*Scan == '\n' || *Scan == '\r') 253d7073db1af89c0340eb81740beb78875d3c4a2f8Chris Lattner CurPtr = Scan+1; 254d7073db1af89c0340eb81740beb78875d3c4a2f8Chris Lattner 255d7073db1af89c0340eb81740beb78875d3c4a2f8Chris Lattner 25681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(CurPtr), "scanning from here", 25781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner "note"); 258af9005ddda7809a4ca1900d83fb349d52ef50c48Chris Lattner return 1; 25981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 26081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 26181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 0; 26281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 263