//===-- llvm-ar.cpp - LLVM archive librarian utility ----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Builds up (relatively) standard unix archive files (.a) containing LLVM
// bitcode or other files.
//
//===----------------------------------------------------------------------===//

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Bitcode/Archive.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Signals.h"
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <memory>
using namespace llvm;

// Option for compatibility with AIX, not used but must allow it to be present.
static cl::opt<bool>
X32Option ("X32_64", cl::Hidden,
            cl::desc("Ignored option for compatibility with AIX"));

// llvm-ar operation code and modifier flags. This must come first.
static cl::opt<std::string>
Options(cl::Positional, cl::Required, cl::desc("{operation}[modifiers]..."));

// llvm-ar remaining positional arguments.
static cl::list<std::string>
RestOfArgs(cl::Positional, cl::OneOrMore,
    cl::desc("[relpos] [count] <archive-file> [members]..."));

// MoreHelp - Provide additional help output explaining the operations and
// modifiers of llvm-ar. This object instructs the CommandLine library
// to print the text of the constructor when the --help option is given.
static cl::extrahelp MoreHelp(
  "\nOPERATIONS:\n"
  "  d[NsS]       - delete file(s) from the archive\n"
  "  m[abiSs]     - move file(s) in the archive\n"
  "  p[kN]        - print file(s) found in the archive\n"
  "  q[ufsS]      - quick append file(s) to the archive\n"
  "  r[abfiuzRsS] - replace or insert file(s) into the archive\n"
  "  t            - display contents of archive\n"
  "  x[No]        - extract file(s) from the archive\n"
  "\nMODIFIERS (operation specific):\n"
  "  [a] - put file(s) after [relpos]\n"
  "  [b] - put file(s) before [relpos] (same as [i])\n"
  "  [f] - truncate inserted file names\n"
  "  [i] - put file(s) before [relpos] (same as [b])\n"
  "  [k] - always print bitcode files (default is to skip them)\n"
  "  [N] - use instance [count] of name\n"
  "  [o] - preserve original dates\n"
  "  [P] - use full path names when matching\n"
  "  [R] - recurse through directories when inserting\n"
  "  [s] - create an archive index (cf. ranlib)\n"
  "  [S] - do not build a symbol table\n"
  "  [u] - update only files newer than archive contents\n"
  "  [z] - compress files before inserting/extracting\n"
  "\nMODIFIERS (generic):\n"
  "  [c] - do not warn if the library had to be created\n"
  "  [v] - be verbose about actions taken\n"
  "  [V] - be *really* verbose about actions taken\n"
);

// This enumeration delineates the kinds of operations on an archive
// that are permitted.
enum ArchiveOperation {
  NoOperation,      ///< An operation hasn't been specified
  Print,            ///< Print the contents of the archive
  Delete,           ///< Delete the specified members
  Move,             ///< Move members to end or as given by {a,b,i} modifiers
  QuickAppend,      ///< Quickly append to end of archive
  ReplaceOrInsert,  ///< Replace or Insert members
  DisplayTable,     ///< Display the table of contents
  Extract           ///< Extract files back to file system
};

// Modifiers to follow operation to vary behavior
bool AddAfter = false;           ///< 'a' modifier
bool AddBefore = false;          ///< 'b' modifier
bool Create = false;             ///< 'c' modifier
bool TruncateNames = false;      ///< 'f' modifier
bool InsertBefore = false;       ///< 'i' modifier
bool DontSkipBitcode = false;    ///< 'k' modifier
bool UseCount = false;           ///< 'N' modifier
bool OriginalDates = false;      ///< 'o' modifier
bool FullPath = false;           ///< 'P' modifier
bool RecurseDirectories = false; ///< 'R' modifier
bool SymTable = true;            ///< 's' & 'S' modifiers
bool OnlyUpdate = false;         ///< 'u' modifier
bool Verbose = false;            ///< 'v' modifier
bool ReallyVerbose = false;      ///< 'V' modifier
bool Compression = false;        ///< 'z' modifier

// Relative Positional Argument (for insert/move). This variable holds
// the name of the archive member to which the 'a', 'b' or 'i' modifier
// refers. Only one of 'a', 'b' or 'i' can be specified so we only need
// one variable.
std::string RelPos;

