Index: llvm/test/tools/llvm-ar/mri5.test =================================================================== --- llvm/test/tools/llvm-ar/mri5.test +++ llvm/test/tools/llvm-ar/mri5.test @@ -1,2 +1,44 @@ -; RUN: not llvm-ar -M t < %s 2>&1 | FileCheck %s -; CHECK: error: cannot mix -M and other options +# RUN: echo contents > %t.txt + +# RUN: echo create %t.a > %t.mri +# RUN: echo addmod %t.txt >> %t.mri +# RUN: echo save >> %t.mri + +# RUN: rm %t.a +# RUN: llvm-ar -M %t.mri +# RUN: llvm-ar p %t.a| FileCheck %s --check-prefix=CONTENTS +# CONTENTS: contents + +# RUN: not llvm-ar -M %/t.bad 2>&1 | FileCheck %s --check-prefix=BAD-SCRIPT -DPATH=%/t.bad +# BAD-SCRIPT: error: could not open MRI Script [[PATH]]: no such file or directory + +# RUN: not llvm-ar -M t < %s 2>&1 | FileCheck %s --check-prefix=EXTRA-1 +# EXTRA-1: error: could not open MRI Script t: no such file or directory + +# RUN: not llvm-ar -M t v< %s 2>&1 | FileCheck %s --check-prefix=EXTRA-2 +# EXTRA-2: error: cannot mix -M and other options + +# RUN: not llvm-ar t -M < %s 2>&1 | FileCheck %s --check-prefix=EXTRA-2 + +# RUN: rm %t.a +# RUN: echo -M %/t.mri > %t.response +# RUN: llvm-ar @%t.response +# RUN: llvm-ar p %t.a| FileCheck %s --check-prefix=CONTENTS + +# stdin has lower precedence +# RUN: rm %t.a +# RUN: llvm-ar -M %t.mri < %s +# RUN: llvm-ar p %t.a| FileCheck %s --check-prefix=CONTENTS + +# RUN: not llvm-ar < %t.mri 2>&1 | FileCheck %s --check-prefix=NO-M +# NO-M: error: an archive name must be specified + +# RUN: rm %t.a +# RUN: cp %t.mri "%t copy.mri" +# RUN: llvm-ar -M "%t copy.mri" +# RUN: llvm-ar p %t.a| FileCheck %s --check-prefix=CONTENTS + +# RUN: rm %t.a +# RUN: cp %t.mri "%t£.txt" +# RUN: llvm-ar -M "%t£.txt" +# RUN: llvm-ar p %t.a| FileCheck %s --check-prefix=CONTENTS Index: llvm/tools/llvm-ar/llvm-ar.cpp =================================================================== --- llvm/tools/llvm-ar/llvm-ar.cpp +++ llvm/tools/llvm-ar/llvm-ar.cpp @@ -164,8 +164,6 @@ static SmallVector PositionalArgs; -static bool MRI; - namespace { enum Format { Default, GNU, BSD, DARWIN, Unknown }; } @@ -216,6 +214,10 @@ // command line. static std::string ArchiveName; +// This variable holds the name of the MRI script if given on the command line. +// It defaults to "-" for stdin +static std::string MRIScriptName = "-"; + static std::vector> ArchiveBuffers; static std::vector> Archives; @@ -256,6 +258,14 @@ PositionalArgs.erase(PositionalArgs.begin()); } +// Get the MRI script file name from the command line +static void getMRIScript() { + if (PositionalArgs.empty()) + return; + MRIScriptName = PositionalArgs[0]; + PositionalArgs.erase(PositionalArgs.begin()); +} + static object::Archive &readLibrary(const Twine &Library) { auto BufOrErr = MemoryBuffer::getFile(Library, -1, false); failIfError(BufOrErr.getError(), "could not open library " + Library); @@ -274,12 +284,6 @@ // 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 (!PositionalArgs.empty() || !Options.empty()) - fail("cannot mix -M and other options"); - runMRIScript(); - } - // Keep track of number of operations. We can only specify one // per execution. unsigned NumOperations = 0; @@ -295,6 +299,12 @@ for (unsigned i = 0; i < Options.size(); ++i) { switch (Options[i]) { + case 'M': + getMRIScript(); + if (i > 0 || Options.size() > 1 || !PositionalArgs.empty()) + fail("cannot mix -M and other options"); + runMRIScript(); + break; case 'd': ++NumOperations; Operation = Delete; @@ -995,8 +1005,12 @@ static void runMRIScript() { enum class MRICommand { AddLib, AddMod, Create, CreateThin, Delete, Save, End, Invalid }; - ErrorOr> Buf = MemoryBuffer::getSTDIN(); - failIfError(Buf.getError()); + ErrorOr> Buf = + MemoryBuffer::getFileOrSTDIN(MRIScriptName); + + failIfError( + Buf.getError(), + MRIScriptName == "-" ? "" : "could not open MRI Script " + MRIScriptName); const MemoryBuffer &Ref = *Buf.get(); bool Saved = false; std::vector NewMembers; @@ -1119,9 +1133,7 @@ Arg = Argv[i] + 2; else Arg = Argv[i] + 1; - if (Arg == "M") { - MRI = true; - } else if (MatchFlagWithArg("format")) { + if (MatchFlagWithArg("format")) { FormatType = StringSwitch(match) .Case("default", Default) .Case("gnu", GNU)