Use size_t instead of long to represent memory usage. long is 32 bits
[oota-llvm.git] / lib / Support / CommandLine.cpp
index 2337e2e25581b1f8d1e8beb66f86fc6ac3984efe..52e4bbded0299678ef72616bf3dae8fe95dd53a0 100644 (file)
@@ -16,7 +16,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Support/CommandLine.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/CommandLine.h"
 #include <algorithm>
 #include <map>
 #include <set>
@@ -28,6 +29,21 @@ using namespace llvm;
 
 using namespace cl;
 
+// Globals for name and overview of program
+static const char *ProgramName = "<unknown>";
+static const char *ProgramOverview = 0;
+
+// This collects additional help to be printed.
+static std::vector<const char*> &MoreHelp() {
+  static std::vector<const char*> moreHelp;
+  return moreHelp;
+}
+
+extrahelp::extrahelp(const char* Help)
+  : morehelp(Help) {
+  MoreHelp().push_back(Help);
+}
+
 //===----------------------------------------------------------------------===//
 // Basic, shared command line option processing machinery...
 //
@@ -35,29 +51,25 @@ using namespace cl;
 // Return the global command line option vector.  Making it a function scoped
 // static ensures that it will be initialized correctly before its first use.
 //
-static std::map<std::string, Option*> *CommandLineOptions = 0;
 static std::map<std::string, Option*> &getOpts() {
-  if (CommandLineOptions == 0)
-    CommandLineOptions = new std::map<std::string,Option*>();
-  return *CommandLineOptions;
+  static std::map<std::string, Option*> CommandLineOptions;
+  return CommandLineOptions;
 }
 
 static Option *getOption(const std::string &Str) {
-  if (CommandLineOptions == 0) return 0;
-  std::map<std::string,Option*>::iterator I = CommandLineOptions->find(Str);
-  return I != CommandLineOptions->end() ? I->second : 0;
+  std::map<std::string,Option*>::iterator I = getOpts().find(Str);
+  return I != getOpts().end() ? I->second : 0;
 }
 
 static std::vector<Option*> &getPositionalOpts() {
-  static std::vector<Option*> *Positional = 0;
-  if (!Positional) Positional = new std::vector<Option*>();
-  return *Positional;
+  static std::vector<Option*> Positional;
+  return Positional;
 }
 
 static void AddArgument(const char *ArgName, Option *Opt) {
   if (getOption(ArgName)) {
-    std::cerr << "CommandLine Error: Argument '" << ArgName
-              << "' defined more than once!\n";
+    std::cerr << ProgramName << ": CommandLine Error: Argument '" 
+              << ArgName << "' defined more than once!\n";
   } else {
     // Add argument to the argument map!
     getOpts()[ArgName] = Opt;
@@ -68,17 +80,16 @@ static void AddArgument(const char *ArgName, Option *Opt) {
 // options have already been processed and the map has been deleted!
 // 
 static void RemoveArgument(const char *ArgName, Option *Opt) {
-  if (CommandLineOptions == 0) return;
-  assert(getOption(ArgName) == Opt && "Arg not in map!");
-  CommandLineOptions->erase(ArgName);
-  if (CommandLineOptions->empty()) {
-    delete CommandLineOptions;
-    CommandLineOptions = 0;
-  }
-}
+  if(getOpts().empty()) return;
 
-static const char *ProgramName = 0;
-static const char *ProgramOverview = 0;
+#ifndef NDEBUG
+  // This disgusting HACK is brought to you courtesy of GCC 3.3.2, which ICE's
+  // If we pass ArgName directly into getOption here.
+  std::string Tmp = ArgName;
+  assert(getOption(Tmp) == Opt && "Arg not in map!");
+#endif
+  getOpts().erase(ArgName);
+}
 
 static inline bool ProvideOption(Option *Handler, const char *ArgName,
                                  const char *Value, int argc, char **argv,
@@ -99,17 +110,23 @@ static inline bool ProvideOption(Option *Handler, const char *ArgName,
       return Handler->error(" does not allow a value! '" + 
                             std::string(Value) + "' specified.");
     break;
-  case ValueOptional: break;
-  default: std::cerr << "Bad ValueMask flag! CommandLine usage error:" 
-                     << Handler->getValueExpectedFlag() << "\n"; abort();
+  case ValueOptional: 
+    break;
+  default: 
+    std::cerr << ProgramName 
+              << ": Bad ValueMask flag! CommandLine usage error:" 
+              << Handler->getValueExpectedFlag() << "\n"; 
+    abort();
+    break;
   }
 
   // Run the handler now!
-  return Handler->addOccurrence(ArgName, Value);
+  return Handler->addOccurrence(i, ArgName, Value);
 }
 
-static bool ProvidePositionalOption(Option *Handler, const std::string &Arg) {
-  int Dummy;
+static bool ProvidePositionalOption(Option *Handler, const std::string &Arg, 
+                                    int i) {
+  int Dummy = i;
   return ProvideOption(Handler, Handler->ArgStr, Arg.c_str(), 0, 0, Dummy);
 }
 
@@ -171,7 +188,7 @@ static bool EatsUnboundedNumberOfValues(const Option *O) {
 /// them later.
 ///
 static void ParseCStringVector (std::vector<char *> &output,
-                               const char *input) {
+                                const char *input) {
   // Characters which will be treated as token separators:
   static const char *delims = " \v\f\t\r\n";
 
@@ -317,10 +334,10 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
     }
   }
 
-  // PositionalVals - A vector of "positional" arguments we accumulate into to
-  // processes at the end...
+  // PositionalVals - A vector of "positional" arguments we accumulate into
+  // the process at the end...
   //
-  std::vector<std::string> PositionalVals;
+  std::vector<std::pair<std::string,unsigned> > PositionalVals;
 
   // If the program has named positional arguments, and the name has been run
   // across, keep track of which positional argument was named.  Otherwise put
@@ -341,10 +358,10 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
     if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) {
       // Positional argument!
       if (ActivePositionalArg) {
-        ProvidePositionalOption(ActivePositionalArg, argv[i]);
+        ProvidePositionalOption(ActivePositionalArg, argv[i], i);
         continue;  // We are done!
       } else if (!PositionalOpts.empty()) {
-        PositionalVals.push_back(argv[i]);
+        PositionalVals.push_back(std::make_pair(argv[i],i));
 
         // All of the positional arguments have been fulfulled, give the rest to
         // the consume after option... if it's specified...
@@ -352,7 +369,7 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
         if (PositionalVals.size() >= NumPositionalRequired && 
             ConsumeAfterOpt != 0) {
           for (++i; i < argc; ++i)
-            PositionalVals.push_back(argv[i]);
+            PositionalVals.push_back(std::make_pair(argv[i],i));
           break;   // Handle outside of the argument processing loop...
         }
 
@@ -371,7 +388,7 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
       ArgName = argv[i]+1;
       Handler = LookupOption(ArgName, Value);
       if (!Handler || Handler->getFormattingFlag() != cl::Positional) {
-        ProvidePositionalOption(ActivePositionalArg, argv[i]);
+        ProvidePositionalOption(ActivePositionalArg, argv[i], i);
         continue;  // We are done!
       }
 
@@ -380,7 +397,7 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
       Handler = LookupOption(ArgName, Value);
 
       // Check to see if this "option" is really a prefixed or grouped argument.
-      if (Handler == 0 && *Value == 0) {
+      if (Handler == 0) {
         std::string RealName(ArgName);
         if (RealName.size() > 1) {
           unsigned Length = 0;
@@ -425,8 +442,8 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
     }
 
     if (Handler == 0) {
-      std::cerr << "Unknown command line argument '" << argv[i] << "'.  Try: '"
-                << argv[0] << " --help'\n";
+      std::cerr << ProgramName << ": Unknown command line argument '" << argv[i]
+                << "'.  Try: '" << argv[0] << " --help'\n";
       ErrorParsing = true;
       continue;
     }
@@ -462,7 +479,8 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
 
   // Check and handle positional arguments now...
   if (NumPositionalRequired > PositionalVals.size()) {
-    std::cerr << "Not enough positional command line arguments specified!\n"
+    std::cerr << ProgramName 
+              << ": Not enough positional command line arguments specified!\n"
               << "Must specify at least " << NumPositionalRequired
               << " positional arguments: See: " << argv[0] << " --help\n";
     ErrorParsing = true;
@@ -473,7 +491,9 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
     unsigned ValNo = 0, NumVals = PositionalVals.size();
     for (unsigned i = 0, e = PositionalOpts.size(); i != e; ++i) {
       if (RequiresValue(PositionalOpts[i])) {
-        ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo++]);
+        ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo].first, 
+                                PositionalVals[ValNo].second);
+        ValNo++;
         --NumPositionalRequired;  // We fulfilled our duty...
       }
 
@@ -489,7 +509,10 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
           // FALL THROUGH
         case cl::ZeroOrMore:    // Zero or more will take all they can get...
         case cl::OneOrMore:     // One or more will take all they can get...
-          ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo++]);
+          ProvidePositionalOption(PositionalOpts[i],
+                                  PositionalVals[ValNo].first,
+                                  PositionalVals[ValNo].second);
+          ValNo++;
           break;
         default:
           assert(0 && "Internal error, unexpected NumOccurrences flag in "
@@ -501,24 +524,31 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
     assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size());
     unsigned ValNo = 0;
     for (unsigned j = 1, e = PositionalOpts.size(); j != e; ++j)
-      if (RequiresValue(PositionalOpts[j]))
+      if (RequiresValue(PositionalOpts[j])) {
         ErrorParsing |= ProvidePositionalOption(PositionalOpts[j],
-                                                PositionalVals[ValNo++]);
+                                                PositionalVals[ValNo].first,
+                                                PositionalVals[ValNo].second);
+        ValNo++;
+      }
 
     // Handle the case where there is just one positional option, and it's
     // optional.  In this case, we want to give JUST THE FIRST option to the
     // positional option and keep the rest for the consume after.  The above
     // loop would have assigned no values to positional options in this case.
     //
-    if (PositionalOpts.size() == 2 && ValNo == 0 && !PositionalVals.empty())
+    if (PositionalOpts.size() == 2 && ValNo == 0 && !PositionalVals.empty()) {
       ErrorParsing |= ProvidePositionalOption(PositionalOpts[1],
-                                              PositionalVals[ValNo++]);
+                                              PositionalVals[ValNo].first,
+                                              PositionalVals[ValNo].second);
+      ValNo++;
+    }
     
     // Handle over all of the rest of the arguments to the
     // cl::ConsumeAfter command line option...
     for (; ValNo != PositionalVals.size(); ++ValNo)
       ErrorParsing |= ProvidePositionalOption(ConsumeAfterOpt,
-                                              PositionalVals[ValNo]);
+                                              PositionalVals[ValNo].first,
+                                              PositionalVals[ValNo].second);
   }
 
   // Loop over args and make sure all required args are specified!