// Select which of multiple entries in the archive with the same name should be
// used (specified with -N) for the delete and extract operations.
int Count = 1;

// This variable holds the name of the archive file as given on the
// command line.
std::string ArchiveName;

// This variable holds the list of member files to proecess, as given
// on the command line.
std::vector<std::string> Members;

// This variable holds the (possibly expanded) list of path objects that
// correspond to files we will
std::set<sys::Path> Paths;

// The Archive object to which all the editing operations will be sent.
Archive* TheArchive = 0;

// 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";
}

// 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";

  // Non-positive counts are not allowed
  if (Count < 1)
    throw "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.";
}

// getMembers - Copy over remaining items in RestOfArgs to our Members vector
// This is just for clarity.
void getMembers() {
  if(RestOfArgs.size() > 0)
    Members = std::vector<std::string>(RestOfArgs);
}

// 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.
ArchiveOperation parseCommandLine() {

  // Keep track of number of operations. We can only specify one
  // per execution.
  unsigned NumOperations = 0;

  // Keep track of the number of positional modifiers (a,b,i). Only
  // one can be specified.
  unsigned NumPositional = 0;

  // Keep track of which operation was requested
  ArchiveOperation Operation = NoOperation;

  for(unsigned i=0; i<Options.size(); ++i) {
    switch(Options[i]) {
    case 'd': ++NumOperations; Operation = Delete; break;
    case 'm': ++NumOperations; Operation = Move ; break;
    case 'p': ++NumOperations; Operation = Print; break;
    case 'q': ++NumOperations; Operation = QuickAppend; break;
    case 'r': ++NumOperations; Operation = ReplaceOrInsert; break;
    case 't': ++NumOperations; Operation = DisplayTable; break;
    case 'x': ++NumOperations; Operation = Extract; break;
    case 'c': Create = true; break;
    case 'f': TruncateNames = true; break;
    case 'k': DontSkipBitcode = true; break;
    case 'l': /* accepted but unused */ break;
    case 'o': OriginalDates = true; break;
    case 'P': FullPath = true; break;
    case 'R': RecurseDirectories = true; break;
    case 's': SymTable = true; break;
    case 'S': SymTable = false; break;
    case 'u': OnlyUpdate = true; break;
    case 'v': Verbose = true; break;
    case 'V': Verbose = ReallyVerbose = true; break;
    case 'z': Compression = true; break;
    case 'a':
      getRelPos();
      AddAfter = true;
      NumPositional++;
      break;
    case 'b':
      getRelPos();
      AddBefore = true;
      NumPositional++;
      break;
    case 'i':
      getRelPos();
      InsertBefore = true;
      NumPositional++;
      break;
    case 'N':
      getCount();
      UseCount = true;
      break;
    default:
      cl::PrintHelpMessage();
    }
  }

  // At this point, the next thing on the command line must be
  // the archive name.
  getArchive();

  // Everything on the command line at this point is a member.
  getMembers();

  // 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";
  if (NumOperations > 1)
    throw "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)
    if (Operation != Move && Operation != ReplaceOrInsert)
      throw "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";
  if (OriginalDates && Operation != Extract)
    throw "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";
  if (OnlyUpdate && Operation != ReplaceOrInsert)
    throw "The 'u' modifier is only applicable to the 'r' operation";
  if (Compression && Operation!=ReplaceOrInsert && Operation!=Extract)
    throw "The 'z' modifier is only applicable to the 'r' and 'x' operations";
  if (Count > 1 && Members.size() > 1)
    throw "Only one member name may be specified with the 'N' modifier";

  // Return the parsed operation to the caller
  return Operation;
}

