[llvm] r219521 - llvm-ar: Start adding support for mri scripts.

Rafael Espindola rafael.espindola at gmail.com
Fri Oct 10 11:33:51 PDT 2014


Author: rafael
Date: Fri Oct 10 13:33:51 2014
New Revision: 219521

URL: http://llvm.org/viewvc/llvm-project?rev=219521&view=rev
Log:
llvm-ar: Start adding support for mri scripts.

I was quiet surprised to find this feature being used. Fortunately the uses
I found look fairly simple. In fact, they are just a very verbose version
of the regular ar commands.

Start implementing it then by parsing the script and setting the command
variables as if we had a regular command line.

This patch adds just enough support to create an empty archive and do a bit
of error checking. In followup patches I will implement at least addmod
and addlib.

>From the description in the manual, even the more general case should not
be too hard to implement if needed. The features that don't map 1:1 to
the simple command line are

* Reading from multiple archives.
* Creating multiple archives.

Added:
    llvm/trunk/test/Object/mri1.test
    llvm/trunk/test/Object/mri2.test
    llvm/trunk/test/Object/mri3.test
    llvm/trunk/test/Object/mri4.test
    llvm/trunk/test/Object/mri5.test
Modified:
    llvm/trunk/tools/llvm-ar/llvm-ar.cpp

Added: llvm/trunk/test/Object/mri1.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/mri1.test?rev=219521&view=auto
==============================================================================
--- llvm/trunk/test/Object/mri1.test (added)
+++ llvm/trunk/test/Object/mri1.test Fri Oct 10 13:33:51 2014
@@ -0,0 +1,6 @@
+; RUN: echo create %t.a > %t.mri
+; RUN: echo save >> %t.mri
+; RUN: echo end >> %t.mri
+
+; RUN: llvm-ar -M  < %t.mri
+; RUN: llvm-ar t %t.a

Added: llvm/trunk/test/Object/mri2.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/mri2.test?rev=219521&view=auto
==============================================================================
--- llvm/trunk/test/Object/mri2.test (added)
+++ llvm/trunk/test/Object/mri2.test Fri Oct 10 13:33:51 2014
@@ -0,0 +1,7 @@
+; RUN: echo create %t.a > %t.mri
+; RUN: echo create %t.a >> %t.mri
+; RUN: echo save >> %t.mri
+; RUN: echo end >> %t.mri
+
+; RUN: not llvm-ar -M  < %t.mri 2>&1 | FileCheck %s
+; CHECK: Editing multiple archives not supported

Added: llvm/trunk/test/Object/mri3.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/mri3.test?rev=219521&view=auto
==============================================================================
--- llvm/trunk/test/Object/mri3.test (added)
+++ llvm/trunk/test/Object/mri3.test Fri Oct 10 13:33:51 2014
@@ -0,0 +1,6 @@
+; RUN: echo save > %t.mri
+; RUN: echo create %t.a >> %t.mri
+; RUN: echo end >> %t.mri
+
+; RUN: not llvm-ar -M  < %t.mri 2>&1 | FileCheck %s
+; CHECK: File already saved.

Added: llvm/trunk/test/Object/mri4.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/mri4.test?rev=219521&view=auto
==============================================================================
--- llvm/trunk/test/Object/mri4.test (added)
+++ llvm/trunk/test/Object/mri4.test Fri Oct 10 13:33:51 2014
@@ -0,0 +1,4 @@
+; RUN: echo abc > %t.mri
+
+; RUN: not llvm-ar -M  < %t.mri 2>&1 | FileCheck %s
+; CHECK: Unknown command: abc.

Added: llvm/trunk/test/Object/mri5.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/mri5.test?rev=219521&view=auto
==============================================================================
--- llvm/trunk/test/Object/mri5.test (added)
+++ llvm/trunk/test/Object/mri5.test Fri Oct 10 13:33:51 2014
@@ -0,0 +1,2 @@
+; RUN: not llvm-ar -M t < %s 2>&1 | FileCheck %s
+; CHECK: Cannot mix -M and other options.

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=219521&r1=219520&r2=219521&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-ar/llvm-ar.cpp (original)
+++ llvm/trunk/tools/llvm-ar/llvm-ar.cpp Fri Oct 10 13:33:51 2014
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Object/Archive.h"
@@ -20,6 +21,7 @@
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/LineIterator.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/PrettyStackTrace.h"
@@ -67,8 +69,10 @@ static void failIfError(std::error_code
 
 // llvm-ar/llvm-ranlib remaining positional arguments.
 static cl::list<std::string>
-RestOfArgs(cl::Positional, cl::OneOrMore,
-    cl::desc("[relpos] [count] <archive-file> [members]..."));
+    RestOfArgs(cl::Positional, cl::ZeroOrMore,
+               cl::desc("[relpos] [count] <archive-file> [members]..."));
+
+static cl::opt<bool> MRI("M", cl::desc(""));
 
 std::string Options;
 
@@ -173,10 +177,61 @@ static void getMembers() {
     Members = std::vector<std::string>(RestOfArgs);
 }
 
+namespace {
+enum class MRICommand { Create, Save, End, Invalid };
+}
+
+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("create", MRICommand::Create)
+                       .Case("save", MRICommand::Save)
+                       .Case("end", MRICommand::End)
+                       .Default(MRICommand::Invalid);
+
+    switch (Command) {
+    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);
+  return ReplaceOrInsert;
+}
+
 // parseCommandLine - Parse the command line options as presented and return the
 // operation specified. Process all modifiers and check to make sure that
 // constraints on modifier/operation pairs have not been violated.
 static ArchiveOperation parseCommandLine() {
+  if (MRI) {
+    if (!RestOfArgs.empty())
+      fail("Cannot mix -M and other options");
+    return parseMRIScript();
+  }
+
   getOptions();
 
   // Keep track of number of operations. We can only specify one





More information about the llvm-commits mailing list