mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	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:
		| @@ -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;} | ||||||
|   | |||||||
| @@ -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;} | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user