summaryrefslogtreecommitdiff
path: root/lib/Support
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-04-01 03:39:49 +0000
committerChris Lattner <sabre@nondot.org>2008-04-01 03:39:49 +0000
commita7750c1142baa5ad812d5209526a0b6568201e0e (patch)
tree4539a01cb14cce0f03be2ac97d2c75db3473cd3b /lib/Support
parentcc56e64a59db0f8aef62f0df29688cb22a1ea945 (diff)
downloadllvm-a7750c1142baa5ad812d5209526a0b6568201e0e.tar.gz
llvm-a7750c1142baa5ad812d5209526a0b6568201e0e.tar.bz2
llvm-a7750c1142baa5ad812d5209526a0b6568201e0e.tar.xz
Change DiffFilesWithTolerance to be written in terms of MemoryBuffer,
not an mmapped file. This more closely matches its requirements and provides an implicitly null terminated buffer, something this routine had to emulate itself before. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49024 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/FileUtilities.cpp129
1 files changed, 56 insertions, 73 deletions
diff --git a/lib/Support/FileUtilities.cpp b/lib/Support/FileUtilities.cpp
index 8cca9d96d9..a765643b26 100644
--- a/lib/Support/FileUtilities.cpp
+++ b/lib/Support/FileUtilities.cpp
@@ -14,7 +14,9 @@
#include "llvm/Support/FileUtilities.h"
#include "llvm/System/Path.h"
-#include "llvm/System/MappedFile.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include <cstdlib>
#include <cstring>
@@ -44,7 +46,7 @@ static bool isNumberChar(char C) {
}
}
-static char *BackupNumber(char *Pos, char *FirstChar) {
+static const char *BackupNumber(const char *Pos, const char *FirstChar) {
// If we didn't stop in the middle of a number, don't backup.
if (!isNumberChar(*Pos)) return Pos;
@@ -57,11 +59,21 @@ static char *BackupNumber(char *Pos, char *FirstChar) {
return Pos;
}
+/// EndOfNumber - Return the first character that is not part of the specified
+/// number. This assumes that the buffer is null terminated, so it won't fall
+/// off the end.
+static const char *EndOfNumber(const char *Pos) {
+ while (isNumberChar(*Pos))
+ ++Pos;
+ return Pos;
+}
+
/// CompareNumbers - compare two numbers, returning true if they are different.
-static bool CompareNumbers(char *&F1P, char *&F2P, char *F1End, char *F2End,
+static bool CompareNumbers(const char *&F1P, const char *&F2P,
+ const char *F1End, const char *F2End,
double AbsTolerance, double RelTolerance,
std::string *ErrorMsg) {
- char *F1NumEnd, *F2NumEnd;
+ const char *F1NumEnd, *F2NumEnd;
double V1 = 0.0, V2 = 0.0;
// If one of the positions is at a space and the other isn't, chomp up 'til
@@ -71,30 +83,35 @@ static bool CompareNumbers(char *&F1P, char *&F2P, char *F1End, char *F2End,
while (isspace(*F2P) && F2P != F2End)
++F2P;
- // If we stop on numbers, compare their difference. Note that some ugliness
- // is built into this to permit support for numbers that use "D" or "d" as
- // their exponential marker, e.g. "1.234D45". This occurs in 200.sixtrack in
- // spec2k.
- if (isNumberChar(*F1P) && isNumberChar(*F2P)) {
- bool isDNotation;
- do {
- isDNotation = false;
- V1 = strtod(F1P, &F1NumEnd);
- V2 = strtod(F2P, &F2NumEnd);
-
- if (*F1NumEnd == 'D' || *F1NumEnd == 'd') {
- *F1NumEnd = 'e'; // Strange exponential notation!
- isDNotation = true;
- }
- if (*F2NumEnd == 'D' || *F2NumEnd == 'd') {
- *F2NumEnd = 'e'; // Strange exponential notation!
- isDNotation = true;
- }
- } while (isDNotation);
- } else {
- // Otherwise, the diff failed.
+ // If we stop on numbers, compare their difference.
+ if (!isNumberChar(*F1P) || !isNumberChar(*F2P)) {
+ // The diff failed.
F1NumEnd = F1P;
F2NumEnd = F2P;
+ } else {
+ // Note that some ugliness is built into this to permit support for numbers
+ // that use "D" or "d" as their exponential marker, e.g. "1.234D45". This
+ // occurs in 200.sixtrack in spec2k.
+ V1 = strtod(F1P, const_cast<char**>(&F1NumEnd));
+ V2 = strtod(F2P, const_cast<char**>(&F2NumEnd));
+
+ if (*F1NumEnd == 'D' || *F1NumEnd == 'd') {
+ // Copy string into tmp buffer to replace the 'D' with an 'e'.
+ SmallString<200> StrTmp(F1P, EndOfNumber(F1NumEnd)+1);
+ StrTmp[F1NumEnd-F1P] = 'e'; // Strange exponential notation!
+
+ V1 = strtod(&StrTmp[0], const_cast<char**>(&F1NumEnd));
+ F1NumEnd = F1P + (F1NumEnd-&StrTmp[0]);
+ }
+
+ if (*F2NumEnd == 'D' || *F2NumEnd == 'd') {
+ // Copy string into tmp buffer to replace the 'D' with an 'e'.
+ SmallString<200> StrTmp(F2P, EndOfNumber(F2NumEnd)+1);
+ StrTmp[F2NumEnd-F2P] = 'e'; // Strange exponential notation!
+
+ V2 = strtod(&StrTmp[0], const_cast<char**>(&F2NumEnd));
+ F2NumEnd = F2P + (F2NumEnd-&StrTmp[0]);
+ }
}
if (F1NumEnd == F1P || F2NumEnd == F2P) {
@@ -135,25 +152,6 @@ static bool CompareNumbers(char *&F1P, char *&F2P, char *F1End, char *F2End,
return false;
}
-// PadFileIfNeeded - If the files are not identical, we will have to be doing
-// numeric comparisons in here. There are bad cases involved where we (i.e.,
-// strtod) might run off the beginning or end of the file if it starts or ends
-// with a number. Because of this, if needed, we pad the file so that it starts
-// and ends with a null character.
-static void PadFileIfNeeded(char *&FileStart, char *&FileEnd, char *&FP) {
- if (FileStart-FileEnd < 2 ||
- isNumberChar(FileStart[0]) || isNumberChar(FileEnd[-1])) {
- unsigned FileLen = FileEnd-FileStart;
- char *NewFile = new char[FileLen+2];
- NewFile[0] = 0; // Add null padding
- NewFile[FileLen+1] = 0; // Add null padding
- memcpy(NewFile+1, FileStart, FileLen);
- FP = NewFile+(FP-FileStart)+1;
- FileStart = NewFile+1;
- FileEnd = FileStart+FileLen;
- }
-}
-
/// DiffFilesWithTolerance - Compare the two files specified, returning 0 if the
/// files match, 1 if they are different, and 2 if there is a file error. This
/// function differs from DiffFiles in that you can specify an absolete and
@@ -191,27 +189,23 @@ int llvm::DiffFilesWithTolerance(const sys::PathWithStatus &FileA,
// Now its safe to mmap the files into memory becasue both files
// have a non-zero size.
- sys::MappedFile F1;
- if (F1.open(FileA, Error))
- return 2;
- sys::MappedFile F2;
- if (F2.open(FileB, Error))
- return 2;
- if (!F1.map(Error))
+ OwningPtr<MemoryBuffer> F1(MemoryBuffer::getFile(FileA.c_str(), FileA.size(),
+ Error));
+ OwningPtr<MemoryBuffer> F2(MemoryBuffer::getFile(FileB.c_str(), FileB.size(),
+ Error));
+ if (F1 == 0 || F2 == 0)
return 2;
- if (!F2.map(Error))
- return 2;
-
+
// Okay, now that we opened the files, scan them for the first difference.
- char *File1Start = F1.charBase();
- char *File2Start = F2.charBase();
- char *File1End = File1Start+A_size;
- char *File2End = File2Start+B_size;
- char *F1P = File1Start;
- char *F2P = File2Start;
+ const char *File1Start = F1->getBufferStart();
+ const char *File2Start = F2->getBufferStart();
+ const char *File1End = F1->getBufferEnd();
+ const char *File2End = F2->getBufferEnd();
+ const char *F1P = File1Start;
+ const char *F2P = File2Start;
if (A_size == B_size) {
- // Are the buffers identical?
+ // Are the buffers identical? Common case: Handle this efficiently.
if (std::memcmp(File1Start, File2Start, A_size) == 0)
return 0;
@@ -222,13 +216,6 @@ int llvm::DiffFilesWithTolerance(const sys::PathWithStatus &FileA,
}
}
- char *OrigFile1Start = File1Start;
- char *OrigFile2Start = File2Start;
-
- // If the files need padding, do so now.
- PadFileIfNeeded(File1Start, File1End, F1P);
- PadFileIfNeeded(File2Start, File2End, F2P);
-
bool CompareFailed = false;
while (1) {
// Scan for the end of file or next difference.
@@ -272,9 +259,5 @@ int llvm::DiffFilesWithTolerance(const sys::PathWithStatus &FileA,
CompareFailed = true;
}
- if (OrigFile1Start != File1Start)
- delete[] (File1Start-1); // Back up past null byte
- if (OrigFile2Start != File2Start)
- delete[] (File2Start-1); // Back up past null byte
return CompareFailed;
}