diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-10-10 18:33:51 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-10-10 18:33:51 +0000 |
commit | b275797e31a3536f7b5b26be1f7b3d26726434c9 (patch) | |
tree | 1cf7546f65ae1db687a19d9563642591e539f108 /llvm/tools/llvm-ar/llvm-ar.cpp | |
parent | 1d33e8d38f86c89b11cdc3e4f4d79e91baad2fd5 (diff) | |
download | bcm5719-llvm-b275797e31a3536f7b5b26be1f7b3d26726434c9.tar.gz bcm5719-llvm-b275797e31a3536f7b5b26be1f7b3d26726434c9.zip |
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.
llvm-svn: 219521
Diffstat (limited to 'llvm/tools/llvm-ar/llvm-ar.cpp')
-rw-r--r-- | llvm/tools/llvm-ar/llvm-ar.cpp | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp index 2b32098a490..fa0842992ec 100644 --- a/llvm/tools/llvm-ar/llvm-ar.cpp +++ b/llvm/tools/llvm-ar/llvm-ar.cpp @@ -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 EC, Twine Context = "") { // 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 |