diff options
author | Joerg Sonnenberger <joerg@bec.de> | 2012-10-26 10:49:15 +0000 |
---|---|---|
committer | Joerg Sonnenberger <joerg@bec.de> | 2012-10-26 10:49:15 +0000 |
commit | 975bc072ae1d4502d0dc7ca0d218a18574108ee6 (patch) | |
tree | cc3113016f59defebbbfc0e465207d1040d6b9a0 /tools/llvm-ar/llvm-ar.cpp | |
parent | 0bd10f2af37e694f08f41199f4c6792c494430d9 (diff) |
Adjust llvm-ar and llvm-ranlib to not depend on exception handling.
Always use an exit code of 1, but print the help message if useful.
Remove the exception handling tag in llvm-as, llvm-dis and
llvm-bcanalyzer, where it isn't used.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166767 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-ar/llvm-ar.cpp')
-rw-r--r-- | tools/llvm-ar/llvm-ar.cpp | 203 |
1 files changed, 104 insertions, 99 deletions
diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index 7c53701f00..a8a5013a9a 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -23,6 +23,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Signals.h" #include <algorithm> +#include <cstdlib> #include <memory> #include <fstream> using namespace llvm; @@ -126,40 +127,57 @@ std::set<sys::Path> Paths; // The Archive object to which all the editing operations will be sent. Archive* TheArchive = 0; +// The name this program was invoked as. +static const char *program_name; + +// show_help - Show the error message, the help message and exit. +LLVM_ATTRIBUTE_NORETURN static void +show_help(const std::string &msg) { + errs() << program_name << ": " << msg << "\n\n"; + cl::PrintHelpMessage(); + if (TheArchive) + delete TheArchive; + std::exit(1); +} + +// fail - Show the error message and exit. +LLVM_ATTRIBUTE_NORETURN static void +fail(const std::string &msg) { + errs() << program_name << ": " << msg << "\n\n"; + if (TheArchive) + delete TheArchive; + std::exit(1); +} + // getRelPos - Extract the member filename from the command line for // the [relpos] argument associated with a, b, and i modifiers void getRelPos() { - if(RestOfArgs.size() > 0) { - RelPos = RestOfArgs[0]; - RestOfArgs.erase(RestOfArgs.begin()); - } - else - throw "Expected [relpos] for a, b, or i modifier"; + if(RestOfArgs.size() == 0) + show_help("Expected [relpos] for a, b, or i modifier"); + RelPos = RestOfArgs[0]; + RestOfArgs.erase(RestOfArgs.begin()); } // getCount - Extract the [count] argument associated with the N modifier // from the command line and check its value. void getCount() { - if(RestOfArgs.size() > 0) { - Count = atoi(RestOfArgs[0].c_str()); - RestOfArgs.erase(RestOfArgs.begin()); - } - else - throw "Expected [count] value with N modifier"; + if(RestOfArgs.size() == 0) + show_help("Expected [count] value with N modifier"); + + Count = atoi(RestOfArgs[0].c_str()); + RestOfArgs.erase(RestOfArgs.begin()); // Non-positive counts are not allowed if (Count < 1) - throw "Invalid [count] value (not a positive integer)"; + show_help("Invalid [count] value (not a positive integer)"); } // getArchive - Get the archive file name from the command line void getArchive() { - if(RestOfArgs.size() > 0) { - ArchiveName = RestOfArgs[0]; - RestOfArgs.erase(RestOfArgs.begin()); - } - else - throw "An archive name must be specified."; + if(RestOfArgs.size() == 0) + show_help("An archive name must be specified"); + ArchiveName = RestOfArgs[0]; + RestOfArgs.erase(RestOfArgs.begin()); } // getMembers - Copy over remaining items in RestOfArgs to our Members vector @@ -240,25 +258,27 @@ ArchiveOperation parseCommandLine() { // Perform various checks on the operation/modifier specification // to make sure we are dealing with a legal request. if (NumOperations == 0) - throw "You must specify at least one of the operations"; + show_help("You must specify at least one of the operations"); if (NumOperations > 1) - throw "Only one operation may be specified"; + show_help("Only one operation may be specified"); if (NumPositional > 1) - throw "You may only specify one of a, b, and i modifiers"; - if (AddAfter || AddBefore || InsertBefore) + show_help("You may only specify one of a, b, and i modifiers"); + if (AddAfter || AddBefore || InsertBefore) { if (Operation != Move && Operation != ReplaceOrInsert) - throw "The 'a', 'b' and 'i' modifiers can only be specified with " - "the 'm' or 'r' operations"; + show_help("The 'a', 'b' and 'i' modifiers can only be specified with " + "the 'm' or 'r' operations"); + } if (RecurseDirectories && Operation != ReplaceOrInsert) - throw "The 'R' modifiers is only applicabe to the 'r' operation"; + show_help("The 'R' modifiers is only applicabe to the 'r' operation"); if (OriginalDates && Operation != Extract) - throw "The 'o' modifier is only applicable to the 'x' operation"; + show_help("The 'o' modifier is only applicable to the 'x' operation"); if (TruncateNames && Operation!=QuickAppend && Operation!=ReplaceOrInsert) - throw "The 'f' modifier is only applicable to the 'q' and 'r' operations"; + show_help("The 'f' modifier is only applicable to the 'q' and 'r' " + "operations"); if (OnlyUpdate && Operation != ReplaceOrInsert) - throw "The 'u' modifier is only applicable to the 'r' operation"; + show_help("The 'u' modifier is only applicable to the 'r' operation"); if (Count > 1 && Members.size() > 1) - throw "Only one member name may be specified with the 'N' modifier"; + show_help("Only one member name may be specified with the 'N' modifier"); // Return the parsed operation to the caller return Operation; @@ -304,16 +324,16 @@ bool buildPaths(bool checkExistence, std::string* ErrMsg) { for (unsigned i = 0; i < Members.size(); i++) { sys::Path aPath; if (!aPath.set(Members[i])) - throw std::string("File member name invalid: ") + Members[i]; + fail(std::string("File member name invalid: ") + Members[i]); if (checkExistence) { bool Exists; if (sys::fs::exists(aPath.str(), Exists) || !Exists) - throw std::string("File does not exist: ") + Members[i]; + fail(std::string("File does not exist: ") + Members[i]); std::string Err; sys::PathWithStatus PwS(aPath); const sys::FileStatus *si = PwS.getFileStatus(false, &Err); if (!si) - throw Err; + fail(Err); if (si->isDir) { std::set<sys::Path> dirpaths; if (recurseDirectories(aPath, dirpaths, ErrMsg)) @@ -683,6 +703,7 @@ doReplaceOrInsert(std::string* ErrMsg) { // main - main program for llvm-ar .. see comments in the code int main(int argc, char **argv) { + program_name = argv[0]; // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); @@ -698,77 +719,61 @@ int main(int argc, char **argv) { int exitCode = 0; - // Make sure we don't exit with "unhandled exception". - try { - // Do our own parsing of the command line because the CommandLine utility - // can't handle the grouped positional parameters without a dash. - ArchiveOperation Operation = parseCommandLine(); - - // Check the path name of the archive - sys::Path ArchivePath; - if (!ArchivePath.set(ArchiveName)) - throw std::string("Archive name invalid: ") + ArchiveName; - - // Create or open the archive object. - bool Exists; - if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists) { - // Produce a warning if we should and we're creating the archive - if (!Create) - errs() << argv[0] << ": creating " << ArchivePath.str() << "\n"; - TheArchive = Archive::CreateEmpty(ArchivePath, Context); - TheArchive->writeToDisk(); - } else { - std::string Error; - TheArchive = Archive::OpenAndLoad(ArchivePath, Context, &Error); - if (TheArchive == 0) { - errs() << argv[0] << ": error loading '" << ArchivePath.str() << "': " - << Error << "!\n"; - return 1; - } - } + // Do our own parsing of the command line because the CommandLine utility + // can't handle the grouped positional parameters without a dash. + ArchiveOperation Operation = parseCommandLine(); - // Make sure we're not fooling ourselves. - assert(TheArchive && "Unable to instantiate the archive"); - - // Make sure we clean up the archive even on failure. - std::auto_ptr<Archive> AutoArchive(TheArchive); - - // Perform the operation - std::string ErrMsg; - bool haveError = false; - switch (Operation) { - case Print: haveError = doPrint(&ErrMsg); break; - case Delete: haveError = doDelete(&ErrMsg); break; - case Move: haveError = doMove(&ErrMsg); break; - case QuickAppend: haveError = doQuickAppend(&ErrMsg); break; - case ReplaceOrInsert: haveError = doReplaceOrInsert(&ErrMsg); break; - case DisplayTable: haveError = doDisplayTable(&ErrMsg); break; - case Extract: haveError = doExtract(&ErrMsg); break; - case NoOperation: - errs() << argv[0] << ": No operation was selected.\n"; - break; - } - if (haveError) { - errs() << argv[0] << ": " << ErrMsg << "\n"; + // Check the path name of the archive + sys::Path ArchivePath; + if (!ArchivePath.set(ArchiveName)) { + errs() << argv[0] << ": Archive name invalid: " << ArchiveName << "\n"; + return 1; + } + + // Create or open the archive object. + bool Exists; + if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists) { + // Produce a warning if we should and we're creating the archive + if (!Create) + errs() << argv[0] << ": creating " << ArchivePath.str() << "\n"; + TheArchive = Archive::CreateEmpty(ArchivePath, Context); + TheArchive->writeToDisk(); + } else { + std::string Error; + TheArchive = Archive::OpenAndLoad(ArchivePath, Context, &Error); + if (TheArchive == 0) { + errs() << argv[0] << ": error loading '" << ArchivePath.str() << "': " + << Error << "!\n"; return 1; } - } catch (const char*msg) { - // These errors are usage errors, thrown only by the various checks in the - // code above. - errs() << argv[0] << ": " << msg << "\n\n"; - cl::PrintHelpMessage(); - exitCode = 1; - } catch (const std::string& msg) { - // These errors are thrown by LLVM libraries (e.g. lib System) and represent - // a more serious error so we bump the exitCode and don't print the usage. - errs() << argv[0] << ": " << msg << "\n"; - exitCode = 2; - } catch (...) { - // This really shouldn't happen, but just in case .... - errs() << argv[0] << ": An unexpected unknown exception occurred.\n"; - exitCode = 3; } + // Make sure we're not fooling ourselves. + assert(TheArchive && "Unable to instantiate the archive"); + + // Perform the operation + std::string ErrMsg; + bool haveError = false; + switch (Operation) { + case Print: haveError = doPrint(&ErrMsg); break; + case Delete: haveError = doDelete(&ErrMsg); break; + case Move: haveError = doMove(&ErrMsg); break; + case QuickAppend: haveError = doQuickAppend(&ErrMsg); break; + case ReplaceOrInsert: haveError = doReplaceOrInsert(&ErrMsg); break; + case DisplayTable: haveError = doDisplayTable(&ErrMsg); break; + case Extract: haveError = doExtract(&ErrMsg); break; + case NoOperation: + errs() << argv[0] << ": No operation was selected.\n"; + break; + } + if (haveError) { + errs() << argv[0] << ": " << ErrMsg << "\n"; + return 1; + } + + delete TheArchive; + TheArchive = 0; + // Return result code back to operating system. return exitCode; } |