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