X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FMemoryBuffer.cpp;h=4d26d38731a8078b65a3e763207a1fb0389125e3;hb=a795aca96aca81ddeb4cd9628138926dd9fa612c;hp=ffbb4beccfab891fd1f76982ee23ade58a87913a;hpb=82e791dc420c399b7382a4754019b80466c898b0;p=oota-llvm.git diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp index ffbb4beccfa..4d26d38731a 100644 --- a/lib/Support/MemoryBuffer.cpp +++ b/lib/Support/MemoryBuffer.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Chris Lattner and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -14,6 +14,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/System/MappedFile.h" #include "llvm/System/Process.h" +#include "llvm/System/Program.h" #include #include #include @@ -38,7 +39,7 @@ void MemoryBuffer::initCopyOf(const char *BufStart, const char *BufEnd) { BufferEnd = BufferStart+Size; memcpy(const_cast(BufferStart), BufStart, Size); *const_cast(BufferEnd) = 0; // Null terminate buffer. - MustDeleteBuffer = false; + MustDeleteBuffer = true; } /// init - Initialize this MemoryBuffer as a reference to externally allocated @@ -58,9 +59,13 @@ namespace { class MemoryBufferMem : public MemoryBuffer { std::string FileID; public: - MemoryBufferMem(const char *Start, const char *End, const char *FID) + MemoryBufferMem(const char *Start, const char *End, const char *FID, + bool Copy = false) : FileID(FID) { - init(Start, End); + if (!Copy) + init(Start, End); + else + initCopyOf(Start, End); } virtual const char *getBufferIdentifier() const { @@ -77,6 +82,15 @@ MemoryBuffer *MemoryBuffer::getMemBuffer(const char *StartPtr, return new MemoryBufferMem(StartPtr, EndPtr, BufferName); } +/// getMemBufferCopy - Open the specified memory range as a MemoryBuffer, +/// copying the contents and taking ownership of it. This has no requirements +/// on EndPtr[0]. +MemoryBuffer *MemoryBuffer::getMemBufferCopy(const char *StartPtr, + const char *EndPtr, + const char *BufferName) { + return new MemoryBufferMem(StartPtr, EndPtr, BufferName, true); +} + /// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size /// that is completely initialized to zeros. Note that the caller should /// initialize the memory allocated by this method. The memory is owned by @@ -103,6 +117,24 @@ MemoryBuffer *MemoryBuffer::getNewMemBuffer(unsigned Size, } +/// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin +/// if the Filename is "-". If an error occurs, this returns null and fills +/// in *ErrStr with a reason. If stdin is empty, this API (unlike getSTDIN) +/// returns an empty buffer. +MemoryBuffer *MemoryBuffer::getFileOrSTDIN(const char *FilenameStart, + unsigned FnSize, + std::string *ErrStr, + int64_t FileSize) { + if (FnSize != 1 || FilenameStart[0] != '-') + return getFile(FilenameStart, FnSize, ErrStr, FileSize); + MemoryBuffer *M = getSTDIN(); + if (M) return M; + + // If stdin was empty, M is null. Cons up an empty memory buffer now. + const char *EmptyStr = ""; + return MemoryBuffer::getMemBuffer(EmptyStr, EmptyStr, ""); +} + //===----------------------------------------------------------------------===// // MemoryBufferMMapFile implementation. //===----------------------------------------------------------------------===// @@ -113,7 +145,7 @@ class MemoryBufferMMapFile : public MemoryBuffer { public: MemoryBufferMMapFile() {} - bool open(const sys::Path &Filename); + bool open(const sys::Path &Filename, std::string *ErrStr); virtual const char *getBufferIdentifier() const { return File.path().c_str(); @@ -123,13 +155,15 @@ public: }; } -bool MemoryBufferMMapFile::open(const sys::Path &Filename) { +bool MemoryBufferMMapFile::open(const sys::Path &Filename, + std::string *ErrStr) { // FIXME: This does an extra stat syscall to figure out the size, but we // already know the size! - bool Failure = File.open(Filename); + bool Failure = File.open(Filename, sys::MappedFile::READ_ACCESS, ErrStr); if (Failure) return true; - File.map(); + if (!File.map(ErrStr)) + return true; size_t Size = File.size(); @@ -161,11 +195,13 @@ MemoryBufferMMapFile::~MemoryBufferMMapFile() { //===----------------------------------------------------------------------===// MemoryBuffer *MemoryBuffer::getFile(const char *FilenameStart, unsigned FnSize, - int64_t FileSize) { + std::string *ErrStr, int64_t FileSize){ + // FIXME: it would be nice if PathWithStatus didn't copy the filename into a + // temporary string. :( sys::PathWithStatus P(FilenameStart, FnSize); #if 1 MemoryBufferMMapFile *M = new MemoryBufferMMapFile(); - if (!M->open(P)) + if (!M->open(P, ErrStr)) return M; delete M; return 0; @@ -186,7 +222,7 @@ MemoryBuffer *MemoryBuffer::getFile(const char *FilenameStart, unsigned FnSize, // If the file is larger than some threshold, use mmap, otherwise use 'read'. if (FileSize >= 4096*4) { MemoryBufferMMapFile *M = new MemoryBufferMMapFile(); - if (!M->open(P)) + if (!M->open(P, ErrStr)) return M; delete M; return 0; @@ -242,11 +278,15 @@ MemoryBuffer *MemoryBuffer::getSTDIN() { std::vector FileData; // Read in all of the data from stdin, we cannot mmap stdin. - while (size_t ReadBytes = fread(Buffer, 1, 4096*4, stdin)) + sys::Program::ChangeStdinToBinary(); + while (size_t ReadBytes = fread(Buffer, sizeof(char), 4096*4, stdin)) FileData.insert(FileData.end(), Buffer, Buffer+ReadBytes); - + + FileData.push_back(0); // &FileData[Size] is invalid. So is &*FileData.end(). size_t Size = FileData.size(); + if (Size <= 1) + return 0; MemoryBuffer *B = new STDINBufferFile(); - B->initCopyOf(&FileData[0], &FileData[Size]); + B->initCopyOf(&FileData[0], &FileData[Size-1]); return B; }