// recurseDirectories - Implements the "R" modifier. This function scans through
// the Paths vector (built by buildPaths, below) and replaces any directories it
// finds with all the files in that directory (recursively). It uses the
// sys::Path::getDirectoryContent method to perform the actual directory scans.
bool
recurseDirectories(const sys::Path& path, 
                   std::set<sys::Path>& result, std::string* ErrMsg) {
  result.clear();
  if (RecurseDirectories) {
    std::set<sys::Path> content;
    if (path.getDirectoryContents(content, ErrMsg))
      return true;

    for (std::set<sys::Path>::iterator I = content.begin(), E = content.end();
         I != E; ++I) {
      // Make sure it exists and is a directory
      sys::PathWithStatus PwS(*I);
      const sys::FileStatus *Status = PwS.getFileStatus(false, ErrMsg);
      if (!Status)
        return true;
      if (Status->isDir) {
        std::set<sys::Path> moreResults;
        if (recurseDirectories(*I, moreResults, ErrMsg))
          return true;
        result.insert(moreResults.begin(), moreResults.end());
      } else {
          result.insert(*I);
      }
    }
  }
  return false;
}

// buildPaths - Convert the strings in the Members vector to sys::Path objects
// and make sure they are valid and exist exist. This check is only needed for
// the operations that add/replace files to the archive ('q' and 'r')
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];
    if (checkExistence) {
      if (!aPath.exists())
        throw 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;
      if (si->isDir) {
        std::set<sys::Path> dirpaths;
        if (recurseDirectories(aPath, dirpaths, ErrMsg))
          return true;
        Paths.insert(dirpaths.begin(),dirpaths.end());
      } else {
        Paths.insert(aPath);
      }
    } else {
      Paths.insert(aPath);
    }
  }
  return false;
}

// printSymbolTable - print out the archive's symbol table.
void printSymbolTable() {
  std::cout << "\nArchive Symbol Table:\n";
  const Archive::SymTabType& symtab = TheArchive->getSymbolTable();
  for (Archive::SymTabType::const_iterator I=symtab.begin(), E=symtab.end();
       I != E; ++I ) {
    unsigned offset = TheArchive->getFirstFileOffset() + I->second;
    std::cout << " " << std::setw(9) << offset << "\t" << I->first <<"\n";
  }
}

// doPrint - Implements the 'p' operation. This function traverses the archive
// looking for members that match the path list. It is careful to uncompress
// things that should be and to skip bitcode files unless the 'k' modifier was
// given.
bool doPrint(std::string* ErrMsg) {
  if (buildPaths(false, ErrMsg))
    return true;
  unsigned countDown = Count;
  for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
       I != E; ++I ) {
    if (Paths.empty() ||
        (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) {
      if (countDown == 1) {
        const char* data = reinterpret_cast<const char*>(I->getData());

        // Skip things that don't make sense to print
        if (I->isLLVMSymbolTable() || I->isSVR4SymbolTable() ||
            I->isBSD4SymbolTable() || (!DontSkipBitcode && I->isBitcode()))
          continue;

        if (Verbose)
          std::cout << "Printing " << I->getPath().toString() << "\n";

        unsigned len = I->getSize();
        std::cout.write(data, len);
      } else {
        countDown--;
      }
    }
  }
  return false;
}

// putMode - utility function for printing out the file mode when the 't'
// operation is in verbose mode.
void 
printMode(unsigned mode) {
  if (mode & 004)
    std::cout << "r";
  else
    std::cout << "-";
  if (mode & 002)
    std::cout << "w";
  else
    std::cout << "-";
  if (mode & 001)
    std::cout << "x";
  else
    std::cout << "-";
}

// doDisplayTable - Implement the 't' operation. This function prints out just
// the file names of each of the members. However, if verbose mode is requested
// ('v' modifier) then the file type, permission mode, user, group, size, and
// modification time are also printed.
bool 
doDisplayTable(std::string* ErrMsg) {
  if (buildPaths(false, ErrMsg))
    return true;
  for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
       I != E; ++I ) {
    if (Paths.empty() ||
        (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) {
      if (Verbose) {
        // FIXME: Output should be this format:
        // Zrw-r--r--  500/ 500    525 Nov  8 17:42 2004 Makefile
        if (I->isBitcode())
          std::cout << "b";
        else if (I->isCompressed())
          std::cout << "Z";
        else
          std::cout << " ";
        unsigned mode = I->getMode();
        printMode((mode >> 6) & 007);
        printMode((mode >> 3) & 007);
        printMode(mode & 007);
        std::cout << " " << std::setw(4) << I->getUser();
        std::cout << "/" << std::setw(4) << I->getGroup();
        std::cout << " " << std::setw(8) << I->getSize();
        std::cout << " " << std::setw(20) <<
          I->getModTime().toString().substr(4);
        std::cout << " " << I->getPath().toString() << "\n";
      } else {
        std::cout << I->getPath().toString() << "\n";
      }
    }
  }
  if (ReallyVerbose)
    printSymbolTable();
  return false;
}

