From: Reid Spencer Date: Thu, 24 Aug 2006 23:45:08 +0000 (+0000) Subject: For PR797: X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=0ff2d31766209ce1a69d4d2c5d35761ef57362aa For PR797: Remove exception handling from the bytecode archiver and adjust the llvm-ar tool to accommodate the new interfaces. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29866 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Bytecode/Archive.h b/include/llvm/Bytecode/Archive.h index 62a05bbcd80..72942423cc2 100644 --- a/include/llvm/Bytecode/Archive.h +++ b/include/llvm/Bytecode/Archive.h @@ -167,8 +167,9 @@ class ArchiveMember { /// of the file specified by \p File. The contents of \p this will be /// updated to reflect the new data from \p File. The \p File must exist and /// be readable on entry to this method. + /// @returns true if an error occurred, false otherwise /// @brief Replace contents of archive member with a new file. - void replaceWith(const sys::Path &aFile); + bool replaceWith(const sys::Path &aFile, std::string* ErrMsg); /// @} /// @name ilist methods - do not use @@ -439,8 +440,8 @@ class Archive { /// name will be truncated at 15 characters. If \p Compress is specified, /// all archive members will be compressed before being written. If /// \p PrintSymTab is true, the symbol table will be printed to std::cout. - /// @returns false if an error occurred, \p error set to error message - /// @returns true if the writing succeeded. + /// @returns true if an error occurred, \p error set to error message + /// @returns false if the writing succeeded. /// @brief Write (possibly modified) archive contents to disk bool writeToDisk( bool CreateSymbolTable=false, ///< Create Symbol table @@ -453,10 +454,13 @@ class Archive { /// to determine just enough information to create an ArchiveMember object /// which is then inserted into the Archive object's ilist at the location /// given by \p where. - /// @throws std::string if an error occurs reading the \p filename. - /// @returns nothing + /// @returns true if an error occured, false otherwise /// @brief Add a file to the archive. - void addFileBefore(const sys::Path& filename, iterator where); + bool addFileBefore( + const sys::Path& filename, ///< The file to be added + iterator where, ///< Insertion point + std::string* ErrMsg ///< Optional error message location + ); /// @} /// @name Implementation @@ -464,7 +468,7 @@ class Archive { protected: /// @brief Construct an Archive for \p filename and optionally map it /// into memory. - Archive(const sys::Path& filename, bool map = false ); + Archive(const sys::Path& filename); /// @param error Set to address of a std::string to get error messages /// @returns false on error @@ -500,8 +504,8 @@ class Archive { /// Writes one ArchiveMember to an ofstream. If an error occurs, returns /// false, otherwise true. If an error occurs and error is non-null then /// it will be set to an error message. - /// @returns true Writing member succeeded - /// @returns false Writing member failed, \p error set to error message + /// @returns false Writing member succeeded + /// @returns true Writing member failed, \p error set to error message bool writeMember( const ArchiveMember& member, ///< The member to be written std::ofstream& ARFile, ///< The file to write member onto @@ -515,6 +519,9 @@ class Archive { bool fillHeader(const ArchiveMember&mbr, ArchiveMemberHeader& hdr,int sz, bool TruncateNames) const; + /// @brief Maps archive into memory + bool mapToMemory(std::string* ErrMsg); + /// @brief Frees all the members and unmaps the archive file. void cleanUpMemory(); @@ -525,6 +532,7 @@ class Archive { typedef std::map > ModuleMap; + /// @} /// @name Data /// @{ diff --git a/lib/Archive/Archive.cpp b/lib/Archive/Archive.cpp index d5b56ca85e2..a661a4e992a 100644 --- a/lib/Archive/Archive.cpp +++ b/lib/Archive/Archive.cpp @@ -61,7 +61,7 @@ ArchiveMember::ArchiveMember(Archive* PAR) // This method allows an ArchiveMember to be replaced with the data for a // different file, presumably as an update to the member. It also makes sure // the flags are reset correctly. -void ArchiveMember::replaceWith(const sys::Path& newFile) { +bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) { assert(newFile.exists() && "Can't replace with a non-existent file"); data = 0; path = newFile; @@ -110,8 +110,8 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) { path.getMagicNumber(magic,4); signature = magic.c_str(); std::string err; - if (path.getFileStatus(info, &err)) - throw err; + if (path.getFileStatus(info, ErrMsg)) + return true; } // Determine what kind of file it is @@ -127,23 +127,27 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) { flags &= ~(BytecodeFlag|CompressedBytecodeFlag); break; } + return false; } // Archive constructor - this is the only constructor that gets used for the // Archive class. Everything else (default,copy) is deprecated. This just // initializes and maps the file into memory, if requested. -Archive::Archive(const sys::Path& filename, bool map ) +Archive::Archive(const sys::Path& filename) : archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(), symTabSize(0), firstFileOffset(0), modules(), foreignST(0) { - if (map) { - std::string ErrMsg; - mapfile = new sys::MappedFile(); - if (mapfile->open(filename, sys::MappedFile::READ_ACCESS, &ErrMsg)) - throw ErrMsg; - if (!(base = (char*) mapfile->map(&ErrMsg))) - throw ErrMsg; - } +} + +bool +Archive::mapToMemory(std::string* ErrMsg) +{ + mapfile = new sys::MappedFile(); + if (mapfile->open(archPath, sys::MappedFile::READ_ACCESS, ErrMsg)) + return true; + if (!(base = (char*) mapfile->map(ErrMsg))) + return true; + return false; } void Archive::cleanUpMemory() { diff --git a/lib/Archive/ArchiveReader.cpp b/lib/Archive/ArchiveReader.cpp index c8dd17c8f11..38aa07243c7 100644 --- a/lib/Archive/ArchiveReader.cpp +++ b/lib/Archive/ArchiveReader.cpp @@ -330,7 +330,9 @@ Archive::loadArchive(std::string* error) { Archive* Archive::OpenAndLoad(const sys::Path& file, std::string* ErrorMessage) { - std::auto_ptr result ( new Archive(file, true)); + std::auto_ptr result ( new Archive(file)); + if (result->mapToMemory(ErrorMessage)) + return 0; if (!result->loadArchive(ErrorMessage)) return 0; return result.release(); @@ -437,7 +439,9 @@ Archive::loadSymbolTable(std::string* ErrorMsg) { // Open the archive and load just the symbol tables Archive* Archive::OpenAndLoadSymbols(const sys::Path& file, std::string* ErrorMessage) { - std::auto_ptr result ( new Archive(file, true) ); + std::auto_ptr result ( new Archive(file) ); + if (result->mapToMemory(ErrorMessage)) + return 0; if (!result->loadSymbolTable(ErrorMessage)) return 0; return result.release(); diff --git a/lib/Archive/ArchiveWriter.cpp b/lib/Archive/ArchiveWriter.cpp index 86da17cc77f..3746dbff8a1 100644 --- a/lib/Archive/ArchiveWriter.cpp +++ b/lib/Archive/ArchiveWriter.cpp @@ -64,7 +64,7 @@ inline unsigned numVbrBytes(unsigned num) { // Create an empty archive. Archive* Archive::CreateEmpty(const sys::Path& FilePath ) { - Archive* result = new Archive(FilePath,false); + Archive* result = new Archive(FilePath); return result; } @@ -151,17 +151,17 @@ Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr, // Insert a file into the archive before some other member. This also takes care // of extracting the necessary flags and information from the file. -void -Archive::addFileBefore(const sys::Path& filePath, iterator where) { +bool +Archive::addFileBefore(const sys::Path& filePath, iterator where, + std::string* ErrMsg) { assert(filePath.exists() && "Can't add a non-existent file"); ArchiveMember* mbr = new ArchiveMember(this); mbr->data = 0; mbr->path = filePath; - std::string err; - if (mbr->path.getFileStatus(mbr->info, &err)) - throw err; + if (mbr->path.getFileStatus(mbr->info, ErrMsg)) + return true; unsigned flags = 0; bool hasSlash = filePath.toString().find('/') != std::string::npos; @@ -183,6 +183,7 @@ Archive::addFileBefore(const sys::Path& filePath, iterator where) { } mbr->flags = flags; members.insert(where,mbr); + return false; } // Write one member out to the file. @@ -193,7 +194,7 @@ Archive::writeMember( bool CreateSymbolTable, bool TruncateNames, bool ShouldCompress, - std::string* error + std::string* ErrMsg ) { unsigned filepos = ARFile.tellp(); @@ -205,12 +206,11 @@ Archive::writeMember( const char* data = (const char*)member.getData(); sys::MappedFile* mFile = 0; if (!data) { - std::string ErrMsg; mFile = new sys::MappedFile(); - if (mFile->open(member.getPath(), sys::MappedFile::READ_ACCESS, &ErrMsg)) - throw ErrMsg; - if (!(data = (const char*) mFile->map(&ErrMsg))) - throw ErrMsg; + if (mFile->open(member.getPath(), sys::MappedFile::READ_ACCESS, ErrMsg)) + return true; + if (!(data = (const char*) mFile->map(ErrMsg))) + return true; fSize = mFile->size(); } @@ -246,8 +246,9 @@ Archive::writeMember( mFile->close(); delete mFile; } - if (error) - *error = "Can't parse bytecode member: " + member.getPath().toString(); + if (ErrMsg) + *ErrMsg = "Can't parse bytecode member: " + member.getPath().toString(); + return true; } } @@ -274,9 +275,9 @@ Archive::writeMember( data +=4; fSize -= 4; } - fSize = Compressor::compressToNewBuffer(data,fSize,output,error); + fSize = Compressor::compressToNewBuffer(data,fSize,output,ErrMsg); if (fSize == 0) - return false; + return true; data = output; if (member.isBytecode()) hdrSize = -fSize-4; @@ -320,7 +321,7 @@ Archive::writeMember( mFile->close(); delete mFile; } - return true; + return false; } // Write out the LLVM symbol table as an archive member to the file. @@ -380,7 +381,7 @@ Archive::writeSymbolTable(std::ofstream& ARFile) { // compressing each archive member. bool Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, - std::string* error) + std::string* ErrMsg) { // Make sure they haven't opened up the file, not loaded it, // but are now trying to write it which would wipe out the file. @@ -389,8 +390,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // Create a temporary file to store the archive in sys::Path TmpArchive = archPath; - if (TmpArchive.createTemporaryFileOnDisk(error)) - return false; + if (TmpArchive.createTemporaryFileOnDisk(ErrMsg)) + return true; // Make sure the temporary gets removed if we crash sys::RemoveFileOnSignal(TmpArchive); @@ -404,9 +405,9 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, if (!ArchiveFile.is_open() || ArchiveFile.bad()) { if (TmpArchive.exists()) TmpArchive.eraseFromDisk(); - if (error) - *error = "Error opening archive file: " + archPath.toString(); - return false; + if (ErrMsg) + *ErrMsg = "Error opening archive file: " + archPath.toString(); + return true; } // If we're creating a symbol table, reset it now @@ -421,12 +422,12 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // Loop over all member files, and write them out. Note that this also // builds the symbol table, symTab. for (MembersList::iterator I = begin(), E = end(); I != E; ++I) { - if (!writeMember(*I, ArchiveFile, CreateSymbolTable, - TruncateNames, Compress, error)) { + if (writeMember(*I, ArchiveFile, CreateSymbolTable, + TruncateNames, Compress, ErrMsg)) { if (TmpArchive.exists()) TmpArchive.eraseFromDisk(); ArchiveFile.close(); - return false; + return true; } } @@ -443,27 +444,26 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // Map in the archive we just wrote. sys::MappedFile arch; - std::string ErrMsg; - if (arch.open(TmpArchive, sys::MappedFile::READ_ACCESS, &ErrMsg)) - throw ErrMsg; + if (arch.open(TmpArchive, sys::MappedFile::READ_ACCESS, ErrMsg)) + return true; const char* base; - if (!(base = (const char*) arch.map(&ErrMsg))) - throw ErrMsg; + if (!(base = (const char*) arch.map(ErrMsg))) + return true; // Open another temporary file in order to avoid invalidating the // mmapped data sys::Path FinalFilePath = archPath; - if (FinalFilePath.createTemporaryFileOnDisk(error)) - return false; + if (FinalFilePath.createTemporaryFileOnDisk(ErrMsg)) + return true; sys::RemoveFileOnSignal(FinalFilePath); std::ofstream FinalFile(FinalFilePath.c_str(), io_mode); if (!FinalFile.is_open() || FinalFile.bad()) { if (TmpArchive.exists()) TmpArchive.eraseFromDisk(); - if (error) - *error = "Error opening archive file: " + FinalFilePath.toString(); - return false; + if (ErrMsg) + *ErrMsg = "Error opening archive file: " + FinalFilePath.toString(); + return true; } // Write the file magic number @@ -475,11 +475,11 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // compatibility with other ar(1) implementations as well as allowing the // archive to store both native .o and LLVM .bc files, both indexed. if (foreignST) { - if (!writeMember(*foreignST, FinalFile, false, false, false, error)) { + if (writeMember(*foreignST, FinalFile, false, false, false, ErrMsg)) { FinalFile.close(); if (TmpArchive.exists()) TmpArchive.eraseFromDisk(); - return false; + return true; } } @@ -496,8 +496,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, arch.close(); // Move the final file over top of TmpArchive - if (FinalFilePath.renamePathOnDisk(TmpArchive, error)) - return false; + if (FinalFilePath.renamePathOnDisk(TmpArchive, ErrMsg)) + return true; } // Before we replace the actual archive, we need to forget all the @@ -505,8 +505,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // this because we cannot replace an open file on Windows. cleanUpMemory(); - if (TmpArchive.renamePathOnDisk(archPath, error)) - return false; + if (TmpArchive.renamePathOnDisk(archPath, ErrMsg)) + return true; - return true; + return false; } diff --git a/lib/Bytecode/Archive/Archive.cpp b/lib/Bytecode/Archive/Archive.cpp index d5b56ca85e2..a661a4e992a 100644 --- a/lib/Bytecode/Archive/Archive.cpp +++ b/lib/Bytecode/Archive/Archive.cpp @@ -61,7 +61,7 @@ ArchiveMember::ArchiveMember(Archive* PAR) // This method allows an ArchiveMember to be replaced with the data for a // different file, presumably as an update to the member. It also makes sure // the flags are reset correctly. -void ArchiveMember::replaceWith(const sys::Path& newFile) { +bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) { assert(newFile.exists() && "Can't replace with a non-existent file"); data = 0; path = newFile; @@ -110,8 +110,8 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) { path.getMagicNumber(magic,4); signature = magic.c_str(); std::string err; - if (path.getFileStatus(info, &err)) - throw err; + if (path.getFileStatus(info, ErrMsg)) + return true; } // Determine what kind of file it is @@ -127,23 +127,27 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) { flags &= ~(BytecodeFlag|CompressedBytecodeFlag); break; } + return false; } // Archive constructor - this is the only constructor that gets used for the // Archive class. Everything else (default,copy) is deprecated. This just // initializes and maps the file into memory, if requested. -Archive::Archive(const sys::Path& filename, bool map ) +Archive::Archive(const sys::Path& filename) : archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(), symTabSize(0), firstFileOffset(0), modules(), foreignST(0) { - if (map) { - std::string ErrMsg; - mapfile = new sys::MappedFile(); - if (mapfile->open(filename, sys::MappedFile::READ_ACCESS, &ErrMsg)) - throw ErrMsg; - if (!(base = (char*) mapfile->map(&ErrMsg))) - throw ErrMsg; - } +} + +bool +Archive::mapToMemory(std::string* ErrMsg) +{ + mapfile = new sys::MappedFile(); + if (mapfile->open(archPath, sys::MappedFile::READ_ACCESS, ErrMsg)) + return true; + if (!(base = (char*) mapfile->map(ErrMsg))) + return true; + return false; } void Archive::cleanUpMemory() { diff --git a/lib/Bytecode/Archive/ArchiveReader.cpp b/lib/Bytecode/Archive/ArchiveReader.cpp index c8dd17c8f11..38aa07243c7 100644 --- a/lib/Bytecode/Archive/ArchiveReader.cpp +++ b/lib/Bytecode/Archive/ArchiveReader.cpp @@ -330,7 +330,9 @@ Archive::loadArchive(std::string* error) { Archive* Archive::OpenAndLoad(const sys::Path& file, std::string* ErrorMessage) { - std::auto_ptr result ( new Archive(file, true)); + std::auto_ptr result ( new Archive(file)); + if (result->mapToMemory(ErrorMessage)) + return 0; if (!result->loadArchive(ErrorMessage)) return 0; return result.release(); @@ -437,7 +439,9 @@ Archive::loadSymbolTable(std::string* ErrorMsg) { // Open the archive and load just the symbol tables Archive* Archive::OpenAndLoadSymbols(const sys::Path& file, std::string* ErrorMessage) { - std::auto_ptr result ( new Archive(file, true) ); + std::auto_ptr result ( new Archive(file) ); + if (result->mapToMemory(ErrorMessage)) + return 0; if (!result->loadSymbolTable(ErrorMessage)) return 0; return result.release(); diff --git a/lib/Bytecode/Archive/ArchiveWriter.cpp b/lib/Bytecode/Archive/ArchiveWriter.cpp index 86da17cc77f..3746dbff8a1 100644 --- a/lib/Bytecode/Archive/ArchiveWriter.cpp +++ b/lib/Bytecode/Archive/ArchiveWriter.cpp @@ -64,7 +64,7 @@ inline unsigned numVbrBytes(unsigned num) { // Create an empty archive. Archive* Archive::CreateEmpty(const sys::Path& FilePath ) { - Archive* result = new Archive(FilePath,false); + Archive* result = new Archive(FilePath); return result; } @@ -151,17 +151,17 @@ Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr, // Insert a file into the archive before some other member. This also takes care // of extracting the necessary flags and information from the file. -void -Archive::addFileBefore(const sys::Path& filePath, iterator where) { +bool +Archive::addFileBefore(const sys::Path& filePath, iterator where, + std::string* ErrMsg) { assert(filePath.exists() && "Can't add a non-existent file"); ArchiveMember* mbr = new ArchiveMember(this); mbr->data = 0; mbr->path = filePath; - std::string err; - if (mbr->path.getFileStatus(mbr->info, &err)) - throw err; + if (mbr->path.getFileStatus(mbr->info, ErrMsg)) + return true; unsigned flags = 0; bool hasSlash = filePath.toString().find('/') != std::string::npos; @@ -183,6 +183,7 @@ Archive::addFileBefore(const sys::Path& filePath, iterator where) { } mbr->flags = flags; members.insert(where,mbr); + return false; } // Write one member out to the file. @@ -193,7 +194,7 @@ Archive::writeMember( bool CreateSymbolTable, bool TruncateNames, bool ShouldCompress, - std::string* error + std::string* ErrMsg ) { unsigned filepos = ARFile.tellp(); @@ -205,12 +206,11 @@ Archive::writeMember( const char* data = (const char*)member.getData(); sys::MappedFile* mFile = 0; if (!data) { - std::string ErrMsg; mFile = new sys::MappedFile(); - if (mFile->open(member.getPath(), sys::MappedFile::READ_ACCESS, &ErrMsg)) - throw ErrMsg; - if (!(data = (const char*) mFile->map(&ErrMsg))) - throw ErrMsg; + if (mFile->open(member.getPath(), sys::MappedFile::READ_ACCESS, ErrMsg)) + return true; + if (!(data = (const char*) mFile->map(ErrMsg))) + return true; fSize = mFile->size(); } @@ -246,8 +246,9 @@ Archive::writeMember( mFile->close(); delete mFile; } - if (error) - *error = "Can't parse bytecode member: " + member.getPath().toString(); + if (ErrMsg) + *ErrMsg = "Can't parse bytecode member: " + member.getPath().toString(); + return true; } } @@ -274,9 +275,9 @@ Archive::writeMember( data +=4; fSize -= 4; } - fSize = Compressor::compressToNewBuffer(data,fSize,output,error); + fSize = Compressor::compressToNewBuffer(data,fSize,output,ErrMsg); if (fSize == 0) - return false; + return true; data = output; if (member.isBytecode()) hdrSize = -fSize-4; @@ -320,7 +321,7 @@ Archive::writeMember( mFile->close(); delete mFile; } - return true; + return false; } // Write out the LLVM symbol table as an archive member to the file. @@ -380,7 +381,7 @@ Archive::writeSymbolTable(std::ofstream& ARFile) { // compressing each archive member. bool Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, - std::string* error) + std::string* ErrMsg) { // Make sure they haven't opened up the file, not loaded it, // but are now trying to write it which would wipe out the file. @@ -389,8 +390,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // Create a temporary file to store the archive in sys::Path TmpArchive = archPath; - if (TmpArchive.createTemporaryFileOnDisk(error)) - return false; + if (TmpArchive.createTemporaryFileOnDisk(ErrMsg)) + return true; // Make sure the temporary gets removed if we crash sys::RemoveFileOnSignal(TmpArchive); @@ -404,9 +405,9 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, if (!ArchiveFile.is_open() || ArchiveFile.bad()) { if (TmpArchive.exists()) TmpArchive.eraseFromDisk(); - if (error) - *error = "Error opening archive file: " + archPath.toString(); - return false; + if (ErrMsg) + *ErrMsg = "Error opening archive file: " + archPath.toString(); + return true; } // If we're creating a symbol table, reset it now @@ -421,12 +422,12 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // Loop over all member files, and write them out. Note that this also // builds the symbol table, symTab. for (MembersList::iterator I = begin(), E = end(); I != E; ++I) { - if (!writeMember(*I, ArchiveFile, CreateSymbolTable, - TruncateNames, Compress, error)) { + if (writeMember(*I, ArchiveFile, CreateSymbolTable, + TruncateNames, Compress, ErrMsg)) { if (TmpArchive.exists()) TmpArchive.eraseFromDisk(); ArchiveFile.close(); - return false; + return true; } } @@ -443,27 +444,26 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // Map in the archive we just wrote. sys::MappedFile arch; - std::string ErrMsg; - if (arch.open(TmpArchive, sys::MappedFile::READ_ACCESS, &ErrMsg)) - throw ErrMsg; + if (arch.open(TmpArchive, sys::MappedFile::READ_ACCESS, ErrMsg)) + return true; const char* base; - if (!(base = (const char*) arch.map(&ErrMsg))) - throw ErrMsg; + if (!(base = (const char*) arch.map(ErrMsg))) + return true; // Open another temporary file in order to avoid invalidating the // mmapped data sys::Path FinalFilePath = archPath; - if (FinalFilePath.createTemporaryFileOnDisk(error)) - return false; + if (FinalFilePath.createTemporaryFileOnDisk(ErrMsg)) + return true; sys::RemoveFileOnSignal(FinalFilePath); std::ofstream FinalFile(FinalFilePath.c_str(), io_mode); if (!FinalFile.is_open() || FinalFile.bad()) { if (TmpArchive.exists()) TmpArchive.eraseFromDisk(); - if (error) - *error = "Error opening archive file: " + FinalFilePath.toString(); - return false; + if (ErrMsg) + *ErrMsg = "Error opening archive file: " + FinalFilePath.toString(); + return true; } // Write the file magic number @@ -475,11 +475,11 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // compatibility with other ar(1) implementations as well as allowing the // archive to store both native .o and LLVM .bc files, both indexed. if (foreignST) { - if (!writeMember(*foreignST, FinalFile, false, false, false, error)) { + if (writeMember(*foreignST, FinalFile, false, false, false, ErrMsg)) { FinalFile.close(); if (TmpArchive.exists()) TmpArchive.eraseFromDisk(); - return false; + return true; } } @@ -496,8 +496,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, arch.close(); // Move the final file over top of TmpArchive - if (FinalFilePath.renamePathOnDisk(TmpArchive, error)) - return false; + if (FinalFilePath.renamePathOnDisk(TmpArchive, ErrMsg)) + return true; } // Before we replace the actual archive, we need to forget all the @@ -505,8 +505,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // this because we cannot replace an open file on Windows. cleanUpMemory(); - if (TmpArchive.renamePathOnDisk(archPath, error)) - return false; + if (TmpArchive.renamePathOnDisk(archPath, ErrMsg)) + return true; - return true; + return false; } diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index f266e1f3a57..55a60a331f4 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -586,7 +586,8 @@ doQuickAppend(std::string* ErrMsg) { // Append them quickly. for (std::set::iterator PI = Paths.begin(), PE = Paths.end(); PI != PE; ++PI) { - TheArchive->addFileBefore(*PI,TheArchive->end()); + if (TheArchive->addFileBefore(*PI,TheArchive->end(),ErrMsg)) + return true; } // We're done editting, reconstruct the archive. @@ -647,15 +648,17 @@ doReplaceOrInsert(std::string* ErrMsg) { sys::FileStatus si; std::string Err; if (found->getFileStatus(si, &Err)) - throw Err; + return true; if (si.isDir) { if (OnlyUpdate) { // Replace the item only if it is newer. if (si.modTime > I->getModTime()) - I->replaceWith(*found); + if (I->replaceWith(*found, ErrMsg)) + return true; } else { // Replace the item regardless of time stamp - I->replaceWith(*found); + if (I->replaceWith(*found, ErrMsg)) + return true; } } else { // We purposefully ignore directories. @@ -679,7 +682,8 @@ doReplaceOrInsert(std::string* ErrMsg) { if (!remaining.empty()) { for (std::set::iterator PI = remaining.begin(), PE = remaining.end(); PI != PE; ++PI) { - TheArchive->addFileBefore(*PI,insert_spot); + if (TheArchive->addFileBefore(*PI,insert_spot, ErrMsg)) + return true; } }