Simplify boolean expressions in tools/llvm-objdump.
[oota-llvm.git] / tools / llvm-ar / llvm-ar.cpp
index b3e5043d5008d598aa8997626410a34cdcbb0bf7..ec3cfcb5cad014ed265afbd24eb9d76de9a170d4 100644 (file)
@@ -130,6 +130,7 @@ static bool OnlyUpdate = false;    ///< 'u' modifier
 static bool Verbose = false;       ///< 'v' modifier
 static bool Symtab = true;         ///< 's' modifier
 static bool Deterministic = true;  ///< 'D' and 'U' modifiers
+static bool Thin = false;          ///< 'T' modifier
 
 // Relative Positional Argument (for insert/move). This variable holds
 // the name of the archive member to which the 'a', 'b' or 'i' modifier
@@ -252,6 +253,9 @@ static ArchiveOperation parseCommandLine() {
     case 'U':
       Deterministic = false;
       break;
+    case 'T':
+      Thin = true;
+      break;
     default:
       cl::PrintHelpMessage();
     }
@@ -299,7 +303,9 @@ static void doPrint(StringRef Name, const object::Archive::Child &C) {
   if (Verbose)
     outs() << "Printing " << Name << "\n";
 
-  StringRef Data = C.getBuffer();
+  ErrorOr<StringRef> DataOrErr = C.getBuffer();
+  failIfError(DataOrErr.getError());
+  StringRef Data = *DataOrErr;
   outs().write(Data.data(), Data.size());
 }
 
@@ -355,7 +361,7 @@ static void doExtract(StringRef Name, const object::Archive::Child &C) {
     raw_fd_ostream file(FD, false);
 
     // Get the data and its length
-    StringRef Data = C.getBuffer();
+    StringRef Data = *C.getBuffer();
 
     // Write the data.
     file.write(Data.data(), Data.size());
@@ -391,14 +397,23 @@ static bool shouldCreateArchive(ArchiveOperation Op) {
 
 static void performReadOperation(ArchiveOperation Operation,
                                  object::Archive *OldArchive) {
+  if (Operation == Extract && OldArchive->isThin()) {
+    errs() << "extracting from a thin archive is not supported\n";
+    std::exit(1);
+  }
+
+  bool Filter = !Members.empty();
   for (const object::Archive::Child &C : OldArchive->children()) {
     ErrorOr<StringRef> NameOrErr = C.getName();
     failIfError(NameOrErr.getError());
     StringRef Name = NameOrErr.get();
 
-    if (!Members.empty() &&
-        std::find(Members.begin(), Members.end(), Name) == Members.end())
-      continue;
+    if (Filter) {
+      auto I = std::find(Members.begin(), Members.end(), Name);
+      if (I == Members.end())
+        continue;
+      Members.erase(I);
+    }
 
     switch (Operation) {
     default:
@@ -414,11 +429,27 @@ static void performReadOperation(ArchiveOperation Operation,
       break;
     }
   }
+  if (Members.empty())
+    return;
+  for (StringRef Name : Members)
+    errs() << Name << " was not found\n";
+  std::exit(1);
+}
+
+void addMember(std::vector<NewArchiveIterator> &Members, StringRef FileName,
+               int Pos = -1) {
+  NewArchiveIterator NI(FileName);
+  if (Pos == -1)
+    Members.push_back(NI);
+  else
+    Members[Pos] = NI;
 }
 
-template <typename T>
-void addMember(std::vector<NewArchiveIterator> &Members, T I, StringRef Name,
+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);
@@ -513,7 +544,7 @@ computeNewArchiveMembers(ArchiveOperation Operation,
         addMember(Ret, Child, Name);
         break;
       case IA_AddNewMeber:
-        addMember(Ret, *MemberI, Name);
+        addMember(Ret, *MemberI);
         break;
       case IA_Delete:
         break;
@@ -521,7 +552,7 @@ computeNewArchiveMembers(ArchiveOperation Operation,
         addMember(Moved, Child, Name);
         break;
       case IA_MoveNewMember:
-        addMember(Moved, *MemberI, Name);
+        addMember(Moved, *MemberI);
         break;
       }
       if (MemberI != Members.end())
@@ -541,12 +572,10 @@ computeNewArchiveMembers(ArchiveOperation Operation,
   assert(unsigned(InsertPos) <= Ret.size());
   Ret.insert(Ret.begin() + InsertPos, Moved.begin(), Moved.end());
 
-  Ret.insert(Ret.begin() + InsertPos, Members.size(),
-             NewArchiveIterator("", ""));
+  Ret.insert(Ret.begin() + InsertPos, Members.size(), NewArchiveIterator(""));
   int Pos = InsertPos;
   for (auto &Member : Members) {
-    StringRef Name = sys::path::filename(Member);
-    addMember(Ret, Member, Name, Pos);
+    addMember(Ret, Member, Pos);
     ++Pos;
   }
 
@@ -574,15 +603,15 @@ performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive,
     break;
   }
   if (NewMembersP) {
-    std::pair<StringRef, std::error_code> Result =
-        writeArchive(ArchiveName, *NewMembersP, Symtab, Kind, Deterministic);
+    std::pair<StringRef, std::error_code> Result = writeArchive(
+        ArchiveName, *NewMembersP, Symtab, Kind, Deterministic, Thin);
     failIfError(Result.second, Result.first);
     return;
   }
   std::vector<NewArchiveIterator> NewMembers =
       computeNewArchiveMembers(Operation, OldArchive);
   auto Result =
-      writeArchive(ArchiveName, NewMembers, Symtab, Kind, Deterministic);
+      writeArchive(ArchiveName, NewMembers, Symtab, Kind, Deterministic, Thin);
   failIfError(Result.second, Result.first);
 }
 
@@ -705,7 +734,7 @@ static void runMRIScript() {
       break;
     }
     case MRICommand::AddMod:
-      addMember(NewMembers, Rest, sys::path::filename(Rest));
+      addMember(NewMembers, Rest);
       break;
     case MRICommand::Create:
       Create = true;