mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-27 13:30:05 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219521 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b144f27c8f
commit
f02687d9eb
6
test/Object/mri1.test
Normal file
6
test/Object/mri1.test
Normal file
@ -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
|
7
test/Object/mri2.test
Normal file
7
test/Object/mri2.test
Normal file
@ -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
|
6
test/Object/mri3.test
Normal file
6
test/Object/mri3.test
Normal file
@ -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.
|
4
test/Object/mri4.test
Normal file
4
test/Object/mri4.test
Normal file
@ -0,0 +1,4 @@
|
||||
; RUN: echo abc > %t.mri
|
||||
|
||||
; RUN: not llvm-ar -M < %t.mri 2>&1 | FileCheck %s
|
||||
; CHECK: Unknown command: abc.
|
2
test/Object/mri5.test
Normal file
2
test/Object/mri5.test
Normal file
@ -0,0 +1,2 @@
|
||||
; RUN: not llvm-ar -M t < %s 2>&1 | FileCheck %s
|
||||
; CHECK: Cannot mix -M and other options.
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user