From f7573d6fba84c596e02d6aae9f1e4c0bdada823a Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 3 Aug 2021 15:03:52 +0200 Subject: Regenerate options parsing files --- build2/b-options.cxx | 43 +++++++++++++++++++++++++++-- build2/b-options.hxx | 50 ++++++++++++++++++++++++++++------ build2/b-options.ixx | 53 +++++++++++++++++++++++++----------- libbuild2/script/builtin-options.cxx | 33 ++++++++++++++++++++-- libbuild2/script/builtin-options.hxx | 39 ++++++++++++++++++++++---- libbuild2/script/builtin-options.ixx | 32 +++++++++++++++++----- 6 files changed, 209 insertions(+), 41 deletions(-) diff --git a/build2/b-options.cxx b/build2/b-options.cxx index 096aebc..182dfb0 100644 --- a/build2/b-options.cxx +++ b/build2/b-options.cxx @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -199,6 +200,7 @@ namespace build2 else ++i_; + ++start_position_; return r; } else @@ -209,11 +211,20 @@ namespace build2 skip () { if (i_ < argc_) + { ++i_; + ++start_position_; + } else throw eos_reached (); } + std::size_t argv_scanner:: + position () + { + return start_position_; + } + // argv_file_scanner // int argv_file_scanner::zero_argc_ = 0; @@ -324,6 +335,7 @@ namespace build2 { hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ().value); args_.pop_front (); + ++start_position_; return hold_[i_].c_str (); } } @@ -337,7 +349,10 @@ namespace build2 if (args_.empty ()) return base::skip (); else + { args_.pop_front (); + ++start_position_; + } } const argv_file_scanner::option_info* argv_file_scanner:: @@ -350,6 +365,12 @@ namespace build2 return 0; } + std::size_t argv_file_scanner:: + position () + { + return start_position_; + } + void argv_file_scanner:: load (const std::string& file) { @@ -567,6 +588,23 @@ namespace build2 }; template + struct parser > + { + static void + parse (std::pair& x, bool& xs, scanner& s) + { + x.second = s.position (); + parser::parse (x.first, xs, s); + } + + static void + merge (std::pair& b, const std::pair& a) + { + b = a; + } + }; + + template struct parser > { static void @@ -616,6 +654,7 @@ namespace build2 if (s.more ()) { + std::size_t pos (s.position ()); std::string ov (s.next ()); std::string::size_type p = ov.find ('='); @@ -635,14 +674,14 @@ namespace build2 if (!kstr.empty ()) { av[1] = const_cast (kstr.c_str ()); - argv_scanner s (0, ac, av); + argv_scanner s (0, ac, av, false, pos); parser::parse (k, dummy, s); } if (!vstr.empty ()) { av[1] = const_cast (vstr.c_str ()); - argv_scanner s (0, ac, av); + argv_scanner s (0, ac, av, false, pos); parser::parse (v, dummy, s); } diff --git a/build2/b-options.hxx b/build2/b-options.hxx index 4e1b7bd..a2f99f4 100644 --- a/build2/b-options.hxx +++ b/build2/b-options.hxx @@ -238,6 +238,14 @@ namespace build2 // for the two previous arguments up until a call to a third // peek() or next(). // + // The position() function returns a monotonically-increasing + // number which, if stored, can later be used to determine the + // relative position of the argument returned by the following + // call to next(). Note that if multiple scanners are used to + // extract arguments from multiple sources, then the end + // position of the previous scanner should be used as the + // start position of the next. + // class scanner { public: @@ -255,13 +263,24 @@ namespace build2 virtual void skip () = 0; + + virtual std::size_t + position () = 0; }; class argv_scanner: public scanner { public: - argv_scanner (int& argc, char** argv, bool erase = false); - argv_scanner (int start, int& argc, char** argv, bool erase = false); + argv_scanner (int& argc, + char** argv, + bool erase = false, + std::size_t start_position = 0); + + argv_scanner (int start, + int& argc, + char** argv, + bool erase = false, + std::size_t start_position = 0); int end () const; @@ -278,7 +297,11 @@ namespace build2 virtual void skip (); - private: + virtual std::size_t + position (); + + protected: + std::size_t start_position_; int i_; int& argc_; char** argv_; @@ -291,16 +314,19 @@ namespace build2 argv_file_scanner (int& argc, char** argv, const std::string& option, - bool erase = false); + bool erase = false, + std::size_t start_position = 0); argv_file_scanner (int start, int& argc, char** argv, const std::string& option, - bool erase = false); + bool erase = false, + std::size_t start_position = 0); argv_file_scanner (const std::string& file, - const std::string& option); + const std::string& option, + std::size_t start_position = 0); struct option_info { @@ -317,18 +343,21 @@ namespace build2 char** argv, const option_info* options, std::size_t options_count, - bool erase = false); + bool erase = false, + std::size_t start_position = 0); argv_file_scanner (int start, int& argc, char** argv, const option_info* options, std::size_t options_count, - bool erase = false); + bool erase = false, + std::size_t start_position = 0); argv_file_scanner (const std::string& file, const option_info* options = 0, - std::size_t options_count = 0); + std::size_t options_count = 0, + std::size_t start_position = 0); virtual bool more (); @@ -342,6 +371,9 @@ namespace build2 virtual void skip (); + virtual std::size_t + position (); + // Return the file path if the peeked at argument came from a file and // the empty string otherwise. The reference is guaranteed to be valid // till the end of the scanner lifetime. diff --git a/build2/b-options.ixx b/build2/b-options.ixx index 0e90ba1..104d4da 100644 --- a/build2/b-options.ixx +++ b/build2/b-options.ixx @@ -143,14 +143,29 @@ namespace build2 // argv_scanner // inline argv_scanner:: - argv_scanner (int& argc, char** argv, bool erase) - : i_ (1), argc_ (argc), argv_ (argv), erase_ (erase) + argv_scanner (int& argc, + char** argv, + bool erase, + std::size_t sp) + : start_position_ (sp + 1), + i_ (1), + argc_ (argc), + argv_ (argv), + erase_ (erase) { } inline argv_scanner:: - argv_scanner (int start, int& argc, char** argv, bool erase) - : i_ (start), argc_ (argc), argv_ (argv), erase_ (erase) + argv_scanner (int start, + int& argc, + char** argv, + bool erase, + std::size_t sp) + : start_position_ (sp + static_cast (start)), + i_ (start), + argc_ (argc), + argv_ (argv), + erase_ (erase) { } @@ -166,8 +181,9 @@ namespace build2 argv_file_scanner (int& argc, char** argv, const std::string& option, - bool erase) - : argv_scanner (argc, argv, erase), + bool erase, + std::size_t sp) + : argv_scanner (argc, argv, erase, sp), option_ (option), options_ (&option_info_), options_count_ (1), @@ -183,8 +199,9 @@ namespace build2 int& argc, char** argv, const std::string& option, - bool erase) - : argv_scanner (start, argc, argv, erase), + bool erase, + std::size_t sp) + : argv_scanner (start, argc, argv, erase, sp), option_ (option), options_ (&option_info_), options_count_ (1), @@ -197,8 +214,9 @@ namespace build2 inline argv_file_scanner:: argv_file_scanner (const std::string& file, - const std::string& option) - : argv_scanner (0, zero_argc_, 0), + const std::string& option, + std::size_t sp) + : argv_scanner (0, zero_argc_, 0, sp), option_ (option), options_ (&option_info_), options_count_ (1), @@ -216,8 +234,9 @@ namespace build2 char** argv, const option_info* options, std::size_t options_count, - bool erase) - : argv_scanner (argc, argv, erase), + bool erase, + std::size_t sp) + : argv_scanner (argc, argv, erase, sp), options_ (options), options_count_ (options_count), i_ (1), @@ -231,8 +250,9 @@ namespace build2 char** argv, const option_info* options, std::size_t options_count, - bool erase) - : argv_scanner (start, argc, argv, erase), + bool erase, + std::size_t sp) + : argv_scanner (start, argc, argv, erase, sp), options_ (options), options_count_ (options_count), i_ (1), @@ -243,8 +263,9 @@ namespace build2 inline argv_file_scanner:: argv_file_scanner (const std::string& file, const option_info* options, - std::size_t options_count) - : argv_scanner (0, zero_argc_, 0), + std::size_t options_count, + std::size_t sp) + : argv_scanner (0, zero_argc_, 0, sp), options_ (options), options_count_ (options_count), i_ (1), diff --git a/libbuild2/script/builtin-options.cxx b/libbuild2/script/builtin-options.cxx index c27f266..56e7f24 100644 --- a/libbuild2/script/builtin-options.cxx +++ b/libbuild2/script/builtin-options.cxx @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -160,6 +161,7 @@ namespace build2 else ++i_; + ++start_position_; return r; } else @@ -170,11 +172,20 @@ namespace build2 skip () { if (i_ < argc_) + { ++i_; + ++start_position_; + } else throw eos_reached (); } + std::size_t argv_scanner:: + position () + { + return start_position_; + } + // vector_scanner // bool vector_scanner:: @@ -210,6 +221,12 @@ namespace build2 throw eos_reached (); } + std::size_t vector_scanner:: + position () + { + return start_position_ + i_; + } + template struct parser { @@ -262,6 +279,17 @@ namespace build2 }; template + struct parser > + { + static void + parse (std::pair& x, bool& xs, scanner& s) + { + x.second = s.position (); + parser::parse (x.first, xs, s); + } + }; + + template struct parser > { static void @@ -299,6 +327,7 @@ namespace build2 if (s.more ()) { + std::size_t pos (s.position ()); std::string ov (s.next ()); std::string::size_type p = ov.find ('='); @@ -318,14 +347,14 @@ namespace build2 if (!kstr.empty ()) { av[1] = const_cast (kstr.c_str ()); - argv_scanner s (0, ac, av); + argv_scanner s (0, ac, av, false, pos); parser::parse (k, dummy, s); } if (!vstr.empty ()) { av[1] = const_cast (vstr.c_str ()); - argv_scanner s (0, ac, av); + argv_scanner s (0, ac, av, false, pos); parser::parse (v, dummy, s); } diff --git a/libbuild2/script/builtin-options.hxx b/libbuild2/script/builtin-options.hxx index f6544cf..d665279 100644 --- a/libbuild2/script/builtin-options.hxx +++ b/libbuild2/script/builtin-options.hxx @@ -176,6 +176,14 @@ namespace build2 // for the two previous arguments up until a call to a third // peek() or next(). // + // The position() function returns a monotonically-increasing + // number which, if stored, can later be used to determine the + // relative position of the argument returned by the following + // call to next(). Note that if multiple scanners are used to + // extract arguments from multiple sources, then the end + // position of the previous scanner should be used as the + // start position of the next. + // class scanner { public: @@ -193,13 +201,24 @@ namespace build2 virtual void skip () = 0; + + virtual std::size_t + position () = 0; }; class argv_scanner: public scanner { public: - argv_scanner (int& argc, char** argv, bool erase = false); - argv_scanner (int start, int& argc, char** argv, bool erase = false); + argv_scanner (int& argc, + char** argv, + bool erase = false, + std::size_t start_position = 0); + + argv_scanner (int start, + int& argc, + char** argv, + bool erase = false, + std::size_t start_position = 0); int end () const; @@ -216,7 +235,11 @@ namespace build2 virtual void skip (); - private: + virtual std::size_t + position (); + + protected: + std::size_t start_position_; int i_; int& argc_; char** argv_; @@ -226,13 +249,15 @@ namespace build2 class vector_scanner: public scanner { public: - vector_scanner (const std::vector&, std::size_t start = 0); + vector_scanner (const std::vector&, + std::size_t start = 0, + std::size_t start_position = 0); std::size_t end () const; void - reset (std::size_t start = 0); + reset (std::size_t start = 0, std::size_t start_position = 0); virtual bool more (); @@ -246,7 +271,11 @@ namespace build2 virtual void skip (); + virtual std::size_t + position (); + private: + std::size_t start_position_; const std::vector& v_; std::size_t i_; }; diff --git a/libbuild2/script/builtin-options.ixx b/libbuild2/script/builtin-options.ixx index bbd12b1..8fef25a 100644 --- a/libbuild2/script/builtin-options.ixx +++ b/libbuild2/script/builtin-options.ixx @@ -109,14 +109,29 @@ namespace build2 // argv_scanner // inline argv_scanner:: - argv_scanner (int& argc, char** argv, bool erase) - : i_ (1), argc_ (argc), argv_ (argv), erase_ (erase) + argv_scanner (int& argc, + char** argv, + bool erase, + std::size_t sp) + : start_position_ (sp + 1), + i_ (1), + argc_ (argc), + argv_ (argv), + erase_ (erase) { } inline argv_scanner:: - argv_scanner (int start, int& argc, char** argv, bool erase) - : i_ (start), argc_ (argc), argv_ (argv), erase_ (erase) + argv_scanner (int start, + int& argc, + char** argv, + bool erase, + std::size_t sp) + : start_position_ (sp + static_cast (start)), + i_ (start), + argc_ (argc), + argv_ (argv), + erase_ (erase) { } @@ -129,8 +144,10 @@ namespace build2 // vector_scanner // inline vector_scanner:: - vector_scanner (const std::vector& v, std::size_t i) - : v_ (v), i_ (i) + vector_scanner (const std::vector& v, + std::size_t i, + std::size_t sp) + : start_position_ (sp), v_ (v), i_ (i) { } @@ -141,9 +158,10 @@ namespace build2 } inline void vector_scanner:: - reset (std::size_t i) + reset (std::size_t i, std::size_t sp) { i_ = i; + start_position_ = sp; } } } -- cgit v1.1