Revert "Don't include directory names in archives."

This reverts commit 184420.
Investigating the bot failures.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184421 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola
2013-06-20 13:23:48 +00:00
parent be984d6376
commit 9d39cb1d64
5 changed files with 36 additions and 13 deletions

View File

@@ -1,8 +1,2 @@
;RUN: not llvm-ar r %T/test.a . 2>&1 | FileCheck %s ;RUN: not llvm-ar r %T/test.a . 2>&1 | FileCheck %s
;CHECK: . Is a directory ;CHECK: . Is a directory
;RUN: rm -f %T/test.a
;RUN: llvm-ar r %T/test.a %s
;RUN: llvm-ar t %T/test.a | FileCheck -check-prefix=MEMBERS %s
;MEMBERS-NOT: /
;MEMBERS: directory.ll

View File

@@ -97,8 +97,15 @@ bool ArchiveMember::replaceWith(StringRef newFile, std::string* ErrMsg) {
else else
flags &= ~StringTableFlag; flags &= ~StringTableFlag;
// If it has a slash then it has a path
bool hasSlash = path.find('/') != std::string::npos;
if (hasSlash)
flags |= HasPathFlag;
else
flags &= ~HasPathFlag;
// If it has a slash or its over 15 chars then its a long filename format // If it has a slash or its over 15 chars then its a long filename format
if (path.length() > 15) if (hasSlash || path.length() > 15)
flags |= HasLongFilenameFlag; flags |= HasLongFilenameFlag;
else else
flags &= ~HasLongFilenameFlag; flags &= ~HasLongFilenameFlag;

View File

@@ -52,8 +52,9 @@ class ArchiveMember : public ilist_node<ArchiveMember> {
SVR4SymbolTableFlag = 1, ///< Member is a SVR4 symbol table SVR4SymbolTableFlag = 1, ///< Member is a SVR4 symbol table
BSD4SymbolTableFlag = 2, ///< Member is a BSD4 symbol table BSD4SymbolTableFlag = 2, ///< Member is a BSD4 symbol table
BitcodeFlag = 4, ///< Member is bitcode BitcodeFlag = 4, ///< Member is bitcode
HasLongFilenameFlag = 8, ///< Member uses the long filename syntax HasPathFlag = 8, ///< Member has a full or partial path
StringTableFlag = 16 ///< Member is an ar(1) format string table HasLongFilenameFlag = 16, ///< Member uses the long filename syntax
StringTableFlag = 32 ///< Member is an ar(1) format string table
}; };
/// @} /// @}
@@ -124,6 +125,10 @@ class ArchiveMember : public ilist_node<ArchiveMember> {
/// @brief Determine if this member is a bitcode file. /// @brief Determine if this member is a bitcode file.
bool isBitcode() const { return flags&BitcodeFlag; } bool isBitcode() const { return flags&BitcodeFlag; }
/// @returns true iff the file name contains a path (directory) component.
/// @brief Determine if the member has a path
bool hasPath() const { return flags&HasPathFlag; }
/// Long filenames are an artifact of the ar(1) file format which allows /// Long filenames are an artifact of the ar(1) file format which allows
/// up to sixteen characters in its header and doesn't allow a path /// up to sixteen characters in its header and doesn't allow a path
/// separator character (/). To avoid this, a "long format" member name is /// separator character (/). To avoid this, a "long format" member name is

View File

@@ -98,7 +98,13 @@ Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr,
sprintf(buffer,"%-12u", unsigned(secondsSinceEpoch)); sprintf(buffer,"%-12u", unsigned(secondsSinceEpoch));
memcpy(hdr.date,buffer,12); memcpy(hdr.date,buffer,12);
std::string mbrPath = sys::path::filename(mbr.getPath()); // Get rid of trailing blanks in the name
std::string mbrPath = mbr.getPath().str();
size_t mbrLen = mbrPath.length();
while (mbrLen > 0 && mbrPath[mbrLen-1] == ' ') {
mbrPath.erase(mbrLen-1,1);
mbrLen--;
}
// Set the name field in one of its various flavors. // Set the name field in one of its various flavors.
bool writeLongName = false; bool writeLongName = false;
@@ -159,8 +165,8 @@ bool Archive::addFileBefore(StringRef filePath, iterator where,
ArchiveMember* mbr = new ArchiveMember(this); ArchiveMember* mbr = new ArchiveMember(this);
mbr->data = 0; mbr->data = 0;
mbr->path = filePath; mbr->path = filePath.str();
sys::PathWithStatus PWS(filePath); sys::PathWithStatus PWS(mbr->path);
const sys::FileStatus *FSInfo = PWS.getFileStatus(false, ErrMsg); const sys::FileStatus *FSInfo = PWS.getFileStatus(false, ErrMsg);
if (!FSInfo) { if (!FSInfo) {
delete mbr; delete mbr;
@@ -173,7 +179,10 @@ bool Archive::addFileBefore(StringRef filePath, iterator where,
mbr->Size = FSInfo->getSize(); mbr->Size = FSInfo->getSize();
unsigned flags = 0; unsigned flags = 0;
if (sys::path::filename(filePath).size() > 15) bool hasSlash = filePath.str().find('/') != std::string::npos;
if (hasSlash)
flags |= ArchiveMember::HasPathFlag;
if (hasSlash || filePath.str().length() > 15)
flags |= ArchiveMember::HasLongFilenameFlag; flags |= ArchiveMember::HasLongFilenameFlag;
sys::fs::file_magic type; sys::fs::file_magic type;

View File

@@ -399,6 +399,14 @@ doExtract(std::string* ErrMsg) {
if (Paths.empty() || if (Paths.empty() ||
(std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) { (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) {
// Make sure the intervening directories are created
if (I->hasPath()) {
sys::Path dirs(I->getPath());
dirs.eraseComponent();
if (dirs.createDirectoryOnDisk(/*create_parents=*/true, ErrMsg))
return true;
}
// Open up a file stream for writing // Open up a file stream for writing
std::ios::openmode io_mode = std::ios::out | std::ios::trunc | std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
std::ios::binary; std::ios::binary;