X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FCommandLine.cpp;h=57620b50d6c6f8a3a8e81c194616a414a923e53c;hb=780413d4622e3977227c8e11ef27ba53bdee0d94;hp=73d26cf619cfb43407dbaff341b2f25ad71fe2eb;hpb=f976c856fcc5055f3fc7d9f070d72c2d027c1d9d;p=oota-llvm.git diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp index 73d26cf619c..57620b50d6c 100644 --- a/lib/Support/CommandLine.cpp +++ b/lib/Support/CommandLine.cpp @@ -18,7 +18,9 @@ #include "llvm/Config/config.h" #include "llvm/Support/CommandLine.h" +#include "llvm/System/Path.h" #include +#include #include #include #include @@ -26,11 +28,36 @@ #include #include using namespace llvm; - using namespace cl; +//===----------------------------------------------------------------------===// +// Template instantiations and anchors. +// +TEMPLATE_INSTANTIATION(class basic_parser); +TEMPLATE_INSTANTIATION(class basic_parser); +TEMPLATE_INSTANTIATION(class basic_parser); +TEMPLATE_INSTANTIATION(class basic_parser); +TEMPLATE_INSTANTIATION(class basic_parser); +TEMPLATE_INSTANTIATION(class basic_parser); + +TEMPLATE_INSTANTIATION(class opt); +TEMPLATE_INSTANTIATION(class opt); +TEMPLATE_INSTANTIATION(class opt); +TEMPLATE_INSTANTIATION(class opt); + +void Option::anchor() {} +void basic_parser_impl::anchor() {} +void parser::anchor() {} +void parser::anchor() {} +void parser::anchor() {} +void parser::anchor() {} +void parser::anchor() {} +void parser::anchor() {} + +//===----------------------------------------------------------------------===// + // Globals for name and overview of program -static const char *ProgramName = ""; +static std::string ProgramName = ""; static const char *ProgramOverview = 0; // This collects additional help to be printed. @@ -45,7 +72,7 @@ extrahelp::extrahelp(const char* Help) } //===----------------------------------------------------------------------===// -// Basic, shared command line option processing machinery... +// Basic, shared command line option processing machinery. // // Return the global command line option vector. Making it a function scoped @@ -97,7 +124,7 @@ static inline bool ProvideOption(Option *Handler, const char *ArgName, // Enforce value requirements switch (Handler->getValueExpectedFlag()) { case ValueRequired: - if (Value == 0 || *Value == 0) { // No value specified? + if (Value == 0) { // No value specified? if (i+1 < argc) { // Steal the next argument, like for '-o filename' Value = argv[++i]; } else { @@ -106,7 +133,7 @@ static inline bool ProvideOption(Option *Handler, const char *ArgName, } break; case ValueDisallowed: - if (*Value != 0) + if (Value) return Handler->error(" does not allow a value! '" + std::string(Value) + "' specified."); break; @@ -121,7 +148,7 @@ static inline bool ProvideOption(Option *Handler, const char *ArgName, } // Run the handler now! - return Handler->addOccurrence(i, ArgName, Value); + return Handler->addOccurrence(i, ArgName, Value ? Value : ""); } static bool ProvidePositionalOption(Option *Handler, const std::string &Arg, @@ -187,8 +214,8 @@ static bool EatsUnboundedNumberOfValues(const Option *O) { /// using strdup (), so it is the caller's responsibility to free () /// them later. /// -static void ParseCStringVector (std::vector &output, - const char *input) { +static void ParseCStringVector(std::vector &output, + const char *input) { // Characters which will be treated as token separators: static const char *delims = " \v\f\t\r\n"; @@ -238,26 +265,25 @@ void cl::ParseEnvironmentOptions(const char *progName, const char *envVar, assert(envVar && "Environment variable name missing"); // Get the environment variable they want us to parse options out of. - const char *envValue = getenv (envVar); + const char *envValue = getenv(envVar); if (!envValue) return; // Get program's "name", which we wouldn't know without the caller // telling us. - std::vector newArgv; - newArgv.push_back (strdup (progName)); + std::vector newArgv; + newArgv.push_back(strdup(progName)); // Parse the value of the environment variable into a "command line" // and hand it off to ParseCommandLineOptions(). - ParseCStringVector (newArgv, envValue); - int newArgc = newArgv.size (); - ParseCommandLineOptions (newArgc, &newArgv[0], Overview); + ParseCStringVector(newArgv, envValue); + int newArgc = newArgv.size(); + ParseCommandLineOptions(newArgc, &newArgv[0], Overview); // Free all the strdup()ed strings. - for (std::vector::iterator i = newArgv.begin (), e = newArgv.end (); - i != e; ++i) { + for (std::vector::iterator i = newArgv.begin(), e = newArgv.end(); + i != e; ++i) free (*i); - } } /// LookupOption - Lookup the option specified by the specified option on the @@ -268,11 +294,11 @@ static Option *LookupOption(const char *&Arg, const char *&Value) { const char *ArgEnd = Arg; while (*ArgEnd && *ArgEnd != '=') - ++ArgEnd; // Scan till end of argument name... + ++ArgEnd; // Scan till end of argument name. + + if (*ArgEnd == '=') // If we have an equals sign... + Value = ArgEnd+1; // Get the value, not the equals - Value = ArgEnd; - if (*Value) // If we have an equals sign... - ++Value; // Advance to value... if (*Arg == 0) return 0; @@ -288,7 +314,8 @@ void cl::ParseCommandLineOptions(int &argc, char **argv, assert((!getOpts().empty() || !getPositionalOpts().empty()) && "No options specified, or ParseCommandLineOptions called more" " than once!"); - ProgramName = argv[0]; // Save this away safe and snug + sys::Path progname(argv[0]); + ProgramName = sys::Path(argv[0]).getLast(); ProgramOverview = Overview; bool ErrorParsing = false; @@ -297,6 +324,10 @@ void cl::ParseCommandLineOptions(int &argc, char **argv, // Check out the positional arguments to collect information about them. unsigned NumPositionalRequired = 0; + + // Determine whether or not there are an unlimited number of positionals + bool HasUnlimitedPositionals = false; + Option *ConsumeAfterOpt = 0; if (!PositionalOpts.empty()) { if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) { @@ -332,6 +363,7 @@ void cl::ParseCommandLineOptions(int &argc, char **argv, } UnboundedFound |= EatsUnboundedNumberOfValues(Opt); } + HasUnlimitedPositionals = UnboundedFound || ConsumeAfterOpt; } // PositionalVals - A vector of "positional" arguments we accumulate into @@ -348,7 +380,7 @@ void cl::ParseCommandLineOptions(int &argc, char **argv, bool DashDashFound = false; // Have we read '--'? for (int i = 1; i < argc; ++i) { Option *Handler = 0; - const char *Value = ""; + const char *Value = 0; const char *ArgName = ""; // Check to see if this is a positional argument. This argument is @@ -429,7 +461,7 @@ void cl::ParseCommandLineOptions(int &argc, char **argv, "Option can not be cl::Grouping AND cl::ValueRequired!"); int Dummy; ErrorParsing |= ProvideOption(PGOpt, RealArgName.c_str(), - "", 0, 0, Dummy); + 0, 0, 0, Dummy); // Get the next grouping option... PGOpt = getOptionPred(RealName, Length, isGrouping); @@ -442,15 +474,15 @@ void cl::ParseCommandLineOptions(int &argc, char **argv, } if (Handler == 0) { - std::cerr << ProgramName << ": 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; } // Check to see if this option accepts a comma separated list of values. If // it does, we have to split up the value into multiple values... - if (Handler->getMiscFlags() & CommaSeparated) { + if (Value && Handler->getMiscFlags() & CommaSeparated) { std::string Val(Value); std::string::size_type Pos = Val.find(','); @@ -483,8 +515,15 @@ void cl::ParseCommandLineOptions(int &argc, char **argv, << ": 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"; ErrorParsing = true; - } else if (ConsumeAfterOpt == 0) { // Positional args have already been handled if ConsumeAfter is specified... @@ -587,11 +626,13 @@ bool Option::error(std::string Message, const char *ArgName) { std::cerr << HelpStr; // Be nice for positional arguments else std::cerr << ProgramName << ": for the -" << ArgName; + std::cerr << " option: " << Message << "\n"; return true; } -bool Option::addOccurrence(unsigned pos, 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()) { @@ -663,10 +704,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"; } @@ -693,12 +734,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"; } @@ -815,20 +856,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"; } } @@ -882,9 +923,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 &PosOpts = getPositionalOpts(); @@ -894,28 +935,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::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 @@ -924,19 +965,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... // @@ -944,17 +972,50 @@ HelpPrinter NormalPrinter(false); HelpPrinter HiddenPrinter(true); cl::opt > -HOp("help", cl::desc("display available options (--help-hidden for more)"), +HOp("help", cl::desc("Display available options (--help-hidden for more)"), cl::location(NormalPrinter), cl::ValueDisallowed); cl::opt > -HHOp("help-hidden", cl::desc("display all available options"), +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 (http://llvm.org/):\n"; + std::cout << " " << PACKAGE_NAME << " version " << PACKAGE_VERSION; +#ifdef LLVM_VERSION_INFO + std::cout << LLVM_VERSION_INFO; +#endif + std::cout << "\n "; +#ifndef __OPTIMIZE__ + std::cout << "DEBUG build"; +#else + std::cout << "Optimized build"; +#endif +#ifndef NDEBUG + std::cout << " with assertions"; +#endif + std::cout << ".\n"; + 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 > -VersOp("version", cl::desc("display the version"), +VersOp("version", cl::desc("Display the version of this program"), cl::location(VersionPrinterInstance), cl::ValueDisallowed); @@ -970,3 +1031,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; +}