// doExtract - Implement the 'x' operation. This function extracts files back to
// the file system, making sure to uncompress any that were compressed
bool 
doExtract(std::string* ErrMsg) {
  if (buildPaths(false, ErrMsg))
    return true;
  for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
       I != E; ++I ) {
    if (Paths.empty() ||
        (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) {

      // Make sure the intervening directories are created
      if (I->hasPath()) {
        sys::Path dirs(I->getPath());
        dirs.eraseComponent();
        if (dirs.createDirectoryOnDisk(/*create_parents=*/true, ErrMsg)) 
          return true;
      }

      // Open up a file stream for writing
      std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
                                   std::ios::binary;
      std::ofstream file(I->getPath().c_str(), io_mode);

      // Get the data and its length
      const char* data = reinterpret_cast<const char*>(I->getData());
      unsigned len = I->getSize();

      // Write the data.
      file.write(data,len);
      file.close();

      // If we're supposed to retain the original modification times, etc. do so
      // now.
      if (OriginalDates)
        I->getPath().setStatusInfoOnDisk(I->getFileStatus());
    }
  }
  return false;
}

// doDelete - Implement the delete operation. This function deletes zero or more
// members from the archive. Note that if the count is specified, there should
// be no more than one path in the Paths list or else this algorithm breaks.
// That check is enforced in parseCommandLine (above).
bool 
doDelete(std::string* ErrMsg) {
  if (buildPaths(false, ErrMsg))
    return true;
  if (Paths.empty()) 
    return false;
  unsigned countDown = Count;
  for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
       I != E; ) {
    if (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end()) {
      if (countDown == 1) {
        Archive::iterator J = I;
        ++I;
        TheArchive->erase(J);
      } else
        countDown--;
    } else {
      ++I;
    }
  }

  // We're done editting, reconstruct the archive.
  if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
    return true;
  if (ReallyVerbose)
    printSymbolTable();
  return false;
}

// doMore - Implement the move operation. This function re-arranges just the
// order of the archive members so that when the archive is written the move
// of the members is accomplished. Note the use of the RelPos variable to
// determine where the items should be moved to.
bool 
doMove(std::string* ErrMsg) {
  if (buildPaths(false, ErrMsg)) 
    return true;

  // By default and convention the place to move members to is the end of the
  // archive.
  Archive::iterator moveto_spot = TheArchive->end();

  // However, if the relative positioning modifiers were used, we need to scan
  // the archive to find the member in question. If we don't find it, its no
  // crime, we just move to the end.
  if (AddBefore || InsertBefore || AddAfter) {
    for (Archive::iterator I = TheArchive->begin(), E= TheArchive->end();
         I != E; ++I ) {
      if (RelPos == I->getPath().toString()) {
        if (AddAfter) {
          moveto_spot = I;
          moveto_spot++;
        } else {
          moveto_spot = I;
        }
        break;
      }
    }
  }

  // Keep a list of the paths remaining to be moved
  std::set<sys::Path> remaining(Paths);

  // Scan the archive again, this time looking for the members to move to the
  // moveto_spot.
  for (Archive::iterator I = TheArchive->begin(), E= TheArchive->end();
       I != E && !remaining.empty(); ++I ) {
    std::set<sys::Path>::iterator found =
      std::find(remaining.begin(),remaining.end(),I->getPath());
    if (found != remaining.end()) {
      if (I != moveto_spot)
        TheArchive->splice(moveto_spot,*TheArchive,I);
      remaining.erase(found);
    }
  }

  // We're done editting, reconstruct the archive.
  if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
    return true;
  if (ReallyVerbose)
    printSymbolTable();
  return false;
}

