[llvm] r220336 - Overwrite instead of adding to archives when creating them in mri scripts.

Rafael Espindola rafael.espindola at gmail.com
Tue Oct 21 14:56:47 PDT 2014


Author: rafael
Date: Tue Oct 21 16:56:47 2014
New Revision: 220336

URL: http://llvm.org/viewvc/llvm-project?rev=220336&view=rev
Log:
Overwrite instead of adding to archives when creating them in mri scripts.

This matches the behavior of GNU ar and also makes it easier to implemnt
support for the addlib command.

Modified:
    llvm/trunk/test/Object/mri-addmod.test
    llvm/trunk/tools/llvm-ar/llvm-ar.cpp

Modified: llvm/trunk/test/Object/mri-addmod.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/mri-addmod.test?rev=220336&r1=220335&r2=220336&view=diff
==============================================================================
--- llvm/trunk/test/Object/mri-addmod.test (original)
+++ llvm/trunk/test/Object/mri-addmod.test Tue Oct 21 16:56:47 2014
@@ -14,5 +14,23 @@
 ; CHECK-NEXT: 0000000000000000 T main
 ; CHECK-NEXT:                  U puts
 
+; Now test that CREATE overwrites an existing file.
+; RUN: echo create %t.a > %t2.mri
+; RUN: echo addmod %p/Inputs/trivial-object-test2.elf-x86-64 >> %t2.mri
+; RUN: echo save >> %t2.mri
+; RUN: echo end >> %t2.mri
+
+; RUN: llvm-ar -M  < %t2.mri
+; RUN: llvm-nm -M %t.a | FileCheck --check-prefix=NEW %s
+
+; NEW: Archive map
+; NEW-NEXT: foo in trivial-object-test2.elf-x86-64
+; NEW-NEXT: main in trivial-object-test2.elf-x86-64
+
+; NEW: trivial-object-test2.elf-x86-64:
+; NEW-NEXT: 0000000000000000 t bar
+; NEW-NEXT: 0000000000000006 T foo
+; NEW-NEXT: 0000000000000016 T main
+
 ; line_iterator is incompatible to CRLF.
 ; REQUIRES: shell

Modified: llvm/trunk/tools/llvm-ar/llvm-ar.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ar/llvm-ar.cpp?rev=220336&r1=220335&r2=220336&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-ar/llvm-ar.cpp (original)
+++ llvm/trunk/tools/llvm-ar/llvm-ar.cpp Tue Oct 21 16:56:47 2014
@@ -176,59 +176,7 @@ static void getMembers() {
     Members.push_back(Arg);
 }
 
-namespace {
-enum class MRICommand { AddMod, Create, Save, End, Invalid };
-}
-
-static std::vector<std::string> MRIMembers;
-static ArchiveOperation parseMRIScript() {
-  ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getSTDIN();
-  failIfError(Buf.getError());
-  const MemoryBuffer &Ref = *Buf.get();
-  bool Saved = false;
-
-  for (line_iterator I(Ref, /*SkipBlanks*/ true, ';'), E; I != E; ++I) {
-    StringRef Line = *I;
-    StringRef CommandStr, Rest;
-    std::tie(CommandStr, Rest) = Line.split(' ');
-    auto Command = StringSwitch<MRICommand>(CommandStr.lower())
-                       .Case("addmod", MRICommand::AddMod)
-                       .Case("create", MRICommand::Create)
-                       .Case("save", MRICommand::Save)
-                       .Case("end", MRICommand::End)
-                       .Default(MRICommand::Invalid);
-
-    switch (Command) {
-    case MRICommand::AddMod:
-      MRIMembers.push_back(Rest);
-      break;
-    case MRICommand::Create:
-      Create = true;
-      if (!ArchiveName.empty())
-        fail("Editing multiple archives not supported");
-      if (Saved)
-        fail("File already saved");
-      ArchiveName = Rest;
-      break;
-    case MRICommand::Save:
-      Saved = true;
-      break;
-    case MRICommand::End:
-      break;
-    case MRICommand::Invalid:
-      fail("Unknown command: " + CommandStr);
-    }
-  }
-
-  // Nothing to do if not saved.
-  if (!Saved)
-    exit(0);
-
-  for (auto &M : MRIMembers)
-    Members.push_back(M);
-
-  return ReplaceOrInsert;
-}
+static void runMRIScript();
 
 // Parse the command line options as presented and return the operation
 // specified. Process all modifiers and check to make sure that constraints on
@@ -237,7 +185,7 @@ static ArchiveOperation parseCommandLine
   if (MRI) {
     if (!RestOfArgs.empty())
       fail("Cannot mix -M and other options");
-    return parseMRIScript();
+    runMRIScript();
   }
 
   getOptions();
@@ -805,8 +753,9 @@ writeSymbolTable(raw_fd_ostream &Out, Ar
   Out.seek(Pos);
 }
 
