diff options
Diffstat (limited to 'tools/llvm-ar/llvm-ar.cpp')
| -rw-r--r-- | tools/llvm-ar/llvm-ar.cpp | 61 | 
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,  | 
