Use size_t instead of long to represent memory usage. long is 32 bits
[oota-llvm.git] / lib / Support / CommandLine.cpp
index ad82c849479fec57c82aec0b37f224d5391f9271..52e4bbded0299678ef72616bf3dae8fe95dd53a0 100644 (file)
@@ -33,6 +33,17 @@ using namespace cl;
 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...
 //
@@ -40,23 +51,19 @@ static const char *ProgramOverview = 0;
 // 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) {
@@ -73,18 +80,15 @@ 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;
+  if(getOpts().empty()) return;
+
 #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
-  CommandLineOptions->erase(ArgName);
-  if (CommandLineOptions->empty()) {
-    delete CommandLineOptions;
-    CommandLineOptions = 0;
-  }
+  getOpts().erase(ArgName);
 }
 
 static inline bool ProvideOption(Option *Handler, const char *ArgName,
@@ -393,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;
@@ -565,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);
@@ -835,11 +839,6 @@ void generic_parser_base::printOptionInfo(const Option &O,
 // --help and --help-hidden option implementation
 //
 
-// If this variable is set, it is a pointer to a function that the user wants
-// us to call after we print out the help info. Basically a hook to allow
-// additional help to be printed.
-void (*cl::MoreHelp)() = 0;
-
 namespace {
 
 class HelpPrinter {
@@ -913,11 +912,13 @@ public:
     for (unsigned i = 0, e = Options.size(); i != e; ++i)
       Options[i].second->printOptionInfo(MaxArgLen);
 
-    // Call the user's hook so help output can be extended.
-    if (MoreHelp != 0)
-      (*MoreHelp)();
+    // 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 if help information is printed
+    // Halt the program since help information was printed
     exit(1);
   }
 };
@@ -954,4 +955,16 @@ 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;
+}