Allow any cl::opt to use the method getPosition() to retrieve the option's

absolute position on the command line. Similarly allow any cl::list to
use the method getPosition(n) to retrieve the absolute position of the nth
option in the list. This provides support for two things: (a) options like
-l that are actually positional and their order of occurrence matters when
they are intermixed with positional arguments like "a.o"; and (b) options
like -x LANG which affect only the positional arguments that come after
the option. In both cases, knowing the absolute position of a given option
helps.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15725 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer
2004-08-13 19:47:30 +00:00
parent 1c284ac5ec
commit 1e13fd23d3
3 changed files with 100 additions and 67 deletions

View File

@@ -103,13 +103,13 @@ enum FormattingFlags {
Positional = 0x080, // Is a positional argument, no '-' required Positional = 0x080, // Is a positional argument, no '-' required
Prefix = 0x100, // Can this option directly prefix its value? Prefix = 0x100, // Can this option directly prefix its value?
Grouping = 0x180, // Can this option group with other options? Grouping = 0x180, // Can this option group with other options?
FormattingMask = 0x180, FormattingMask = 0x180, // Union of the above flags.
}; };
enum MiscFlags { // Miscellaneous flags to adjust argument enum MiscFlags { // Miscellaneous flags to adjust argument
CommaSeparated = 0x200, // Should this cl::list split between commas? CommaSeparated = 0x200, // Should this cl::list split between commas?
PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args? PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args?
MiscMask = 0x600, MiscMask = 0x600, // Union of the above flags.
}; };
@@ -126,7 +126,8 @@ class Option {
// an argument. Should return true if there was an error processing the // an argument. Should return true if there was an error processing the
// argument and the program should exit. // argument and the program should exit.
// //
virtual bool handleOccurrence(const char *ArgName, const std::string &Arg) = 0; virtual bool handleOccurrence(unsigned pos, const char *ArgName,
const std::string &Arg) = 0;
virtual enum NumOccurrences getNumOccurrencesFlagDefault() const { virtual enum NumOccurrences getNumOccurrencesFlagDefault() const {
return Optional; return Optional;
@@ -143,6 +144,7 @@ class Option {
int NumOccurrences; // The number of times specified int NumOccurrences; // The number of times specified
int Flags; // Flags for the argument int Flags; // Flags for the argument
unsigned Position; // Position of last occurrence of the option
public: public:
const char *ArgStr; // The argument string itself (ex: "help", "o") const char *ArgStr; // The argument string itself (ex: "help", "o")
const char *HelpStr; // The descriptive text message for --help const char *HelpStr; // The descriptive text message for --help
@@ -171,6 +173,7 @@ public:
inline unsigned getMiscFlags() const { inline unsigned getMiscFlags() const {
return Flags & MiscMask; return Flags & MiscMask;
} }
inline unsigned getPosition() const { return Position; }
// hasArgStr - Return true if the argstr != "" // hasArgStr - Return true if the argstr != ""
bool hasArgStr() const { return ArgStr[0] != 0; } bool hasArgStr() const { return ArgStr[0] != 0; }
@@ -198,8 +201,9 @@ public:
void setHiddenFlag(enum OptionHidden Val) { setFlag(Val, HiddenMask); } void setHiddenFlag(enum OptionHidden Val) { setFlag(Val, HiddenMask); }
void setFormattingFlag(enum FormattingFlags V) { setFlag(V, FormattingMask); } void setFormattingFlag(enum FormattingFlags V) { setFlag(V, FormattingMask); }
void setMiscFlag(enum MiscFlags M) { setFlag(M, M); } void setMiscFlag(enum MiscFlags M) { setFlag(M, M); }
void setPosition(unsigned pos) { Position = pos; }
protected: protected:
Option() : NumOccurrences(0), Flags(0), Option() : NumOccurrences(0), Flags(0), Position(0),
ArgStr(""), HelpStr(""), ValueStr("") {} ArgStr(""), HelpStr(""), ValueStr("") {}
public: public:
@@ -219,7 +223,8 @@ public:
// addOccurrence - Wrapper around handleOccurrence that enforces Flags // addOccurrence - Wrapper around handleOccurrence that enforces Flags
// //
bool addOccurrence(const char *ArgName, const std::string &Value); bool addOccurrence(unsigned pos, const char *ArgName,
const std::string &Value);
// Prints option name followed by message. Always returns true. // Prints option name followed by message. Always returns true.
bool error(std::string Message, const char *ArgName = 0); bool error(std::string Message, const char *ArgName = 0);
@@ -250,7 +255,6 @@ struct value_desc {
void apply(Option &O) const { O.setValueStr(Desc); } void apply(Option &O) const { O.setValueStr(Desc); }
}; };
// init - Specify a default (initial) value for the command line argument, if // init - Specify a default (initial) value for the command line argument, if
// the default constructor for the argument type does not give you what you // the default constructor for the argument type does not give you what you
// want. This is only valid on "opt" arguments, not on "list" arguments. // want. This is only valid on "opt" arguments, not on "list" arguments.
@@ -492,7 +496,6 @@ struct basic_parser_impl { // non-template implementation of basic_parser<t>
// //
void printOptionInfo(const Option &O, unsigned GlobalWidth) const; void printOptionInfo(const Option &O, unsigned GlobalWidth) const;
// getValueName - Overload in subclass to provide a better default value. // getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "value"; } virtual const char *getValueName() const { return "value"; }
}; };
@@ -545,8 +548,7 @@ template<>
struct parser<unsigned> : public basic_parser<unsigned> { struct parser<unsigned> : public basic_parser<unsigned> {
// parse - Return true on error. // parse - Return true on error.
bool parse(Option &O, const char *ArgName, const std::string &Arg, bool parse(Option &O, const char *AN, const std::string &Arg, unsigned &Val);
unsigned &Val);
// getValueName - Overload in subclass to provide a better default value. // getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "uint"; } virtual const char *getValueName() const { return "uint"; }
@@ -585,7 +587,7 @@ struct parser<float> : public basic_parser<float> {
template<> template<>
struct parser<std::string> : public basic_parser<std::string> { struct parser<std::string> : public basic_parser<std::string> {
// parse - Return true on error. // parse - Return true on error.
bool parse(Option &O, const char *ArgName, const std::string &Arg, bool parse(Option &O, const char *AN, const std::string &Arg,
std::string &Value) { std::string &Value) {
Value = Arg; Value = Arg;
return false; return false;
@@ -595,8 +597,6 @@ struct parser<std::string> : public basic_parser<std::string> {
virtual const char *getValueName() const { return "string"; } virtual const char *getValueName() const { return "string"; }
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// applicator class - This class is used because we must use partial // applicator class - This class is used because we must use partial
// specialization to handle literal string arguments specially (const char* does // specialization to handle literal string arguments specially (const char* does
@@ -728,11 +728,13 @@ class opt : public Option,
is_class<DataType>::value> { is_class<DataType>::value> {
ParserClass Parser; ParserClass Parser;
virtual bool handleOccurrence(const char *ArgName, const std::string &Arg) { virtual bool handleOccurrence(unsigned pos, const char *ArgName,
const std::string &Arg) {
typename ParserClass::parser_data_type Val; typename ParserClass::parser_data_type Val;
if (Parser.parse(*this, ArgName, Arg, Val)) if (Parser.parse(*this, ArgName, Arg, Val))
return true; // Parse error! return true; // Parse error!
setValue(Val); setValue(Val);
setPosition(pos);
return false; return false;
} }
@@ -875,6 +877,7 @@ struct list_storage<DataType, bool> : public std::vector<DataType> {
template <class DataType, class Storage = bool, template <class DataType, class Storage = bool,
class ParserClass = parser<DataType> > class ParserClass = parser<DataType> >
class list : public Option, public list_storage<DataType, Storage> { class list : public Option, public list_storage<DataType, Storage> {
std::vector<unsigned> Positions;
ParserClass Parser; ParserClass Parser;
virtual enum NumOccurrences getNumOccurrencesFlagDefault() const { virtual enum NumOccurrences getNumOccurrencesFlagDefault() const {
@@ -884,11 +887,14 @@ class list : public Option, public list_storage<DataType, Storage> {
return Parser.getValueExpectedFlagDefault(); return Parser.getValueExpectedFlagDefault();
} }
virtual bool handleOccurrence(const char *ArgName, const std::string &Arg) { virtual bool handleOccurrence(unsigned pos, const char *ArgName,
const std::string &Arg) {
typename ParserClass::parser_data_type Val; typename ParserClass::parser_data_type Val;
if (Parser.parse(*this, ArgName, Arg, Val)) if (Parser.parse(*this, ArgName, Arg, Val))
return true; // Parse Error! return true; // Parse Error!
addValue(Val); addValue(Val);
setPosition(pos);
Positions.push_back(pos);
return false; return false;
} }
@@ -905,6 +911,11 @@ class list : public Option, public list_storage<DataType, Storage> {
public: public:
ParserClass &getParser() { return Parser; } ParserClass &getParser() { return Parser; }
unsigned getPosition(unsigned optnum) {
assert(optnum < this->size() && "Invalid option index");
return Positions[optnum];
}
// One option... // One option...
template<class M0t> template<class M0t>
list(const M0t &M0) { list(const M0t &M0) {
@@ -966,16 +977,15 @@ public:
} }
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Aliased command line option (alias this name to a preexisting name) // Aliased command line option (alias this name to a preexisting name)
// //
class alias : public Option { class alias : public Option {
Option *AliasFor; Option *AliasFor;
virtual bool handleOccurrence(const char *ArgName, const std::string &Arg) { virtual bool handleOccurrence(unsigned pos, const char *ArgName,
return AliasFor->handleOccurrence(AliasFor->ArgStr, Arg); const std::string &Arg) {
return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
} }
// Aliases default to be hidden... // Aliases default to be hidden...
virtual enum OptionHidden getOptionHiddenFlagDefault() const {return Hidden;} virtual enum OptionHidden getOptionHiddenFlagDefault() const {return Hidden;}

View File

@@ -103,13 +103,13 @@ enum FormattingFlags {
Positional = 0x080, // Is a positional argument, no '-' required Positional = 0x080, // Is a positional argument, no '-' required
Prefix = 0x100, // Can this option directly prefix its value? Prefix = 0x100, // Can this option directly prefix its value?
Grouping = 0x180, // Can this option group with other options? Grouping = 0x180, // Can this option group with other options?
FormattingMask = 0x180, FormattingMask = 0x180, // Union of the above flags.
}; };
enum MiscFlags { // Miscellaneous flags to adjust argument enum MiscFlags { // Miscellaneous flags to adjust argument
CommaSeparated = 0x200, // Should this cl::list split between commas? CommaSeparated = 0x200, // Should this cl::list split between commas?
PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args? PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args?
MiscMask = 0x600, MiscMask = 0x600, // Union of the above flags.
}; };
@@ -126,7 +126,8 @@ class Option {
// an argument. Should return true if there was an error processing the // an argument. Should return true if there was an error processing the
// argument and the program should exit. // argument and the program should exit.
// //
virtual bool handleOccurrence(const char *ArgName, const std::string &Arg) = 0; virtual bool handleOccurrence(unsigned pos, const char *ArgName,
const std::string &Arg) = 0;
virtual enum NumOccurrences getNumOccurrencesFlagDefault() const { virtual enum NumOccurrences getNumOccurrencesFlagDefault() const {
return Optional; return Optional;
@@ -143,6 +144,7 @@ class Option {
int NumOccurrences; // The number of times specified int NumOccurrences; // The number of times specified
int Flags; // Flags for the argument int Flags; // Flags for the argument
unsigned Position; // Position of last occurrence of the option
public: public:
const char *ArgStr; // The argument string itself (ex: "help", "o") const char *ArgStr; // The argument string itself (ex: "help", "o")
const char *HelpStr; // The descriptive text message for --help const char *HelpStr; // The descriptive text message for --help
@@ -171,6 +173,7 @@ public:
inline unsigned getMiscFlags() const { inline unsigned getMiscFlags() const {
return Flags & MiscMask; return Flags & MiscMask;
} }
inline unsigned getPosition() const { return Position; }
// hasArgStr - Return true if the argstr != "" // hasArgStr - Return true if the argstr != ""
bool hasArgStr() const { return ArgStr[0] != 0; } bool hasArgStr() const { return ArgStr[0] != 0; }
@@ -198,8 +201,9 @@ public:
void setHiddenFlag(enum OptionHidden Val) { setFlag(Val, HiddenMask); } void setHiddenFlag(enum OptionHidden Val) { setFlag(Val, HiddenMask); }
void setFormattingFlag(enum FormattingFlags V) { setFlag(V, FormattingMask); } void setFormattingFlag(enum FormattingFlags V) { setFlag(V, FormattingMask); }
void setMiscFlag(enum MiscFlags M) { setFlag(M, M); } void setMiscFlag(enum MiscFlags M) { setFlag(M, M); }
void setPosition(unsigned pos) { Position = pos; }
protected: protected:
Option() : NumOccurrences(0), Flags(0), Option() : NumOccurrences(0), Flags(0), Position(0),
ArgStr(""), HelpStr(""), ValueStr("") {} ArgStr(""), HelpStr(""), ValueStr("") {}
public: public:
@@ -219,7 +223,8 @@ public:
// addOccurrence - Wrapper around handleOccurrence that enforces Flags // addOccurrence - Wrapper around handleOccurrence that enforces Flags
// //
bool addOccurrence(const char *ArgName, const std::string &Value); bool addOccurrence(unsigned pos, const char *ArgName,
const std::string &Value);
// Prints option name followed by message. Always returns true. // Prints option name followed by message. Always returns true.
bool error(std::string Message, const char *ArgName = 0); bool error(std::string Message, const char *ArgName = 0);
@@ -250,7 +255,6 @@ struct value_desc {
void apply(Option &O) const { O.setValueStr(Desc); } void apply(Option &O) const { O.setValueStr(Desc); }
}; };
// init - Specify a default (initial) value for the command line argument, if // init - Specify a default (initial) value for the command line argument, if
// the default constructor for the argument type does not give you what you // the default constructor for the argument type does not give you what you
// want. This is only valid on "opt" arguments, not on "list" arguments. // want. This is only valid on "opt" arguments, not on "list" arguments.
@@ -492,7 +496,6 @@ struct basic_parser_impl { // non-template implementation of basic_parser<t>
// //
void printOptionInfo(const Option &O, unsigned GlobalWidth) const; void printOptionInfo(const Option &O, unsigned GlobalWidth) const;
// getValueName - Overload in subclass to provide a better default value. // getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "value"; } virtual const char *getValueName() const { return "value"; }
}; };
@@ -545,8 +548,7 @@ template<>
struct parser<unsigned> : public basic_parser<unsigned> { struct parser<unsigned> : public basic_parser<unsigned> {
// parse - Return true on error. // parse - Return true on error.
bool parse(Option &O, const char *ArgName, const std::string &Arg, bool parse(Option &O, const char *AN, const std::string &Arg, unsigned &Val);
unsigned &Val);
// getValueName - Overload in subclass to provide a better default value. // getValueName - Overload in subclass to provide a better default value.
virtual const char *getValueName() const { return "uint"; } virtual const char *getValueName() const { return "uint"; }
@@ -585,7 +587,7 @@ struct parser<float> : public basic_parser<float> {
template<> template<>
struct parser<std::string> : public basic_parser<std::string> { struct parser<std::string> : public basic_parser<std::string> {
// parse - Return true on error. // parse - Return true on error.
bool parse(Option &O, const char *ArgName, const std::string &Arg, bool parse(Option &O, const char *AN, const std::string &Arg,
std::string &Value) { std::string &Value) {
Value = Arg; Value = Arg;
return false; return false;
@@ -595,8 +597,6 @@ struct parser<std::string> : public basic_parser<std::string> {
virtual const char *getValueName() const { return "string"; } virtual const char *getValueName() const { return "string"; }
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// applicator class - This class is used because we must use partial // applicator class - This class is used because we must use partial
// specialization to handle literal string arguments specially (const char* does // specialization to handle literal string arguments specially (const char* does
@@ -728,11 +728,13 @@ class opt : public Option,
is_class<DataType>::value> { is_class<DataType>::value> {
ParserClass Parser; ParserClass Parser;
virtual bool handleOccurrence(const char *ArgName, const std::string &Arg) { virtual bool handleOccurrence(unsigned pos, const char *ArgName,
const std::string &Arg) {
typename ParserClass::parser_data_type Val; typename ParserClass::parser_data_type Val;
if (Parser.parse(*this, ArgName, Arg, Val)) if (Parser.parse(*this, ArgName, Arg, Val))
return true; // Parse error! return true; // Parse error!
setValue(Val); setValue(Val);
setPosition(pos);
return false; return false;
} }
@@ -875,6 +877,7 @@ struct list_storage<DataType, bool> : public std::vector<DataType> {
template <class DataType, class Storage = bool, template <class DataType, class Storage = bool,
class ParserClass = parser<DataType> > class ParserClass = parser<DataType> >
class list : public Option, public list_storage<DataType, Storage> { class list : public Option, public list_storage<DataType, Storage> {
std::vector<unsigned> Positions;
ParserClass Parser; ParserClass Parser;
virtual enum NumOccurrences getNumOccurrencesFlagDefault() const { virtual enum NumOccurrences getNumOccurrencesFlagDefault() const {
@@ -884,11 +887,14 @@ class list : public Option, public list_storage<DataType, Storage> {
return Parser.getValueExpectedFlagDefault(); return Parser.getValueExpectedFlagDefault();
} }
virtual bool handleOccurrence(const char *ArgName, const std::string &Arg) { virtual bool handleOccurrence(unsigned pos, const char *ArgName,
const std::string &Arg) {
typename ParserClass::parser_data_type Val; typename ParserClass::parser_data_type Val;
if (Parser.parse(*this, ArgName, Arg, Val)) if (Parser.parse(*this, ArgName, Arg, Val))
return true; // Parse Error! return true; // Parse Error!
addValue(Val); addValue(Val);
setPosition(pos);
Positions.push_back(pos);
return false; return false;
} }
@@ -905,6 +911,11 @@ class list : public Option, public list_storage<DataType, Storage> {
public: public:
ParserClass &getParser() { return Parser; } ParserClass &getParser() { return Parser; }
unsigned getPosition(unsigned optnum) {
assert(optnum < this->size() && "Invalid option index");
return Positions[optnum];
}
// One option... // One option...
template<class M0t> template<class M0t>
list(const M0t &M0) { list(const M0t &M0) {
@@ -966,16 +977,15 @@ public:
} }
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Aliased command line option (alias this name to a preexisting name) // Aliased command line option (alias this name to a preexisting name)
// //
class alias : public Option { class alias : public Option {
Option *AliasFor; Option *AliasFor;
virtual bool handleOccurrence(const char *ArgName, const std::string &Arg) { virtual bool handleOccurrence(unsigned pos, const char *ArgName,
return AliasFor->handleOccurrence(AliasFor->ArgStr, Arg); const std::string &Arg) {
return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
} }
// Aliases default to be hidden... // Aliases default to be hidden...
virtual enum OptionHidden getOptionHiddenFlagDefault() const {return Hidden;} virtual enum OptionHidden getOptionHiddenFlagDefault() const {return Hidden;}

View File

@@ -111,11 +111,12 @@ static inline bool ProvideOption(Option *Handler, const char *ArgName,
} }
// Run the handler now! // Run the handler now!
return Handler->addOccurrence(ArgName, Value); return Handler->addOccurrence(i, ArgName, Value);
} }
static bool ProvidePositionalOption(Option *Handler, const std::string &Arg) { static bool ProvidePositionalOption(Option *Handler, const std::string &Arg,
int Dummy; int i) {
int Dummy = i;
return ProvideOption(Handler, Handler->ArgStr, Arg.c_str(), 0, 0, Dummy); return ProvideOption(Handler, Handler->ArgStr, Arg.c_str(), 0, 0, Dummy);
} }
@@ -323,10 +324,10 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
} }
} }
// PositionalVals - A vector of "positional" arguments we accumulate into to // PositionalVals - A vector of "positional" arguments we accumulate into
// processes at the end... // 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 // If the program has named positional arguments, and the name has been run
// across, keep track of which positional argument was named. Otherwise put // across, keep track of which positional argument was named. Otherwise put
@@ -347,10 +348,10 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) { if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) {
// Positional argument! // Positional argument!
if (ActivePositionalArg) { if (ActivePositionalArg) {
ProvidePositionalOption(ActivePositionalArg, argv[i]); ProvidePositionalOption(ActivePositionalArg, argv[i], i);
continue; // We are done! continue; // We are done!
} else if (!PositionalOpts.empty()) { } 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 // All of the positional arguments have been fulfulled, give the rest to
// the consume after option... if it's specified... // the consume after option... if it's specified...
@@ -358,7 +359,7 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
if (PositionalVals.size() >= NumPositionalRequired && if (PositionalVals.size() >= NumPositionalRequired &&
ConsumeAfterOpt != 0) { ConsumeAfterOpt != 0) {
for (++i; i < argc; ++i) 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... break; // Handle outside of the argument processing loop...
} }
@@ -377,7 +378,7 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
ArgName = argv[i]+1; ArgName = argv[i]+1;
Handler = LookupOption(ArgName, Value); Handler = LookupOption(ArgName, Value);
if (!Handler || Handler->getFormattingFlag() != cl::Positional) { if (!Handler || Handler->getFormattingFlag() != cl::Positional) {
ProvidePositionalOption(ActivePositionalArg, argv[i]); ProvidePositionalOption(ActivePositionalArg, argv[i], i);
continue; // We are done! continue; // We are done!
} }
@@ -479,7 +480,9 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
unsigned ValNo = 0, NumVals = PositionalVals.size(); unsigned ValNo = 0, NumVals = PositionalVals.size();
for (unsigned i = 0, e = PositionalOpts.size(); i != e; ++i) { for (unsigned i = 0, e = PositionalOpts.size(); i != e; ++i) {
if (RequiresValue(PositionalOpts[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... --NumPositionalRequired; // We fulfilled our duty...
} }
@@ -495,7 +498,10 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
// FALL THROUGH // FALL THROUGH
case cl::ZeroOrMore: // Zero or more will take all they can get... case cl::ZeroOrMore: // Zero or more will take all they can get...
case cl::OneOrMore: // One 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; break;
default: default:
assert(0 && "Internal error, unexpected NumOccurrences flag in " assert(0 && "Internal error, unexpected NumOccurrences flag in "
@@ -507,24 +513,31 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size()); assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size());
unsigned ValNo = 0; unsigned ValNo = 0;
for (unsigned j = 1, e = PositionalOpts.size(); j != e; ++j) for (unsigned j = 1, e = PositionalOpts.size(); j != e; ++j)
if (RequiresValue(PositionalOpts[j])) if (RequiresValue(PositionalOpts[j])) {
ErrorParsing |= ProvidePositionalOption(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 // 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 // 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 // positional option and keep the rest for the consume after. The above
// loop would have assigned no values to positional options in this case. // 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], ErrorParsing |= ProvidePositionalOption(PositionalOpts[1],
PositionalVals[ValNo++]); PositionalVals[ValNo].first,
PositionalVals[ValNo].second);
ValNo++;
}
// Handle over all of the rest of the arguments to the // Handle over all of the rest of the arguments to the
// cl::ConsumeAfter command line option... // cl::ConsumeAfter command line option...
for (; ValNo != PositionalVals.size(); ++ValNo) for (; ValNo != PositionalVals.size(); ++ValNo)
ErrorParsing |= ProvidePositionalOption(ConsumeAfterOpt, ErrorParsing |= ProvidePositionalOption(ConsumeAfterOpt,
PositionalVals[ValNo]); PositionalVals[ValNo].first,
PositionalVals[ValNo].second);
} }
// Loop over args and make sure all required args are specified! // Loop over args and make sure all required args are specified!
@@ -567,7 +580,7 @@ bool Option::error(std::string Message, const char *ArgName) {
return true; 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 NumOccurrences++; // Increment the number of times we have been seen
switch (getNumOccurrencesFlag()) { switch (getNumOccurrencesFlag()) {
@@ -585,7 +598,7 @@ bool Option::addOccurrence(const char *ArgName, const std::string &Value) {
default: return error(": bad num occurrences flag 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 // addArgument - Tell the system that this Option subclass will handle all