-static void performWriteOperation(ArchiveOperation Operation,
-                                  object::Archive *OldArchive) {
+static void
+performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive,
+                      std::vector<NewArchiveIterator> &NewMembers) {
   SmallString<128> TmpArchive;
   failIfError(sys::fs::createUniqueFile(ArchiveName + ".temp-archive-%%%%%%%.a",
                                         TmpArchiveFD, TmpArchive));
@@ -816,9 +765,6 @@ static void performWriteOperation(Archiv
   raw_fd_ostream &Out = Output.os();
   Out << "!<arch>\n";
 
-  std::vector<NewArchiveIterator> NewMembers =
-      computeNewArchiveMembers(Operation, OldArchive);
-
   std::vector<std::pair<unsigned, unsigned> > MemberOffsetRefs;
 
   std::vector<std::unique_ptr<MemoryBuffer>> Buffers;
@@ -914,6 +860,18 @@ static void performWriteOperation(Archiv
   TemporaryOutput = nullptr;
 }
 
+static void
+performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive,
+                      std::vector<NewArchiveIterator> *NewMembersP) {
+  if (NewMembersP) {
+    performWriteOperation(Operation, OldArchive, *NewMembersP);
+    return;
+  }
+  std::vector<NewArchiveIterator> NewMembers =
+      computeNewArchiveMembers(Operation, OldArchive);
+  performWriteOperation(Operation, OldArchive, NewMembers);
+}
+
 static void createSymbolTable(object::Archive *OldArchive) {
   // When an archive is created or modified, if the s option is given, the
   // resulting archive will have a current symbol table. If the S option
@@ -924,11 +882,12 @@ static void createSymbolTable(object::Ar
   if (OldArchive->hasSymbolTable())
     return;
 
-  performWriteOperation(CreateSymTab, OldArchive);
+  performWriteOperation(CreateSymTab, OldArchive, nullptr);
 }
 
 static void performOperation(ArchiveOperation Operation,
-                             object::Archive *OldArchive) {
+                             object::Archive *OldArchive,
+                             std::vector<NewArchiveIterator> *NewMembers) {
   switch (Operation) {
   case Print:
   case DisplayTable:
@@ -940,7 +899,7 @@ static void performOperation(ArchiveOper
   case Move:
   case QuickAppend:
   case ReplaceOrInsert:
-    performWriteOperation(Operation, OldArchive);
+    performWriteOperation(Operation, OldArchive, NewMembers);
     return;
   case CreateSymTab:
     createSymbolTable(OldArchive);
@@ -949,7 +908,8 @@ static void performOperation(ArchiveOper
   llvm_unreachable("Unknown operation.");
 }
 
-static int performOperation(ArchiveOperation Operation) {
+static int performOperation(ArchiveOperation Operation,
+                            std::vector<NewArchiveIterator> *NewMembers) {
   // Create or open the archive object.
   ErrorOr<std::unique_ptr<MemoryBuffer>> Buf =
       MemoryBuffer::getFile(ArchiveName, -1, false);
@@ -968,7 +928,7 @@ static int performOperation(ArchiveOpera
              << "': " << EC.message() << "!\n";
       return 1;
     }
-    performOperation(Operation, &Archive);
+    performOperation(Operation, &Archive, NewMembers);
     return 0;
   }
 
@@ -983,22 +943,70 @@ static int performOperation(ArchiveOpera
     }
   }
 
-  performOperation(Operation, nullptr);
+  performOperation(Operation, nullptr, NewMembers);
   return 0;
 }
 
+static void runMRIScript() {
+  enum class MRICommand { AddMod, Create, Save, End, Invalid };
+
+  ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getSTDIN();
+  failIfError(Buf.getError());
+  const MemoryBuffer &Ref = *Buf.get();
+  bool Saved = false;
+  std::vector<NewArchiveIterator> NewMembers;
+
+  for (line_iterator I(Ref, /*SkipBlanks*/ true, ';'), E; I != E; ++I) {
+    StringRef Line = *I;
+    StringRef CommandStr, Rest;
+    std::tie(CommandStr, Rest) = Line.split(' ');
+    auto Command = StringSwitch<MRICommand>(CommandStr.lower())
+                       .Case("addmod", MRICommand::AddMod)
+                       .Case("create", MRICommand::Create)
+                       .Case("save", MRICommand::Save)
+                       .Case("end", MRICommand::End)
+                       .Default(MRICommand::Invalid);
+
+    switch (Command) {
+    case MRICommand::AddMod:
+      addMember(NewMembers, Rest, sys::path::filename(Rest));
+      break;
+    case MRICommand::Create:
+      Create = true;
+      if (!ArchiveName.empty())
+        fail("Editing multiple archives not supported");
+      if (Saved)
+        fail("File already saved");
+      ArchiveName = Rest;
+      break;
+    case MRICommand::Save:
+      Saved = true;
+      break;
+    case MRICommand::End:
+      break;
+    case MRICommand::Invalid:
+      fail("Unknown command: " + CommandStr);
+    }
+  }
+
+  // Nothing to do if not saved.
+  if (Saved)
+    performOperation(ReplaceOrInsert, &NewMembers);
+  exit(0);
+}
+
 int ar_main(char **argv) {
   // Do our own parsing of the command line because the CommandLine utility
   // can't handle the grouped positional parameters without a dash.
   ArchiveOperation Operation = parseCommandLine();
-  return performOperation(Operation);
+  return performOperation(Operation, nullptr);
 }
 
 int ranlib_main() {
   if (RestOfArgs.size() != 1)
     fail(ToolName + "takes just one archive as argument");
   ArchiveName = RestOfArgs[0];
-  return performOperation(CreateSymTab);
+  return performOperation(CreateSymTab, nullptr);
 }
 
 int main(int argc, char **argv) {





More information about the llvm-commits mailing list