mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 03:29:40 +00:00
rewrite FileCheck in terms of StringRef instead of manual pointer pairs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82407 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
386251341f
commit
96077036f0
@ -56,35 +56,6 @@ struct CheckString {
|
||||
};
|
||||
|
||||
|
||||
/// FindFixedStringInBuffer - This works like strstr, except for two things:
|
||||
/// 1) it handles 'nul' characters in memory buffers. 2) it returns the end of
|
||||
/// the memory buffer on match failure instead of null.
|
||||
static const char *FindFixedStringInBuffer(StringRef Str, const char *CurPtr,
|
||||
const MemoryBuffer &MB) {
|
||||
assert(!Str.empty() && "Can't find an empty string");
|
||||
const char *BufEnd = MB.getBufferEnd();
|
||||
|
||||
while (1) {
|
||||
// Scan for the first character in the match string.
|
||||
CurPtr = (char*)memchr(CurPtr, Str[0], BufEnd-CurPtr);
|
||||
|
||||
// If we didn't find the first character of the string, then we failed to
|
||||
// match.
|
||||
if (CurPtr == 0) return BufEnd;
|
||||
|
||||
// If the match string is one character, then we win.
|
||||
if (Str.size() == 1) return CurPtr;
|
||||
|
||||
// Otherwise, verify that the rest of the string matches.
|
||||
if (Str.size() <= unsigned(BufEnd-CurPtr) &&
|
||||
memcmp(CurPtr+1, Str.data()+1, Str.size()-1) == 0)
|
||||
return CurPtr;
|
||||
|
||||
// If not, advance past this character and try again.
|
||||
++CurPtr;
|
||||
}
|
||||
}
|
||||
|
||||
/// ReadCheckFile - Read the check file, which specifies the sequence of
|
||||
/// expected strings. The strings are added to the CheckStrings vector.
|
||||
static bool ReadCheckFile(SourceMgr &SM,
|
||||
@ -101,52 +72,51 @@ static bool ReadCheckFile(SourceMgr &SM,
|
||||
SM.AddNewSourceBuffer(F, SMLoc());
|
||||
|
||||
// Find all instances of CheckPrefix followed by : in the file.
|
||||
const char *CurPtr = F->getBufferStart(), *BufferEnd = F->getBufferEnd();
|
||||
StringRef Buffer = F->getBuffer();
|
||||
|
||||
while (1) {
|
||||
// See if Prefix occurs in the memory buffer.
|
||||
const char *Ptr = FindFixedStringInBuffer(CheckPrefix, CurPtr, *F);
|
||||
Buffer = Buffer.substr(Buffer.find(CheckPrefix));
|
||||
|
||||
// If we didn't find a match, we're done.
|
||||
if (Ptr == BufferEnd)
|
||||
if (Buffer.empty())
|
||||
break;
|
||||
|
||||
const char *CheckPrefixStart = Ptr;
|
||||
const char *CheckPrefixStart = Buffer.data();
|
||||
|
||||
// When we find a check prefix, keep track of whether we find CHECK: or
|
||||
// CHECK-NEXT:
|
||||
bool IsCheckNext;
|
||||
|
||||
// Verify that the : is present after the prefix.
|
||||
if (Ptr[CheckPrefix.size()] == ':') {
|
||||
Ptr += CheckPrefix.size()+1;
|
||||
if (Buffer[CheckPrefix.size()] == ':') {
|
||||
Buffer = Buffer.substr(CheckPrefix.size()+1);
|
||||
IsCheckNext = false;
|
||||
} else if (BufferEnd-Ptr > 6 &&
|
||||
memcmp(Ptr+CheckPrefix.size(), "-NEXT:", 6) == 0) {
|
||||
Ptr += CheckPrefix.size()+7;
|
||||
} else if (Buffer.size() > CheckPrefix.size()+6 &&
|
||||
memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
|
||||
Buffer = Buffer.substr(CheckPrefix.size()+7);
|
||||
IsCheckNext = true;
|
||||
} else {
|
||||
CurPtr = Ptr+1;
|
||||
Buffer = Buffer.substr(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Okay, we found the prefix, yay. Remember the rest of the line, but
|
||||
// ignore leading and trailing whitespace.
|
||||
while (*Ptr == ' ' || *Ptr == '\t')
|
||||
++Ptr;
|
||||
while (!Buffer.empty() && (Buffer[0] == ' ' || Buffer[0] == '\t'))
|
||||
Buffer = Buffer.substr(1);
|
||||
|
||||
// Scan ahead to the end of line.
|
||||
CurPtr = Ptr;
|
||||
while (CurPtr != BufferEnd && *CurPtr != '\n' && *CurPtr != '\r')
|
||||
++CurPtr;
|
||||
size_t EOL = Buffer.find_first_of("\n\r");
|
||||
if (EOL == StringRef::npos) EOL = Buffer.size();
|
||||
|
||||
// Ignore trailing whitespace.
|
||||
while (CurPtr[-1] == ' ' || CurPtr[-1] == '\t')
|
||||
--CurPtr;
|
||||
while (EOL && (Buffer[EOL-1] == ' ' || Buffer[EOL-1] == '\t'))
|
||||
--EOL;
|
||||
|
||||
// Check that there is something on the line.
|
||||
if (Ptr >= CurPtr) {
|
||||
SM.PrintMessage(SMLoc::getFromPointer(CurPtr),
|
||||
if (EOL == 0) {
|
||||
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
|
||||
"found empty check string with prefix '"+CheckPrefix+":'",
|
||||
"error");
|
||||
return true;
|
||||
@ -161,9 +131,12 @@ static bool ReadCheckFile(SourceMgr &SM,
|
||||
}
|
||||
|
||||
// Okay, add the string we captured to the output vector and move on.
|
||||
CheckStrings.push_back(CheckString(std::string(Ptr, CurPtr),
|
||||
SMLoc::getFromPointer(Ptr),
|
||||
CheckStrings.push_back(CheckString(std::string(Buffer.data(),
|
||||
Buffer.data()+EOL),
|
||||
SMLoc::getFromPointer(Buffer.data()),
|
||||
IsCheckNext));
|
||||
|
||||
Buffer = Buffer.substr(EOL);
|
||||
}
|
||||
|
||||
if (CheckStrings.empty()) {
|
||||
@ -230,22 +203,16 @@ static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
|
||||
|
||||
|
||||
static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
|
||||
const char *CurPtr, const char *BufferEnd) {
|
||||
StringRef Buffer) {
|
||||
// Otherwise, we have an error, emit an error message.
|
||||
SM.PrintMessage(CheckStr.Loc, "expected string not found in input",
|
||||
"error");
|
||||
|
||||
// Print the "scanning from here" line. If the current position is at the
|
||||
// end of a line, advance to the start of the next line.
|
||||
const char *Scan = CurPtr;
|
||||
while (Scan != BufferEnd &&
|
||||
(*Scan == ' ' || *Scan == '\t'))
|
||||
++Scan;
|
||||
if (*Scan == '\n' || *Scan == '\r')
|
||||
CurPtr = Scan+1;
|
||||
Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
|
||||
|
||||
|
||||
SM.PrintMessage(SMLoc::getFromPointer(CurPtr), "scanning from here",
|
||||
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here",
|
||||
"note");
|
||||
}
|
||||
|
||||
@ -302,18 +269,20 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Check that we have all of the expected strings, in order, in the input
|
||||
// file.
|
||||
const char *CurPtr = F->getBufferStart(), *BufferEnd = F->getBufferEnd();
|
||||
StringRef Buffer = F->getBuffer();
|
||||
|
||||
const char *LastMatch = 0;
|
||||
for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) {
|
||||
const CheckString &CheckStr = CheckStrings[StrNo];
|
||||
|
||||
StringRef SearchFrom = Buffer;
|
||||
|
||||
// Find StrNo in the file.
|
||||
const char *Ptr = FindFixedStringInBuffer(CheckStr.Str, CurPtr, *F);
|
||||
Buffer = Buffer.substr(Buffer.find(CheckStr.Str));
|
||||
|
||||
// If we didn't find a match, reject the input.
|
||||
if (Ptr == BufferEnd) {
|
||||
PrintCheckFailed(SM, CheckStr, CurPtr, BufferEnd);
|
||||
if (Buffer.empty()) {
|
||||
PrintCheckFailed(SM, CheckStr, SearchFrom);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -323,12 +292,12 @@ int main(int argc, char **argv) {
|
||||
// Count the number of newlines between the previous match and this one.
|
||||
assert(LastMatch && "CHECK-NEXT can't be the first check in a file");
|
||||
|
||||
unsigned NumNewLines = CountNumNewlinesBetween(LastMatch, Ptr);
|
||||
unsigned NumNewLines = CountNumNewlinesBetween(LastMatch, Buffer.data());
|
||||
if (NumNewLines == 0) {
|
||||
SM.PrintMessage(CheckStr.Loc,
|
||||
CheckPrefix+"-NEXT: is on the same line as previous match",
|
||||
"error");
|
||||
SM.PrintMessage(SMLoc::getFromPointer(Ptr),
|
||||
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
|
||||
"'next' match was here", "note");
|
||||
SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
|
||||
"previous match was here", "note");
|
||||
@ -340,7 +309,7 @@ int main(int argc, char **argv) {
|
||||
CheckPrefix+
|
||||
"-NEXT: is not on the line after the previous match",
|
||||
"error");
|
||||
SM.PrintMessage(SMLoc::getFromPointer(Ptr),
|
||||
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
|
||||
"'next' match was here", "note");
|
||||
SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
|
||||
"previous match was here", "note");
|
||||
@ -350,8 +319,8 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Otherwise, everything is good. Remember this as the last match and move
|
||||
// on to the next one.
|
||||
LastMatch = Ptr;
|
||||
CurPtr = Ptr + CheckStr.Str.size();
|
||||
LastMatch = Buffer.data();
|
||||
Buffer = Buffer.substr(CheckStr.Str.size());
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user