예제 #1
0
파일: llvm-ar.cpp 프로젝트: Drup/llvm
// Implement the 'x' operation. This function extracts files back to the file
// system.
static void doExtract(StringRef Name, object::Archive::child_iterator I) {
  // Retain the original mode.
  sys::fs::perms Mode = I->getAccessMode();
  SmallString<128> Storage = Name;

  int FD;
  failIfError(
      sys::fs::openFileForWrite(Storage.c_str(), FD, sys::fs::F_None, Mode),
      Storage.c_str());

  {
    raw_fd_ostream file(FD, false);

    // Get the data and its length
    StringRef Data = I->getBuffer();

    // Write the data.
    file.write(Data.data(), Data.size());
  }

  // If we're supposed to retain the original modification times, etc. do so
  // now.
  if (OriginalDates)
    failIfError(
        sys::fs::setLastModificationAndAccessTime(FD, I->getLastModified()));

  if (close(FD))
    fail("Could not close the file");
}
예제 #2
0
파일: llvm-ar.cpp 프로젝트: Drup/llvm
// Implement the 't' operation. This function prints out just
// the file names of each of the members. However, if verbose mode is requested
// ('v' modifier) then the file type, permission mode, user, group, size, and
// modification time are also printed.
static void doDisplayTable(StringRef Name, object::Archive::child_iterator I) {
  if (Verbose) {
    sys::fs::perms Mode = I->getAccessMode();
    printMode((Mode >> 6) & 007);
    printMode((Mode >> 3) & 007);
    printMode(Mode & 007);
    outs() << ' ' << I->getUID();
    outs() << '/' << I->getGID();
    outs() << ' ' << format("%6llu", I->getSize());
    outs() << ' ' << I->getLastModified().str();
    outs() << ' ';
  }
  outs() << Name << "\n";
}
예제 #3
0
파일: llvm-ar.cpp 프로젝트: Drup/llvm
// Implements the 'p' operation. This function traverses the archive
// looking for members that match the path list.
static void doPrint(StringRef Name, object::Archive::child_iterator I) {
  if (Verbose)
    outs() << "Printing " << Name << "\n";

  StringRef Data = I->getBuffer();
  outs().write(Data.data(), Data.size());
}
예제 #4
0
void addMember(std::vector<NewArchiveIterator> &Members,
               object::Archive::child_iterator I, StringRef Name,
               int Pos = -1) {
  if (Thin && !I->getParent()->isThin())
    fail("Cannot convert a regular archive to a thin one");
  NewArchiveIterator NI(I, Name);
  if (Pos == -1)
    Members.push_back(NI);
  else
    Members[Pos] = NI;
}
예제 #5
0
static InsertAction
computeInsertAction(ArchiveOperation Operation,
                    object::Archive::child_iterator I, StringRef Name,
                    std::vector<std::string>::iterator &Pos) {
    if (Operation == QuickAppend || Members.empty())
        return IA_AddOldMember;

    std::vector<std::string>::iterator MI = std::find_if(
            Members.begin(), Members.end(),
    [Name](StringRef Path) {
        return Name == sys::path::filename(Path);
    });

    if (MI == Members.end())
        return IA_AddOldMember;

    Pos = MI;

    if (Operation == Delete)
        return IA_Delete;

    if (Operation == Move)
        return IA_MoveOldMember;

    if (Operation == ReplaceOrInsert) {
        StringRef PosName = sys::path::filename(RelPos);
        if (!OnlyUpdate) {
            if (PosName.empty())
                return IA_AddNewMeber;
            return IA_MoveNewMember;
        }

        // We could try to optimize this to a fstat, but it is not a common
        // operation.
        sys::fs::file_status Status;
        failIfError(sys::fs::status(*MI, Status), *MI);
        if (Status.getLastModificationTime() < I->getLastModified()) {
            if (PosName.empty())
                return IA_AddOldMember;
            return IA_MoveOldMember;
        }

        if (PosName.empty())
            return IA_AddNewMeber;
        return IA_MoveNewMember;
    }
    llvm_unreachable("No such operation");
}