Make it possible to override the standard version printer. Not all tools
[oota-llvm.git] / lib / Support / CommandLine.cpp
index 09038d3a5f3826e2dd0844c44550ffd3a8cbd8cc..4b3a1d8f7d2670f9f1cb51a69a4b16fa70720abb 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/Config/config.h"
 #include "llvm/Support/CommandLine.h"
 #include <algorithm>
+#include <functional>
 #include <map>
 #include <set>
 #include <iostream>
@@ -335,11 +336,8 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
                                    " does not require a value!");
       }
       UnboundedFound |= EatsUnboundedNumberOfValues(Opt);
-      
-      if (Opt->getNumOccurrencesFlag() == cl::ZeroOrMore
-          || Opt->getNumOccurrencesFlag() == cl::OneOrMore)
-          HasUnlimitedPositionals = true;
     }
+    HasUnlimitedPositionals = UnboundedFound || ConsumeAfterOpt;
   }
 
   // PositionalVals - A vector of "positional" arguments we accumulate into
@@ -450,8 +448,11 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
     }
 
     if (Handler == 0) {
-      std::cerr << ProgramName << ": Unknown command line argument '" << argv[i]
-                << "'.  Try: '" << argv[0] << " --help'\n";
+      if (ProgramName)
+        std::cerr << ProgramName << ": Unknown command line argument '"
+                  << argv[i] << "'.  Try: '" << argv[0] << " --help'\n";
+      else
+        std::cerr << "Unknown command line argument '" << argv[i] << "'.\n";
       ErrorParsing = true;
       continue;
     }
@@ -487,17 +488,28 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
 
   // Check and handle positional arguments now...
   if (NumPositionalRequired > PositionalVals.size()) {
-    std::cerr << ProgramName
-              << ": Not enough positional command line arguments specified!\n"
-              << "Must specify at least " << NumPositionalRequired
-              << " positional arguments: See: " << argv[0] << " --help\n";
+    if (ProgramName)
+      std::cerr << ProgramName
+                << ": Not enough positional command line arguments specified!\n"
+                << "Must specify at least " << NumPositionalRequired
+                << " positional arguments: See: " << argv[0] << " --help\n";
+    else
+      std::cerr << "Not enough positional command line arguments specified!\n"
+                << "Must specify at least " << NumPositionalRequired
+                << " positional arguments.";
+    
     ErrorParsing = true;
   } else if (!HasUnlimitedPositionals
              && PositionalVals.size() > PositionalOpts.size()) {
-    std::cerr << ProgramName
-              << ": Too many positional arguments specified!\n"
-              << "Can specify at most " << PositionalOpts.size()
-              << " positional arguments: See: " << argv[0] << " --help\n";
+    if (ProgramName)
+      std::cerr << ProgramName
+                << ": Too many positional arguments specified!\n"
+                << "Can specify at most " << PositionalOpts.size()
+                << " positional arguments: See: " << argv[0] << " --help\n";
+    else
+      std::cerr << "Too many positional arguments specified!\n"
+                << "Can specify at most " << PositionalOpts.size()
+                << " positional arguments.\n";
     ErrorParsing = true;
 
   } else if (ConsumeAfterOpt == 0) {
@@ -678,10 +690,10 @@ unsigned alias::getOptionWidth() const {
   return std::strlen(ArgStr)+6;
 }
 
-// Print out the option for the alias...
+// Print out the option for the alias.
 void alias::printOptionInfo(unsigned GlobalWidth) const {
   unsigned L = std::strlen(ArgStr);
-  std::cerr << "  -" << ArgStr << std::string(GlobalWidth-L-6, ' ') << " - "
+  std::cout << "  -" << ArgStr << std::string(GlobalWidth-L-6, ' ') << " - "
             << HelpStr << "\n";
 }
 
@@ -708,12 +720,12 @@ unsigned basic_parser_impl::getOptionWidth(const Option &O) const {
 //
 void basic_parser_impl::printOptionInfo(const Option &O,
                                         unsigned GlobalWidth) const {
-  std::cerr << "  -" << O.ArgStr;
+  std::cout << "  -" << O.ArgStr;
 
   if (const char *ValName = getValueName())
-    std::cerr << "=<" << getValueStr(O, ValName) << ">";
+    std::cout << "=<" << getValueStr(O, ValName) << ">";
 
-  std::cerr << std::string(GlobalWidth-getOptionWidth(O), ' ') << " - "
+  std::cout << std::string(GlobalWidth-getOptionWidth(O), ' ') << " - "
             << O.HelpStr << "\n";
 }
 
@@ -830,20 +842,20 @@ void generic_parser_base::printOptionInfo(const Option &O,
                                           unsigned GlobalWidth) const {
   if (O.hasArgStr()) {
     unsigned L = std::strlen(O.ArgStr);
-    std::cerr << "  -" << O.ArgStr << std::string(GlobalWidth-L-6, ' ')
+    std::cout << "  -" << O.ArgStr << std::string(GlobalWidth-L-6, ' ')
               << " - " << O.HelpStr << "\n";
 
     for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
       unsigned NumSpaces = GlobalWidth-strlen(getOption(i))-8;
-      std::cerr << "    =" << getOption(i) << std::string(NumSpaces, ' ')
+      std::cout << "    =" << getOption(i) << std::string(NumSpaces, ' ')
                 << " - " << getDescription(i) << "\n";
     }
   } else {
     if (O.HelpStr[0])
-      std::cerr << "  " << O.HelpStr << "\n";
+      std::cout << "  " << O.HelpStr << "\n";
     for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
       unsigned L = std::strlen(getOption(i));
-      std::cerr << "    -" << getOption(i) << std::string(GlobalWidth-L-8, ' ')
+      std::cout << "    -" << getOption(i) << std::string(GlobalWidth-L-8, ' ')
                 << " - " << getDescription(i) << "\n";
     }
   }
@@ -897,9 +909,9 @@ public:
     }
 
     if (ProgramOverview)
