// 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. bool ArchiveMember::replaceWith(StringRef newFile, std::string* ErrMsg) { bool Exists; if (sys::fs::exists(newFile.str(), Exists) || !Exists) { if (ErrMsg) *ErrMsg = "Can not replace an archive member with a non-existent file"; return true; } data = 0; path = newFile.str(); // SVR4 symbol tables have an empty name if (path == ARFILE_SVR4_SYMTAB_NAME) flags |= SVR4SymbolTableFlag; else flags &= ~SVR4SymbolTableFlag; // BSD4.4 symbol tables have a special name if (path == ARFILE_BSD4_SYMTAB_NAME) flags |= BSD4SymbolTableFlag; else flags &= ~BSD4SymbolTableFlag; // String table name if (path == ARFILE_STRTAB_NAME) flags |= StringTableFlag; else flags &= ~StringTableFlag; // If it has a slash or its over 15 chars then its a long filename format if (path.length() > 15) flags |= HasLongFilenameFlag; else flags &= ~HasLongFilenameFlag; // Get the signature and status info const char* signature = (const char*) data; SmallString<4> magic; if (!signature) { sys::fs::get_magic(path, magic.capacity(), magic); signature = magic.c_str(); sys::fs::file_status Status; error_code EC = sys::fs::status(path, Status); if (EC) return true; User = Status.getUser(); Group = Status.getGroup(); Mode = Status.permissions(); ModTime = Status.getLastModificationTime(); // FIXME: On posix this is a second stat. EC = sys::fs::file_size(path, Size); if (EC) return true; } return false; }
// 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. bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) { bool Exists; if (sys::fs::exists(newFile.str(), Exists) || !Exists) { if (ErrMsg) *ErrMsg = "Can not replace an archive member with a non-existent file"; return true; } data = 0; path = newFile; // SVR4 symbol tables have an empty name if (path.str() == ARFILE_SVR4_SYMTAB_NAME) flags |= SVR4SymbolTableFlag; else flags &= ~SVR4SymbolTableFlag; // BSD4.4 symbol tables have a special name if (path.str() == ARFILE_BSD4_SYMTAB_NAME) flags |= BSD4SymbolTableFlag; else flags &= ~BSD4SymbolTableFlag; // LLVM symbol tables have a very specific name if (path.str() == ARFILE_LLVM_SYMTAB_NAME) flags |= LLVMSymbolTableFlag; else flags &= ~LLVMSymbolTableFlag; // String table name if (path.str() == ARFILE_STRTAB_NAME) flags |= StringTableFlag; else flags &= ~StringTableFlag; // If it has a slash then it has a path bool hasSlash = path.str().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 (hasSlash || path.str().length() > 15) flags |= HasLongFilenameFlag; else flags &= ~HasLongFilenameFlag; // Get the signature and status info const char* signature = (const char*) data; SmallString<4> magic; if (!signature) { sys::fs::get_magic(path.str(), magic.capacity(), magic); signature = magic.c_str(); const sys::FileStatus *FSinfo = path.getFileStatus(false, ErrMsg); if (FSinfo) info = *FSinfo; else return true; } // Determine what kind of file it is. switch (sys::IdentifyFileType(signature,4)) { case sys::Bitcode_FileType: flags |= BitcodeFlag; break; default: flags &= ~BitcodeFlag; break; } return false; }