summaryrefslogtreecommitdiff
path: root/tools/llvm-ar/llvm-ar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-ar/llvm-ar.cpp')
-rw-r--r--tools/llvm-ar/llvm-ar.cpp61
1 files changed, 35 insertions, 26 deletions
diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp
index af4d3efa52f7..ae7d1a7f1b7a 100644
--- a/tools/llvm-ar/llvm-ar.cpp
+++ b/tools/llvm-ar/llvm-ar.cpp
@@ -15,7 +15,6 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
#include "llvm/ToolDrivers/llvm-dlltool/DlltoolDriver.h"
#include "llvm/ToolDrivers/llvm-lib/LibDriver.h"
#include "llvm/Object/Archive.h"
@@ -36,9 +35,6 @@
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cstdlib>
-#include <memory>
#if !defined(_MSC_VER) && !defined(__MINGW32__)
#include <unistd.h>
@@ -54,6 +50,7 @@ static StringRef ToolName;
// Show the error message and exit.
LLVM_ATTRIBUTE_NORETURN static void fail(Twine Error) {
errs() << ToolName << ": " << Error << ".\n";
+ cl::PrintHelpMessage();
exit(1);
}
@@ -126,6 +123,8 @@ static cl::extrahelp MoreHelp(
" [v] - be verbose about actions taken\n"
);
+static const char OptionChars[] = "dmpqrtxabiosSTucv";
+
// This enumeration delineates the kinds of operations on an archive
// that are permitted.
enum ArchiveOperation {
@@ -164,26 +163,18 @@ static std::string ArchiveName;
// on the command line.
static std::vector<StringRef> Members;
-// Show the error message, the help message and exit.
-LLVM_ATTRIBUTE_NORETURN static void
-show_help(const std::string &msg) {
- errs() << ToolName << ": " << msg << "\n\n";
- cl::PrintHelpMessage();
- exit(1);
-}
-
// Extract the member filename from the command line for the [relpos] argument
// associated with a, b, and i modifiers
static void getRelPos() {
if(RestOfArgs.size() == 0)
- show_help("Expected [relpos] for a, b, or i modifier");
+ fail("Expected [relpos] for a, b, or i modifier");
RelPos = RestOfArgs[0];
RestOfArgs.erase(RestOfArgs.begin());
}
static void getOptions() {
if(RestOfArgs.size() == 0)
- show_help("Expected options");
+ fail("Expected options");
Options = RestOfArgs[0];
RestOfArgs.erase(RestOfArgs.begin());
}
@@ -191,7 +182,7 @@ static void getOptions() {
// Get the archive file name from the command line
static void getArchive() {
if(RestOfArgs.size() == 0)
- show_help("An archive name must be specified");
+ fail("An archive name must be specified");
ArchiveName = RestOfArgs[0];
RestOfArgs.erase(RestOfArgs.begin());
}
@@ -275,7 +266,7 @@ static ArchiveOperation parseCommandLine() {
Thin = true;
break;
default:
- cl::PrintHelpMessage();
+ fail(std::string("unknown option ") + Options[i]);
}
}
@@ -290,26 +281,26 @@ static ArchiveOperation parseCommandLine() {
NumOperations = 1;
Operation = CreateSymTab;
if (!Members.empty())
- show_help("The s operation takes only an archive as argument");
+ fail("The s operation takes only an archive as argument");
}
// Perform various checks on the operation/modifier specification
// to make sure we are dealing with a legal request.
if (NumOperations == 0)
- show_help("You must specify at least one of the operations");
+ fail("You must specify at least one of the operations");
if (NumOperations > 1)
- show_help("Only one operation may be specified");
+ fail("Only one operation may be specified");
if (NumPositional > 1)
- show_help("You may only specify one of a, b, and i modifiers");
+ fail("You may only specify one of a, b, and i modifiers");
if (AddAfter || AddBefore) {
if (Operation != Move && Operation != ReplaceOrInsert)
- show_help("The 'a', 'b' and 'i' modifiers can only be specified with "
- "the 'm' or 'r' operations");
+ fail("The 'a', 'b' and 'i' modifiers can only be specified with "
+ "the 'm' or 'r' operations");
}
if (OriginalDates && Operation != Extract)
- show_help("The 'o' modifier is only applicable to the 'x' operation");
+ fail("The 'o' modifier is only applicable to the 'x' operation");
if (OnlyUpdate && Operation != ReplaceOrInsert)
- show_help("The 'u' modifier is only applicable to the 'r' operation");
+ fail("The 'u' modifier is only applicable to the 'r' operation");
// Return the parsed operation to the caller
return Operation;
@@ -688,10 +679,10 @@ performWriteOperation(ArchiveOperation Operation,
break;
}
- std::pair<StringRef, std::error_code> Result =
+ Error E =
writeArchive(ArchiveName, NewMembersP ? *NewMembersP : NewMembers, Symtab,
Kind, Deterministic, Thin, std::move(OldArchiveBuf));
- failIfError(Result.second, Result.first);
+ failIfError(std::move(E), ArchiveName);
}
static void createSymbolTable(object::Archive *OldArchive) {
@@ -871,6 +862,24 @@ int main(int argc, char **argv) {
Stem.find("lib") != StringRef::npos)
return libDriverMain(makeArrayRef(argv, argc));
+ for (int i = 1; i < argc; i++) {
+ // If an argument starts with a dash and only contains chars
+ // that belong to the options chars set, remove the dash.
+ // We can't handle it after the command line options parsing
+ // is done, since it will error out on an unrecognized string
+ // starting with a dash.
+ // Make sure this doesn't match the actual llvm-ar specific options
+ // that start with a dash.
+ StringRef S = argv[i];
+ if (S.startswith("-") &&
+ S.find_first_not_of(OptionChars, 1) == StringRef::npos) {
+ argv[i]++;
+ break;
+ }
+ if (S == "--")
+ break;
+ }
+
// Have the command line options parsed and handle things
// like --help and --version.
cl::ParseCommandLineOptions(argc, argv,