// doQuickAppend - Implements the 'q' operation. This function just
// indiscriminantly adds the members to the archive and rebuilds it.
bool 
doQuickAppend(std::string* ErrMsg) {
  // Get the list of paths to append.
  if (buildPaths(true, ErrMsg))
    return true;
  if (Paths.empty()) 
    return false;

  // Append them quickly.
  for (std::set<sys::Path>::iterator PI = Paths.begin(), PE = Paths.end();
       PI != PE; ++PI) {
    if (TheArchive->addFileBefore(*PI,TheArchive->end(),ErrMsg))
      return true;
  }

  // We're done editting, reconstruct the archive.
  if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
    return true;
  if (ReallyVerbose)
    printSymbolTable();
  return false;
}

// doReplaceOrInsert - Implements the 'r' operation. This function will replace
// any existing files or insert new ones into the archive.
bool 
doReplaceOrInsert(std::string* ErrMsg) {

  // Build the list of files to be added/replaced.
  if (buildPaths(true, ErrMsg))
    return true;
  if (Paths.empty()) 
    return false;

  // Keep track of the paths that remain to be inserted.
  std::set<sys::Path> remaining(Paths);

  // Default the insertion spot to the end of the archive
  Archive::iterator insert_spot = TheArchive->end();

  // Iterate over the archive contents
  for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
       I != E && !remaining.empty(); ++I ) {

    // Determine if this archive member matches one of the paths we're trying
    // to replace.

    std::set<sys::Path>::iterator found = remaining.end();
    for (std::set<sys::Path>::iterator RI = remaining.begin(),
         RE = remaining.end(); RI != RE; ++RI ) {
      std::string compare(RI->toString());
      if (TruncateNames && compare.length() > 15) {
        const char* nm = compare.c_str();
        unsigned len = compare.length();
        size_t slashpos = compare.rfind('/');
        if (slashpos != std::string::npos) {
          nm += slashpos + 1;
          len -= slashpos +1;
        }
        if (len > 15)
          len = 15;
        compare.assign(nm,len);
      }
      if (compare == I->getPath().toString()) {
        found = RI;
        break;
      }
    }

    if (found != remaining.end()) {
      std::string Err;
      sys::PathWithStatus PwS(*found); 
      const sys::FileStatus *si = PwS.getFileStatus(false, &Err);
      if (!si)
        return true;
      if (!si->isDir) {
        if (OnlyUpdate) {
          // Replace the item only if it is newer.
          if (si->modTime > I->getModTime())
            if (I->replaceWith(*found, ErrMsg))
              return true;
        } else {
          // Replace the item regardless of time stamp
          if (I->replaceWith(*found, ErrMsg))
            return true;
        }
      } else {
        // We purposefully ignore directories.
      }

      // Remove it from our "to do" list
      remaining.erase(found);
    }

    // Determine if this is the place where we should insert
    if ((AddBefore || InsertBefore) && (RelPos == I->getPath().toString()))
      insert_spot = I;
    else if (AddAfter && (RelPos == I->getPath().toString())) {
      insert_spot = I;
      insert_spot++;
    }
  }

  // If we didn't replace all the members, some will remain and need to be
  // inserted at the previously computed insert-spot.
  if (!remaining.empty()) {
    for (std::set<sys::Path>::iterator PI = remaining.begin(),
         PE = remaining.end(); PI != PE; ++PI) {
      if (TheArchive->addFileBefore(*PI,insert_spot, ErrMsg))
        return true;
    }
  }

  // We're done editting, reconstruct the archive.
  if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
    return true;
  if (ReallyVerbose)
    printSymbolTable();
  return false;
}

// main - main program for llvm-ar .. see comments in the code
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Have the command line options parsed and handle things
  // like --help and --version.
  cl::ParseCommandLineOptions(argc, argv,
    "LLVM Archiver (llvm-ar)\n\n"
    "  This program archives bitcode files into single libraries\n"
  );

  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.
    if (!ArchivePath.exists()) {
      // Produce a warning if we should and we're creating the archive
      if (!Create)
        errs() << argv[0] << ": creating " << ArchivePath.toString() << "\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 << "': "
               << Error << "!\n";
        return 1;
      }
    }

    // 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";
      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;
  }

  // Return result code back to operating system.
  return exitCode;
}
