aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/script/builtin-options.cxx33
-rw-r--r--libbuild2/script/builtin-options.hxx39
-rw-r--r--libbuild2/script/builtin-options.ixx32
3 files changed, 90 insertions, 14 deletions
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 <set>
#include <string>
#include <vector>
+#include <utility>
#include <ostream>
#include <sstream>
@@ -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 <typename X>
struct parser
{
@@ -262,6 +279,17 @@ namespace build2
};
template <typename X>
+ struct parser<std::pair<X, std::size_t> >
+ {
+ static void
+ parse (std::pair<X, std::size_t>& x, bool& xs, scanner& s)
+ {
+ x.second = s.position ();
+ parser<X>::parse (x.first, xs, s);
+ }
+ };
+
+ template <typename X>
struct parser<std::vector<X> >
{
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<char*> (kstr.c_str ());
- argv_scanner s (0, ac, av);
+ argv_scanner s (0, ac, av, false, pos);
parser<K>::parse (k, dummy, s);
}
if (!vstr.empty ())
{
av[1] = const_cast<char*> (vstr.c_str ());
- argv_scanner s (0, ac, av);
+ argv_scanner s (0, ac, av, false, pos);
parser<V>::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::string>&, std::size_t start = 0);
+ vector_scanner (const std::vector<std::string>&,
+ 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<std::string>& 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<std::size_t> (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<std::string>& v, std::size_t i)
- : v_ (v), i_ (i)
+ vector_scanner (const std::vector<std::string>& 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;
}
}
}