forked from OSchip/llvm-project
Patches to avoid "leaking" memory on process exit. Patch contributed by
Morten Ofstad! llvm-svn: 17998
This commit is contained in:
parent
78e12c73e5
commit
37bcd99622
|
@ -33,6 +33,17 @@ using namespace cl;
|
||||||
static const char *ProgramName = "<unknown>";
|
static const char *ProgramName = "<unknown>";
|
||||||
static const char *ProgramOverview = 0;
|
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...
|
// 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
|
// 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 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() {
|
static std::map<std::string, Option*> &getOpts() {
|
||||||
if (CommandLineOptions == 0)
|
static std::map<std::string, Option*> CommandLineOptions;
|
||||||
CommandLineOptions = new std::map<std::string,Option*>();
|
return CommandLineOptions;
|
||||||
return *CommandLineOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Option *getOption(const std::string &Str) {
|
static Option *getOption(const std::string &Str) {
|
||||||
if (CommandLineOptions == 0) return 0;
|
std::map<std::string,Option*>::iterator I = getOpts().find(Str);
|
||||||
std::map<std::string,Option*>::iterator I = CommandLineOptions->find(Str);
|
return I != getOpts().end() ? I->second : 0;
|
||||||
return I != CommandLineOptions->end() ? I->second : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<Option*> &getPositionalOpts() {
|
static std::vector<Option*> &getPositionalOpts() {
|
||||||
static std::vector<Option*> *Positional = 0;
|
static std::vector<Option*> Positional;
|
||||||
if (!Positional) Positional = new std::vector<Option*>();
|
return Positional;
|
||||||
return *Positional;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddArgument(const char *ArgName, Option *Opt) {
|
static void AddArgument(const char *ArgName, Option *Opt) {
|
||||||
|
@ -73,18 +80,13 @@ static void AddArgument(const char *ArgName, Option *Opt) {
|
||||||
// options have already been processed and the map has been deleted!
|
// options have already been processed and the map has been deleted!
|
||||||
//
|
//
|
||||||
static void RemoveArgument(const char *ArgName, Option *Opt) {
|
static void RemoveArgument(const char *ArgName, Option *Opt) {
|
||||||
if (CommandLineOptions == 0) return;
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// This disgusting HACK is brought to you courtesy of GCC 3.3.2, which ICE's
|
// This disgusting HACK is brought to you courtesy of GCC 3.3.2, which ICE's
|
||||||
// If we pass ArgName directly into getOption here.
|
// If we pass ArgName directly into getOption here.
|
||||||
std::string Tmp = ArgName;
|
std::string Tmp = ArgName;
|
||||||
assert(getOption(Tmp) == Opt && "Arg not in map!");
|
assert(getOption(Tmp) == Opt && "Arg not in map!");
|
||||||
#endif
|
#endif
|
||||||
CommandLineOptions->erase(ArgName);
|
getOpts().erase(ArgName);
|
||||||
if (CommandLineOptions->empty()) {
|
|
||||||
delete CommandLineOptions;
|
|
||||||
CommandLineOptions = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ProvideOption(Option *Handler, const char *ArgName,
|
static inline bool ProvideOption(Option *Handler, const char *ArgName,
|
||||||
|
@ -565,9 +567,9 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
|
||||||
|
|
||||||
// Free all of the memory allocated to the map. Command line options may only
|
// Free all of the memory allocated to the map. Command line options may only
|
||||||
// be processed once!
|
// be processed once!
|
||||||
delete CommandLineOptions;
|
getOpts().clear();
|
||||||
CommandLineOptions = 0;
|
|
||||||
PositionalOpts.clear();
|
PositionalOpts.clear();
|
||||||
|
MoreHelp().clear();
|
||||||
|
|
||||||
// If we had an error processing our arguments, don't let the program execute
|
// If we had an error processing our arguments, don't let the program execute
|
||||||
if (ErrorParsing) exit(1);
|
if (ErrorParsing) exit(1);
|
||||||
|
@ -835,19 +837,6 @@ void generic_parser_base::printOptionInfo(const Option &O,
|
||||||
// --help and --help-hidden option implementation
|
// --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.
|
|
||||||
static std::vector<const char*>* MoreHelp = 0;
|
|
||||||
|
|
||||||
extrahelp::extrahelp(const char* Help)
|
|
||||||
: morehelp(Help) {
|
|
||||||
if (!MoreHelp) {
|
|
||||||
MoreHelp = new std::vector<const char*>;
|
|
||||||
}
|
|
||||||
MoreHelp->push_back(Help);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class HelpPrinter {
|
class HelpPrinter {
|
||||||
|
@ -921,14 +910,11 @@ public:
|
||||||
for (unsigned i = 0, e = Options.size(); i != e; ++i)
|
for (unsigned i = 0, e = Options.size(); i != e; ++i)
|
||||||
Options[i].second->printOptionInfo(MaxArgLen);
|
Options[i].second->printOptionInfo(MaxArgLen);
|
||||||
|
|
||||||
// Print any extra help the user has declared. If MoreHelp is not null,
|
// Print any extra help the user has declared.
|
||||||
// then the user used at least one cl::extrahelp instance to provide
|
for (std::vector<const char *>::iterator I = MoreHelp().begin(),
|
||||||
// additional help. We just print it out now.
|
E = MoreHelp().end(); I != E; ++I)
|
||||||
if (MoreHelp != 0) {
|
std::cerr << *I;
|
||||||
for (std::vector<const char *>::iterator I = MoreHelp->begin(),
|
MoreHelp().clear();
|
||||||
E = MoreHelp->end(); I != E; ++I)
|
|
||||||
std::cerr << *I;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Halt the program since help information was printed
|
// Halt the program since help information was printed
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
Loading…
Reference in New Issue