@@ -539,9 +569,9 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
 
   // Free all of the memory allocated to the map.  Command line options may only
   // be processed once!
-  delete CommandLineOptions;
-  CommandLineOptions = 0;
+  getOpts().clear();
   PositionalOpts.clear();
+  MoreHelp().clear();
 
   // If we had an error processing our arguments, don't let the program execute
   if (ErrorParsing) exit(1);
@@ -556,12 +586,12 @@ bool Option::error(std::string Message, const char *ArgName) {
   if (ArgName[0] == 0)
     std::cerr << HelpStr;  // Be nice for positional arguments
   else
-    std::cerr << "-" << ArgName;
-  std::cerr << " option" << Message << "\n";
+    std::cerr << ProgramName << ": for the -" << ArgName;
+  std::cerr << " option" << Message << "\n";
   return true;
 }
 
-bool Option::addOccurrence(const char *ArgName, const std::string &Value) {
+bool Option::addOccurrence(unsigned pos, const char *ArgName, const std::string &Value) {
   NumOccurrences++;   // Increment the number of times we have been seen
 
   switch (getNumOccurrencesFlag()) {
@@ -579,7 +609,7 @@ bool Option::addOccurrence(const char *ArgName, const std::string &Value) {
   default: return error(": bad num occurrences flag value!");
   }
 
-  return handleOccurrence(ArgName, Value);
+  return handleOccurrence(pos, ArgName, Value);
 }
 
 // addArgument - Tell the system that this Option subclass will handle all
@@ -808,6 +838,7 @@ void generic_parser_base::printOptionInfo(const Option &O,
 //===----------------------------------------------------------------------===//
 // --help and --help-hidden option implementation
 //
+
 namespace {
 
 class HelpPrinter {
@@ -881,11 +912,27 @@ public:
     for (unsigned i = 0, e = Options.size(); i != e; ++i)
       Options[i].second->printOptionInfo(MaxArgLen);
 
-    // Halt the program if help information is printed
+    // 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;
+    MoreHelp().clear();
+
+    // Halt the program since help information was printed
     exit(1);
   }
 };
 
+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";
+      exit(1);
+    }
+  }
+};
 
 
 // Define the two HelpPrinter instances that are used to print out help, or
@@ -902,4 +949,22 @@ cl::opt<HelpPrinter, true, parser<bool> >
 HHOp("help-hidden", cl::desc("display all available options"),
      cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed);
 
+// Define the --version option that prints out the LLVM version for the tool
+VersionPrinter VersionPrinterInstance;
+cl::opt<VersionPrinter, true, parser<bool> >
+VersOp("version", cl::desc("display the version"), 
+    cl::location(VersionPrinterInstance), cl::ValueDisallowed);
+
+
 } // End anonymous namespace
+
+// Utility function for printing the help message.
+void cl::PrintHelpMessage() {
+  // This looks weird, but it actually prints the help message. The 
+  // NormalPrinter variable is a HelpPrinter and the help gets printed when
+  // its operator= is invoked. That's because the "normal" usages of the
+  // help printer is to be assigned true/false depending on whether the 
+  // --help option was given or not. Since we're circumventing that we have
+  // to make it look like --help was given, so we assign true.
+  NormalPrinter = true;
+}