#include <iostream>
using namespace cl;
-using std::map;
-using std::pair;
-using std::vector;
-using std::string;
-using std::cerr;
//===----------------------------------------------------------------------===//
// Basic, shared command line option processing machinery...
// 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 map<string,Option*> *CommandLineOptions = 0;
-static map<string, Option*> &getOpts() {
- if (CommandLineOptions == 0) CommandLineOptions = new map<string,Option*>();
+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 Option *getOption(const string &Str) {
+static Option *getOption(const std::string &Str) {
if (CommandLineOptions == 0) return 0;
- map<string,Option*>::iterator I = CommandLineOptions->find(Str);
+ std::map<std::string,Option*>::iterator I = CommandLineOptions->find(Str);
return I != CommandLineOptions->end() ? I->second : 0;
}
-static vector<Option*> &getPositionalOpts() {
- static vector<Option*> Positional;
+static std::vector<Option*> &getPositionalOpts() {
+ static std::vector<Option*> Positional;
return Positional;
}
static void AddArgument(const char *ArgName, Option *Opt) {
if (getOption(ArgName)) {
- cerr << "CommandLine Error: Argument '" << ArgName
- << "' defined more than once!\n";
+ std::cerr << "CommandLine Error: Argument '" << ArgName
+ << "' defined more than once!\n";
} else {
// Add argument to the argument map!
getOpts()[ArgName] = Opt;
case ValueDisallowed:
if (*Value != 0)
return Handler->error(" does not allow a value! '" +
- string(Value) + "' specified.");
+ std::string(Value) + "' specified.");
break;
case ValueOptional: break;
- default: cerr << "Bad ValueMask flag! CommandLine usage error:"
- << Handler->getValueExpectedFlag() << "\n"; abort();
+ default: std::cerr << "Bad ValueMask flag! CommandLine usage error:"
+ << Handler->getValueExpectedFlag() << "\n"; abort();
}
// Run the handler now!
- return Handler->addOccurance(ArgName, Value);
+ return Handler->addOccurrence(ArgName, Value);
}
-static bool ProvidePositionalOption(Option *Handler, string &Arg) {
+static bool ProvidePositionalOption(Option *Handler, std::string &Arg) {
int Dummy;
return ProvideOption(Handler, "", Arg.c_str(), 0, 0, Dummy);
}
}
static bool RequiresValue(const Option *O) {
- return O->getNumOccurancesFlag() == cl::Required ||
- O->getNumOccurancesFlag() == cl::OneOrMore;
+ return O->getNumOccurrencesFlag() == cl::Required ||
+ O->getNumOccurrencesFlag() == cl::OneOrMore;
}
static bool EatsUnboundedNumberOfValues(const Option *O) {
- return O->getNumOccurancesFlag() == cl::ZeroOrMore ||
- O->getNumOccurancesFlag() == cl::OneOrMore;
+ return O->getNumOccurrencesFlag() == cl::ZeroOrMore ||
+ O->getNumOccurrencesFlag() == cl::OneOrMore;
}
void cl::ParseCommandLineOptions(int &argc, char **argv,
ProgramOverview = Overview;
bool ErrorParsing = false;
- map<string, Option*> &Opts = getOpts();
- vector<Option*> &PositionalOpts = getPositionalOpts();
+ std::map<std::string, Option*> &Opts = getOpts();
+ std::vector<Option*> &PositionalOpts = getPositionalOpts();
// Check out the positional arguments to collect information about them.
unsigned NumPositionalRequired = 0;
Option *ConsumeAfterOpt = 0;
if (!PositionalOpts.empty()) {
- if (PositionalOpts[0]->getNumOccurancesFlag() == cl::ConsumeAfter) {
+ if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) {
assert(PositionalOpts.size() > 1 &&
"Cannot specify cl::ConsumeAfter without a positional argument!");
ConsumeAfterOpt = PositionalOpts[0];
// PositionalVals - A vector of "positional" arguments we accumulate into to
// processes at the end...
//
- vector<string> PositionalVals;
+ std::vector<std::string> PositionalVals;
// Loop over all of the arguments... processing them.
bool DashDashFound = false; // Have we read '--'?
++Value; // Advance to value...
if (*ArgName != 0) {
- string RealName(ArgName, ArgNameEnd);
+ std::string RealName(ArgName, ArgNameEnd);
// Extract arg name part
- map<string, Option*>::iterator I = Opts.find(RealName);
+ std::map<std::string, Option*>::iterator I = Opts.find(RealName);
if (I == Opts.end() && !*Value && RealName.size() > 1) {
// Check to see if this "option" is really a prefixed or grouped
if (PGOpt && PGOpt->getFormattingFlag() == cl::Prefix) {
ArgNameEnd = ArgName+Length;
Value = ArgNameEnd;
- I = Opts.find(string(ArgName, ArgNameEnd));
+ I = Opts.find(std::string(ArgName, ArgNameEnd));
assert(I->second == PGOpt);
} else if (PGOpt) {
// This must be a grouped option... handle all of them now...
do {
// Move current arg name out of RealName into RealArgName...
- string RealArgName(RealName.begin(), RealName.begin()+Length);
+ std::string RealArgName(RealName.begin(),RealName.begin()+Length);
RealName.erase(RealName.begin(), RealName.begin()+Length);
// Because ValueRequired is an invalid flag for grouped arguments,
}
if (Handler == 0) {
- cerr << "Unknown command line argument '" << argv[i] << "'. Try: "
- << argv[0] << " --help'\n";
+ std::cerr << "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) {
+ std::string Val(Value);
+ std::string::size_type Pos = Val.find(',');
+
+ while (Pos != std::string::npos) {
+ // Process the portion before the comma...
+ ErrorParsing |= ProvideOption(Handler, ArgName,
+ std::string(Val.begin(),
+ Val.begin()+Pos).c_str(),
+ argc, argv, i);
+ // Erase the portion before the comma, AND the comma...
+ Val.erase(Val.begin(), Val.begin()+Pos+1);
+ Value += Pos+1; // Increment the original value pointer as well...
+
+ // Check for another comma...
+ Pos = Val.find(',');
+ }
+ }
ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i);
}
// Check and handle positional arguments now...
if (NumPositionalRequired > PositionalVals.size()) {
- cerr << "Not enough positional command line arguments specified!\n";
- cerr << "Must specify at least " << NumPositionalRequired
- << " positional arguments: See: " << argv[0] << " --help\n";
+ std::cerr << "Not enough positional command line arguments specified!\n"
+ << "Must specify at least " << NumPositionalRequired
+ << " positional arguments: See: " << argv[0] << " --help\n";
ErrorParsing = true;
// do not give it values that others need. 'Done' controls whether the
// option even _WANTS_ any more.
//
- bool Done = PositionalOpts[i]->getNumOccurancesFlag() == cl::Required;
+ bool Done = PositionalOpts[i]->getNumOccurrencesFlag() == cl::Required;
while (NumVals-ValNo > NumPositionalRequired && !Done) {
- switch (PositionalOpts[i]->getNumOccurancesFlag()) {
+ switch (PositionalOpts[i]->getNumOccurrencesFlag()) {
case cl::Optional:
Done = true; // Optional arguments want _at most_ one value
// FALL THROUGH
ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo++]);
break;
default:
- assert(0 && "Internal error, unexpected NumOccurances flag in "
+ assert(0 && "Internal error, unexpected NumOccurrences flag in "
"positional argument processing!");
}
}
}
// Loop over args and make sure all required args are specified!
- for (map<string, Option*>::iterator I = Opts.begin(),
+ for (std::map<std::string, Option*>::iterator I = Opts.begin(),
E = Opts.end(); I != E; ++I) {
- switch (I->second->getNumOccurancesFlag()) {
+ switch (I->second->getNumOccurrencesFlag()) {
case Required:
case OneOrMore:
- if (I->second->getNumOccurances() == 0) {
+ if (I->second->getNumOccurrences() == 0) {
I->second->error(" must be specified at least once!");
ErrorParsing = true;
}
// Option Base class implementation
//
-bool Option::error(string Message, const char *ArgName) {
+bool Option::error(std::string Message, const char *ArgName) {
if (ArgName == 0) ArgName = ArgStr;
if (ArgName[0] == 0)
- cerr << HelpStr; // Be nice for positional arguments
+ std::cerr << HelpStr; // Be nice for positional arguments
else
- cerr << "-" << ArgName;
- cerr << " option" << Message << "\n";
+ std::cerr << "-" << ArgName;
+ std::cerr << " option" << Message << "\n";
return true;
}
-bool Option::addOccurance(const char *ArgName, const string &Value) {
- NumOccurances++; // Increment the number of times we have been seen
+bool Option::addOccurrence(const char *ArgName, const std::string &Value) {
+ NumOccurrences++; // Increment the number of times we have been seen
- switch (getNumOccurancesFlag()) {
+ switch (getNumOccurrencesFlag()) {
case Optional:
- if (NumOccurances > 1)
+ if (NumOccurrences > 1)
return error(": may only occur zero or one times!", ArgName);
break;
case Required:
- if (NumOccurances > 1)
+ if (NumOccurrences > 1)
return error(": must occur exactly one time!", ArgName);
// Fall through
case OneOrMore:
default: return error(": bad num occurances flag value!");
}
- return handleOccurance(ArgName, Value);
+ return handleOccurrence(ArgName, Value);
}
// addArgument - Tell the system that this Option subclass will handle all
AddArgument(ArgStr, this);
else if (getFormattingFlag() == Positional)
getPositionalOpts().push_back(this);
- else if (getNumOccurancesFlag() == ConsumeAfter) {
+ else if (getNumOccurrencesFlag() == ConsumeAfter) {
assert((getPositionalOpts().empty() ||
- getPositionalOpts().front()->getNumOccurancesFlag() != ConsumeAfter)
+ getPositionalOpts().front()->getNumOccurrencesFlag() != ConsumeAfter)
&& "Cannot specify more than one option with cl::ConsumeAfter "
"specified!");
getPositionalOpts().insert(getPositionalOpts().begin(), this);
if (ArgStr[0]) {
RemoveArgument(ArgStr, this);
} else if (getFormattingFlag() == Positional) {
- vector<Option*>::iterator I =
+ std::vector<Option*>::iterator I =
std::find(getPositionalOpts().begin(), getPositionalOpts().end(), this);
assert(I != getPositionalOpts().end() && "Arg not registered!");
getPositionalOpts().erase(I);
- } else if (getNumOccurancesFlag() == ConsumeAfter) {
+ } else if (getNumOccurrencesFlag() == ConsumeAfter) {
assert(!getPositionalOpts().empty() && getPositionalOpts()[0] == this &&
"Arg not registered correctly!");
getPositionalOpts().erase(getPositionalOpts().begin());
// Print out the option for the alias...
void alias::printOptionInfo(unsigned GlobalWidth) const {
unsigned L = std::strlen(ArgStr);
- cerr << " -" << ArgStr << string(GlobalWidth-L-6, ' ') << " - "
- << HelpStr << "\n";
+ std::cerr << " -" << ArgStr << std::string(GlobalWidth-L-6, ' ') << " - "
+ << HelpStr << "\n";
}
// Parser Implementation code...
//
+// basic_parser implementation
+//
+
+// Return the width of the option tag for printing...
+unsigned basic_parser_impl::getOptionWidth(const Option &O) const {
+ unsigned Len = std::strlen(O.ArgStr);
+ if (const char *ValName = getValueName())
+ Len += std::strlen(getValueStr(O, ValName))+3;
+
+ return Len + 6;
+}
+
+// printOptionInfo - Print out information about this option. The
+// to-be-maintained width is specified.
+//
+void basic_parser_impl::printOptionInfo(const Option &O,
+ unsigned GlobalWidth) const {
+ std::cerr << " -" << O.ArgStr;
+
+ if (const char *ValName = getValueName())
+ std::cerr << "=<" << getValueStr(O, ValName) << ">";
+
+ std::cerr << std::string(GlobalWidth-getOptionWidth(O), ' ') << " - "
+ << O.HelpStr << "\n";
+}
+
+
+
+
// parser<bool> implementation
//
-bool parser<bool>::parseImpl(Option &O, const string &Arg, bool &Value) {
+bool parser<bool>::parse(Option &O, const char *ArgName,
+ const std::string &Arg, bool &Value) {
if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
Arg == "1") {
Value = true;
return false;
}
-// Return the width of the option tag for printing...
-unsigned parser<bool>::getOptionWidth(const Option &O) const {
- return std::strlen(O.ArgStr)+6;
-}
-
-// printOptionInfo - Print out information about this option. The
-// to-be-maintained width is specified.
-//
-void parser<bool>::printOptionInfo(const Option &O, unsigned GlobalWidth) const{
- unsigned L = std::strlen(O.ArgStr);
- cerr << " -" << O.ArgStr << string(GlobalWidth-L-6, ' ') << " - "
- << O.HelpStr << "\n";
-}
-
-
-
// parser<int> implementation
//
-bool parser<int>::parseImpl(Option &O, const string &Arg, int &Value) {
- const char *ArgStart = Arg.c_str();
+bool parser<int>::parse(Option &O, const char *ArgName,
+ const std::string &Arg, int &Value) {
char *End;
- Value = (int)strtol(ArgStart, &End, 0);
+ Value = (int)strtol(Arg.c_str(), &End, 0);
if (*End != 0)
return O.error(": '" + Arg + "' value invalid for integer argument!");
return false;
}
-// Return the width of the option tag for printing...
-unsigned parser<int>::getOptionWidth(const Option &O) const {
- return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "int"))+9;
-}
-
-// printOptionInfo - Print out information about this option. The
-// to-be-maintained width is specified.
+// parser<unsigned> implementation
//
-void parser<int>::printOptionInfo(const Option &O, unsigned GlobalWidth) const{
- cerr << " -" << O.ArgStr << "=<" << getValueStr(O, "int") << ">"
- << string(GlobalWidth-getOptionWidth(O), ' ') << " - "
- << O.HelpStr << "\n";
+bool parser<unsigned>::parse(Option &O, const char *ArgName,
+ const std::string &Arg, unsigned &Value) {
+ char *End;
+ long long int V = strtoll(Arg.c_str(), &End, 0);
+ Value = (unsigned)V;
+ if (*End != 0 || V < 0 || Value != V)
+ return O.error(": '" + Arg + "' value invalid for uint argument!");
+ return false;
}
-
-// parser<double> implementation
+// parser<double>/parser<float> implementation
//
-bool parser<double>::parseImpl(Option &O, const string &Arg, double &Value) {
+static bool parseDouble(Option &O, const std::string &Arg, double &Value) {
const char *ArgStart = Arg.c_str();
char *End;
Value = strtod(ArgStart, &End);
return false;
}
-// Return the width of the option tag for printing...
-unsigned parser<double>::getOptionWidth(const Option &O) const {
- return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "number"))+9;
+bool parser<double>::parse(Option &O, const char *AN,
+ const std::string &Arg, double &Val) {
+ return parseDouble(O, Arg, Val);
}
-// printOptionInfo - Print out information about this option. The
-// to-be-maintained width is specified.
-//
-void parser<double>::printOptionInfo(const Option &O,
- unsigned GlobalWidth) const{
- cerr << " -" << O.ArgStr << "=<" << getValueStr(O, "number") << ">"
- << string(GlobalWidth-getOptionWidth(O), ' ')
- << " - " << O.HelpStr << "\n";
+bool parser<float>::parse(Option &O, const char *AN,
+ const std::string &Arg, float &Val) {
+ double dVal;
+ if (parseDouble(O, Arg, dVal))
+ return true;
+ Val = (float)dVal;
+ return false;
}
-// parser<string> implementation
-//
-
-// Return the width of the option tag for printing...
-unsigned parser<string>::getOptionWidth(const Option &O) const {
- return std::strlen(O.ArgStr)+std::strlen(getValueStr(O, "string"))+9;
-}
-
-// printOptionInfo - Print out information about this option. The
-// to-be-maintained width is specified.
-//
-void parser<string>::printOptionInfo(const Option &O,
- unsigned GlobalWidth) const{
- cerr << " -" << O.ArgStr << " <" << getValueStr(O, "string") << ">"
- << string(GlobalWidth-getOptionWidth(O), ' ')
- << " - " << O.HelpStr << "\n";
-}
// generic_parser_base implementation
//
//
unsigned generic_parser_base::findOption(const char *Name) {
unsigned i = 0, e = getNumOptions();
- string N(Name);
+ std::string N(Name);
while (i != e)
if (getOption(i) == N)
unsigned GlobalWidth) const {
if (O.hasArgStr()) {
unsigned L = std::strlen(O.ArgStr);
- cerr << " -" << O.ArgStr << string(GlobalWidth-L-6, ' ')
- << " - " << O.HelpStr << "\n";
+ std::cerr << " -" << 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;
- cerr << " =" << getOption(i) << string(NumSpaces, ' ') << " - "
- << getDescription(i) << "\n";
+ std::cerr << " =" << getOption(i) << std::string(NumSpaces, ' ')
+ << " - " << getDescription(i) << "\n";
}
} else {
if (O.HelpStr[0])
- cerr << " " << O.HelpStr << "\n";
+ std::cerr << " " << O.HelpStr << "\n";
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
unsigned L = std::strlen(getOption(i));
- cerr << " -" << getOption(i) << string(GlobalWidth-L-8, ' ') << " - "
- << getDescription(i) << "\n";
+ std::cerr << " -" << getOption(i) << std::string(GlobalWidth-L-8, ' ')
+ << " - " << getDescription(i) << "\n";
}
}
}
const bool ShowHidden;
// isHidden/isReallyHidden - Predicates to be used to filter down arg lists.
- inline static bool isHidden(pair<string, Option *> &OptPair) {
+ inline static bool isHidden(std::pair<std::string, Option *> &OptPair) {
return OptPair.second->getOptionHiddenFlag() >= Hidden;
}
- inline static bool isReallyHidden(pair<string, Option *> &OptPair) {
+ inline static bool isReallyHidden(std::pair<std::string, Option *> &OptPair) {
return OptPair.second->getOptionHiddenFlag() == ReallyHidden;
}
if (Value == false) return;
// Copy Options into a vector so we can sort them as we like...
- vector<pair<string, Option*> > Options;
+ std::vector<std::pair<std::string, Option*> > Options;
copy(getOpts().begin(), getOpts().end(), std::back_inserter(Options));
// Eliminate Hidden or ReallyHidden arguments, depending on ShowHidden
}
if (ProgramOverview)
- cerr << "OVERVIEW:" << ProgramOverview << "\n";
+ std::cerr << "OVERVIEW:" << ProgramOverview << "\n";
- cerr << "USAGE: " << ProgramName << " [options]";
+ std::cerr << "USAGE: " << ProgramName << " [options]";
// Print out the positional options...
- vector<Option*> &PosOpts = getPositionalOpts();
+ std::vector<Option*> &PosOpts = getPositionalOpts();
Option *CAOpt = 0; // The cl::ConsumeAfter option, if it exists...
- if (!PosOpts.empty() && PosOpts[0]->getNumOccurancesFlag() == ConsumeAfter)
+ if (!PosOpts.empty() && PosOpts[0]->getNumOccurrencesFlag() == ConsumeAfter)
CAOpt = PosOpts[0];
- for (unsigned i = CAOpt != 0, e = PosOpts.size(); i != e; ++i) {
- cerr << " " << PosOpts[i]->HelpStr;
- switch (PosOpts[i]->getNumOccurancesFlag()) {
- case Optional: cerr << "?"; break;
- case ZeroOrMore: cerr << "*"; break;
- case Required: break;
- case OneOrMore: cerr << "+"; break;
- case ConsumeAfter:
- default:
- assert(0 && "Unknown NumOccurances Flag Value!");
- }
- }
+ for (unsigned i = CAOpt != 0, e = PosOpts.size(); i != e; ++i)
+ std::cerr << " " << PosOpts[i]->HelpStr;
// Print the consume after option info if it exists...
- if (CAOpt) cerr << " " << CAOpt->HelpStr;
+ if (CAOpt) std::cerr << " " << CAOpt->HelpStr;
- cerr << "\n\n";
+ std::cerr << "\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());
- cerr << "OPTIONS:\n";
+ std::cerr << "OPTIONS:\n";
for (unsigned i = 0, e = Options.size(); i != e; ++i)
Options[i].second->printOptionInfo(MaxArgLen);
cl::opt<HelpPrinter, true, parser<bool> >
HOp("help", cl::desc("display available options (--help-hidden for more)"),
- cl::location(NormalPrinter));
+ cl::location(NormalPrinter), cl::ValueDisallowed);
cl::opt<HelpPrinter, true, parser<bool> >
HHOp("help-hidden", cl::desc("display all available options"),
- cl::location(HiddenPrinter), cl::Hidden);
+ cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed);
} // End anonymous namespace