-      std::cerr << "OVERVIEW:" << ProgramOverview << "\n";
+      std::cout << "OVERVIEW:" << ProgramOverview << "\n";
 
-    std::cerr << "USAGE: " << ProgramName << " [options]";
+    std::cout << "USAGE: " << ProgramName << " [options]";
 
     // Print out the positional options...
     std::vector<Option*> &PosOpts = getPositionalOpts();
@@ -909,28 +921,28 @@ public:
 
     for (unsigned i = CAOpt != 0, e = PosOpts.size(); i != e; ++i) {
       if (PosOpts[i]->ArgStr[0])
-        std::cerr << " --" << PosOpts[i]->ArgStr;
-      std::cerr << " " << PosOpts[i]->HelpStr;
+        std::cout << " --" << PosOpts[i]->ArgStr;
+      std::cout << " " << PosOpts[i]->HelpStr;
     }
 
     // Print the consume after option info if it exists...
-    if (CAOpt) std::cerr << " " << CAOpt->HelpStr;
+    if (CAOpt) std::cout << " " << CAOpt->HelpStr;
 
-    std::cerr << "\n\n";
+    std::cout << "\n\n";
 
     // Compute the maximum argument length...
     MaxArgLen = 0;
     for (unsigned i = 0, e = Options.size(); i != e; ++i)
       MaxArgLen = std::max(MaxArgLen, Options[i].second->getOptionWidth());
 
-    std::cerr << "OPTIONS:\n";
+    std::cout << "OPTIONS:\n";
     for (unsigned i = 0, e = Options.size(); i != e; ++i)
       Options[i].second->printOptionInfo(MaxArgLen);
 
     // Print any extra help the user has declared.
     for (std::vector<const char *>::iterator I = MoreHelp().begin(),
           E = MoreHelp().end(); I != E; ++I)
-      std::cerr << *I;
+      std::cout << *I;
     MoreHelp().clear();
 
     // Halt the program since help information was printed
@@ -939,19 +951,6 @@ public:
   }
 };
 
-class VersionPrinter {
-public:
-  void operator=(bool OptionWasSpecified) {
-    if (OptionWasSpecified) {
-      std::cerr << "Low Level Virtual Machine (" << PACKAGE_NAME << ") "
-                << PACKAGE_VERSION << " (see http://llvm.cs.uiuc.edu/)\n";
-      getOpts().clear();  // Don't bother making option dtors remove from map.
-      exit(1);
-    }
-  }
-};
-
-
 // Define the two HelpPrinter instances that are used to print out help, or
 // help-hidden...
 //
@@ -966,6 +965,31 @@ cl::opt<HelpPrinter, true, parser<bool> >
 HHOp("help-hidden", cl::desc("Display all available options"),
      cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed);
 
+void (*OverrideVersionPrinter)() = 0;
+
+class VersionPrinter {
+public:
+  void operator=(bool OptionWasSpecified) {
+    if (OptionWasSpecified) {
+      if (OverrideVersionPrinter == 0) {
+        std::cout << "Low Level Virtual Machine (" << PACKAGE_NAME << ") "
+                  << PACKAGE_VERSION << " (see http://llvm.org/)";
+#ifndef NDEBUG
+        std::cout << " ASSERTIONS ENABLED\n";
+#else
+        std::cout << "\n";
+#endif
+        getOpts().clear();  // Don't bother making option dtors remove from map.
+        exit(1);
+      } else {
+        (*OverrideVersionPrinter)();
+        exit(1);
+      }
+    }
+  }
+};
+
+
 // Define the --version option that prints out the LLVM version for the tool
 VersionPrinter VersionPrinterInstance;
 cl::opt<VersionPrinter, true, parser<bool> >
@@ -985,3 +1009,7 @@ void cl::PrintHelpMessage() {
   // to make it look like --help was given, so we assign true.
   NormalPrinter = true;
 }
+
+void cl::SetVersionPrinter(void (*func)()) {
+  OverrideVersionPrinter = func;
+}