Combine two lines that can be.
[oota-llvm.git] / lib / Support / CommandLine.cpp
index cd903126f5bf85ddf0e7b1093dd837ed19640eb9..e556d76f96580c7e872cd84ae622e69e4404d84d 100644 (file)
 #include "llvm/Config/config.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Streams.h"
 #include "llvm/System/Path.h"
 #include <algorithm>
 #include <functional>
 #include <map>
+#include <ostream>
 #include <set>
-#include <iostream>
 #include <cstdlib>
 #include <cerrno>
 #include <cstring>
@@ -57,8 +58,9 @@ void parser<std::string>::anchor() {}
 
 //===----------------------------------------------------------------------===//
 
-// Globals for name and overview of program
-static std::string ProgramName = "<premain>";
+// Globals for name and overview of program.  Program name is not a string to
+// avoid static ctor/dtor issues.
+static char ProgramName[80] = "<premain>";
 static const char *ProgramOverview = 0;
 
 // This collects additional help to be printed.
@@ -83,8 +85,8 @@ static Option *getOption(const std::string &Str) {
 
 static void AddArgument(const char *ArgName, Option *Opt) {
   if (getOption(ArgName)) {
-    std::cerr << ProgramName << ": CommandLine Error: Argument '"
-              << ArgName << "' defined more than once!\n";
+    cerr << ProgramName << ": CommandLine Error: Argument '"
+         << ArgName << "' defined more than once!\n";
   } else {
     // Add argument to the argument map!
     (*Options)[ArgName] = Opt;
@@ -128,9 +130,9 @@ static inline bool ProvideOption(Option *Handler, const char *ArgName,
   case ValueOptional:
     break;
   default:
-    std::cerr << ProgramName
-              << ": Bad ValueMask flag! CommandLine usage error:"
-              << Handler->getValueExpectedFlag() << "\n";
+    cerr << ProgramName
+         << ": Bad ValueMask flag! CommandLine usage error:"
+         << Handler->getValueExpectedFlag() << "\n";
     abort();
     break;
   }
@@ -303,7 +305,12 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
          "No options specified, or ParseCommandLineOptions called more"
          " than once!");
   sys::Path progname(argv[0]);
-  ProgramName = sys::Path(argv[0]).getLast();
+
+  // Copy the program name into ProgName, making sure not to overflow it.
+  std::string ProgName = sys::Path(argv[0]).getLast();
+  if (ProgName.size() > 79) ProgName.resize(79);
+  strcpy(ProgramName, ProgName.c_str());
+  
   ProgramOverview = Overview;
   bool ErrorParsing = false;
 
@@ -462,8 +469,8 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
     }
 
     if (Handler == 0) {
-      std::cerr << ProgramName << ": Unknown command line argument '"
-                  << argv[i] << "'.  Try: '" << argv[0] << " --help'\n";
+      cerr << ProgramName << ": Unknown command line argument '"
+           << argv[i] << "'.  Try: '" << argv[0] << " --help'\n";
       ErrorParsing = true;
       continue;
     }
@@ -499,18 +506,18 @@ 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";
+    cerr << ProgramName
+         << ": Not enough positional command line arguments specified!\n"
+         << "Must specify at least " << NumPositionalRequired
+         << " positional arguments: See: " << argv[0] << " --help\n";
     
     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";
+    cerr << ProgramName
+         << ": Too many positional arguments specified!\n"
+         << "Can specify at most " << PositionalOpts.size()
+         << " positional arguments: See: " << argv[0] << " --help\n";
     ErrorParsing = true;
 
   } else if (ConsumeAfterOpt == 0) {
@@ -611,11 +618,11 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
 bool Option::error(std::string Message, const char *ArgName) {
   if (ArgName == 0) ArgName = ArgStr;
   if (ArgName[0] == 0)
-    std::cerr << HelpStr;  // Be nice for positional arguments
+    cerr << HelpStr;  // Be nice for positional arguments
   else
-    std::cerr << ProgramName << ": for the -" << ArgName;
+    cerr << ProgramName << ": for the -" << ArgName;
   
-  std::cerr << " option: " << Message << "\n";
+  cerr << " option: " << Message << "\n";
   return true;
 }
 
@@ -695,8 +702,8 @@ unsigned alias::getOptionWidth() const {
 // Print out the option for the alias.
 void alias::printOptionInfo(unsigned GlobalWidth) const {
   unsigned L = std::strlen(ArgStr);
-  std::cout << "  -" << ArgStr << std::string(GlobalWidth-L-6, ' ') << " - "
-            << HelpStr << "\n";
+  cout << "  -" << ArgStr << std::string(GlobalWidth-L-6, ' ') << " - "
+       << HelpStr << "\n";
 }
 
 
@@ -722,13 +729,13 @@ unsigned basic_parser_impl::getOptionWidth(const Option &O) const {
 //
 void basic_parser_impl::printOptionInfo(const Option &O,
                                         unsigned GlobalWidth) const {
-  std::cout << "  -" << O.ArgStr;
+  cout << "  -" << O.ArgStr;
 
   if (const char *ValName = getValueName())
-    std::cout << "=<" << getValueStr(O, ValName) << ">";
+    cout << "=<" << getValueStr(O, ValName) << ">";
 
-  std::cout << std::string(GlobalWidth-getOptionWidth(O), ' ') << " - "
-            << O.HelpStr << "\n";
+  cout << std::string(GlobalWidth-getOptionWidth(O), ' ') << " - "
+       << O.HelpStr << "\n";
 }
 
 
@@ -844,21 +851,21 @@ void generic_parser_base::printOptionInfo(const Option &O,
                                           unsigned GlobalWidth) const {
   if (O.hasArgStr()) {
     unsigned L = std::strlen(O.ArgStr);
-    std::cout << "  -" << O.ArgStr << std::string(GlobalWidth-L-6, ' ')
-              << " - " << O.HelpStr << "\n";
+    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::cout << "    =" << getOption(i) << std::string(NumSpaces, ' ')
-                << " - " << getDescription(i) << "\n";
+      cout << "    =" << getOption(i) << std::string(NumSpaces, ' ')
+           << " - " << getDescription(i) << "\n";
     }
   } else {
     if (O.HelpStr[0])
-      std::cout << "  " << O.HelpStr << "\n";
+      cout << "  " << O.HelpStr << "\n";
     for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
       unsigned L = std::strlen(getOption(i));
-      std::cout << "    -" << getOption(i) << std::string(GlobalWidth-L-8, ' ')
-                << " - " << getDescription(i) << "\n";
+      cout << "    -" << getOption(i) << std::string(GlobalWidth-L-8, ' ')
+           << " - " << getDescription(i) << "\n";
     }
   }
 }
@@ -911,9 +918,9 @@ public:
     }
 
     if (ProgramOverview)
-      std::cout << "OVERVIEW:" << ProgramOverview << "\n";
+      cout << "OVERVIEW:" << ProgramOverview << "\n";
 
-    std::cout << "USAGE: " << ProgramName << " [options]";
+    cout << "USAGE: " << ProgramName << " [options]";
 
     // Print out the positional options.
     std::vector<Option*> &PosOpts = *PositionalOptions;
@@ -923,28 +930,28 @@ public:
 
     for (unsigned i = CAOpt != 0, e = PosOpts.size(); i != e; ++i) {
       if (PosOpts[i]->ArgStr[0])
-        std::cout << " --" << PosOpts[i]->ArgStr;
-      std::cout << " " << PosOpts[i]->HelpStr;
+        cout << " --" << PosOpts[i]->ArgStr;
+      cout << " " << PosOpts[i]->HelpStr;
     }
 
     // Print the consume after option info if it exists...
-    if (CAOpt) std::cout << " " << CAOpt->HelpStr;
+    if (CAOpt) cout << " " << CAOpt->HelpStr;
 
-    std::cout << "\n\n";
+    cout << "\n\n";
 
     // Compute the maximum argument length...
     MaxArgLen = 0;
     for (unsigned i = 0, e = Opts.size(); i != e; ++i)
       MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());
 
-    std::cout << "OPTIONS:\n";
+    cout << "OPTIONS:\n";
     for (unsigned i = 0, e = Opts.size(); i != e; ++i)
       Opts[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::cout << *I;
+      cout << *I;
     MoreHelp->clear();
 
     // Halt the program since help information was printed
@@ -973,24 +980,27 @@ static void (*OverrideVersionPrinter)() = 0;
 namespace {
 class VersionPrinter {
 public:
-  void operator=(bool OptionWasSpecified) {
-    if (OptionWasSpecified) {
-      if (OverrideVersionPrinter == 0) {
-        std::cout << "Low Level Virtual Machine (http://llvm.org/):\n";
-        std::cout << "  " << PACKAGE_NAME << " version " << PACKAGE_VERSION;
+  void print() {
+        cout << "Low Level Virtual Machine (http://llvm.org/):\n";
+        cout << "  " << PACKAGE_NAME << " version " << PACKAGE_VERSION;
 #ifdef LLVM_VERSION_INFO
-        std::cout << LLVM_VERSION_INFO;
+        cout << LLVM_VERSION_INFO;
 #endif
-        std::cout << "\n  ";
+        cout << "\n  ";
 #ifndef __OPTIMIZE__
-        std::cout << "DEBUG build";
+        cout << "DEBUG build";
 #else
-        std::cout << "Optimized build";
+        cout << "Optimized build";
 #endif
 #ifndef NDEBUG
-        std::cout << " with assertions";
+        cout << " with assertions";
 #endif
-        std::cout << ".\n";
+        cout << ".\n";
+  }
+  void operator=(bool OptionWasSpecified) {
+    if (OptionWasSpecified) {
+      if (OverrideVersionPrinter == 0) {
+        print();
         Options->clear();  // Don't bother making option dtors remove from map.
         exit(1);
       } else {
@@ -1021,6 +1031,11 @@ void cl::PrintHelpMessage() {
   NormalPrinter = true;
 }
 
+/// Utility function for printing version number.
+void cl::PrintVersionMessage() {
+  VersionPrinterInstance.print();
+}
+
 void cl::SetVersionPrinter(void (*func)()) {
   OverrideVersionPrinter = func;
 }