aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2022-02-18 16:20:27 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2022-02-18 17:23:24 +0300
commit24adee85717a9bc61013b6b12fd81135d856d33d (patch)
treec1c5638eea4d5edf42ac961823d069cca747b15a
parent2835794b28d482b1e391dc85f79dfa91f9e63d3e (diff)
Factor out common CLI types (scanners, etc)
-rw-r--r--libbuild2/b-options.cxx494
-rw-r--r--libbuild2/b-options.hxx420
-rw-r--r--libbuild2/b-options.ixx270
-rw-r--r--libbuild2/b.cli4
-rw-r--r--libbuild2/build/script/builtin-options.cxx517
-rw-r--r--libbuild2/build/script/builtin-options.hxx309
-rw-r--r--libbuild2/build/script/builtin-options.ixx161
-rw-r--r--libbuild2/build/script/builtin.cli2
-rw-r--r--libbuild2/build/script/types-parsers.cxx56
-rw-r--r--libbuild2/build/script/types-parsers.hxx49
-rw-r--r--libbuild2/buildfile30
-rw-r--r--libbuild2/common-options.cxx731
-rw-r--r--libbuild2/common-options.hxx480
-rw-r--r--libbuild2/common-options.ixx312
-rw-r--r--libbuild2/common.cli6
-rw-r--r--libbuild2/script/builtin-options.cxx420
-rw-r--r--libbuild2/script/builtin-options.hxx366
-rw-r--r--libbuild2/script/builtin-options.ixx158
-rw-r--r--libbuild2/script/builtin.cli2
-rw-r--r--libbuild2/script/run.cxx2
20 files changed, 1888 insertions, 2901 deletions
diff --git a/libbuild2/b-options.cxx b/libbuild2/b-options.cxx
index 86f5bfe..0164a0a 100644
--- a/libbuild2/b-options.cxx
+++ b/libbuild2/b-options.cxx
@@ -19,8 +19,6 @@
#include <utility>
#include <ostream>
#include <sstream>
-#include <cstring>
-#include <fstream>
namespace build2
{
@@ -28,498 +26,6 @@ namespace build2
{
namespace cli
{
- // unknown_option
- //
- unknown_option::
- ~unknown_option () throw ()
- {
- }
-
- void unknown_option::
- print (::std::ostream& os) const
- {
- os << "unknown option '" << option ().c_str () << "'";
- }
-
- const char* unknown_option::
- what () const throw ()
- {
- return "unknown option";
- }
-
- // unknown_argument
- //
- unknown_argument::
- ~unknown_argument () throw ()
- {
- }
-
- void unknown_argument::
- print (::std::ostream& os) const
- {
- os << "unknown argument '" << argument ().c_str () << "'";
- }
-
- const char* unknown_argument::
- what () const throw ()
- {
- return "unknown argument";
- }
-
- // missing_value
- //
- missing_value::
- ~missing_value () throw ()
- {
- }
-
- void missing_value::
- print (::std::ostream& os) const
- {
- os << "missing value for option '" << option ().c_str () << "'";
- }
-
- const char* missing_value::
- what () const throw ()
- {
- return "missing option value";
- }
-
- // invalid_value
- //
- invalid_value::
- ~invalid_value () throw ()
- {
- }
-
- void invalid_value::
- print (::std::ostream& os) const
- {
- os << "invalid value '" << value ().c_str () << "' for option '"
- << option ().c_str () << "'";
-
- if (!message ().empty ())
- os << ": " << message ().c_str ();
- }
-
- const char* invalid_value::
- what () const throw ()
- {
- return "invalid option value";
- }
-
- // eos_reached
- //
- void eos_reached::
- print (::std::ostream& os) const
- {
- os << what ();
- }
-
- const char* eos_reached::
- what () const throw ()
- {
- return "end of argument stream reached";
- }
-
- // file_io_failure
- //
- file_io_failure::
- ~file_io_failure () throw ()
- {
- }
-
- void file_io_failure::
- print (::std::ostream& os) const
- {
- os << "unable to open file '" << file ().c_str () << "' or read failure";
- }
-
- const char* file_io_failure::
- what () const throw ()
- {
- return "unable to open file or read failure";
- }
-
- // unmatched_quote
- //
- unmatched_quote::
- ~unmatched_quote () throw ()
- {
- }
-
- void unmatched_quote::
- print (::std::ostream& os) const
- {
- os << "unmatched quote in argument '" << argument ().c_str () << "'";
- }
-
- const char* unmatched_quote::
- what () const throw ()
- {
- return "unmatched quote";
- }
-
- // scanner
- //
- scanner::
- ~scanner ()
- {
- }
-
- // argv_scanner
- //
- bool argv_scanner::
- more ()
- {
- return i_ < argc_;
- }
-
- const char* argv_scanner::
- peek ()
- {
- if (i_ < argc_)
- return argv_[i_];
- else
- throw eos_reached ();
- }
-
- const char* argv_scanner::
- next ()
- {
- if (i_ < argc_)
- {
- const char* r (argv_[i_]);
-
- if (erase_)
- {
- for (int i (i_ + 1); i < argc_; ++i)
- argv_[i - 1] = argv_[i];
-
- --argc_;
- argv_[argc_] = 0;
- }
- else
- ++i_;
-
- ++start_position_;
- return r;
- }
- else
- throw eos_reached ();
- }
-
- void argv_scanner::
- 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;
- std::string argv_file_scanner::empty_string_;
-
- bool argv_file_scanner::
- more ()
- {
- if (!args_.empty ())
- return true;
-
- while (base::more ())
- {
- // See if the next argument is the file option.
- //
- const char* a (base::peek ());
- const option_info* oi = 0;
- const char* ov = 0;
-
- if (!skip_)
- {
- if ((oi = find (a)) != 0)
- {
- base::next ();
-
- if (!base::more ())
- throw missing_value (a);
-
- ov = base::next ();
- }
- else if (std::strncmp (a, "-", 1) == 0)
- {
- if ((ov = std::strchr (a, '=')) != 0)
- {
- std::string o (a, 0, ov - a);
- if ((oi = find (o.c_str ())) != 0)
- {
- base::next ();
- ++ov;
- }
- }
- }
- }
-
- if (oi != 0)
- {
- if (oi->search_func != 0)
- {
- std::string f (oi->search_func (ov, oi->arg));
-
- if (!f.empty ())
- load (f);
- }
- else
- load (ov);
-
- if (!args_.empty ())
- return true;
- }
- else
- {
- if (!skip_)
- skip_ = (std::strcmp (a, "--") == 0);
-
- return true;
- }
- }
-
- return false;
- }
-
- const char* argv_file_scanner::
- peek ()
- {
- if (!more ())
- throw eos_reached ();
-
- return args_.empty () ? base::peek () : args_.front ().value.c_str ();
- }
-
- const std::string& argv_file_scanner::
- peek_file ()
- {
- if (!more ())
- throw eos_reached ();
-
- return args_.empty () ? empty_string_ : *args_.front ().file;
- }
-
- std::size_t argv_file_scanner::
- peek_line ()
- {
- if (!more ())
- throw eos_reached ();
-
- return args_.empty () ? 0 : args_.front ().line;
- }
-
- const char* argv_file_scanner::
- next ()
- {
- if (!more ())
- throw eos_reached ();
-
- if (args_.empty ())
- return base::next ();
- else
- {
- hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ().value);
- args_.pop_front ();
- ++start_position_;
- return hold_[i_].c_str ();
- }
- }
-
- void argv_file_scanner::
- skip ()
- {
- if (!more ())
- throw eos_reached ();
-
- if (args_.empty ())
- return base::skip ();
- else
- {
- args_.pop_front ();
- ++start_position_;
- }
- }
-
- const argv_file_scanner::option_info* argv_file_scanner::
- find (const char* a) const
- {
- for (std::size_t i (0); i < options_count_; ++i)
- if (std::strcmp (a, options_[i].option) == 0)
- return &options_[i];
-
- return 0;
- }
-
- std::size_t argv_file_scanner::
- position ()
- {
- return start_position_;
- }
-
- void argv_file_scanner::
- load (const std::string& file)
- {
- using namespace std;
-
- ifstream is (file.c_str ());
-
- if (!is.is_open ())
- throw file_io_failure (file);
-
- files_.push_back (file);
-
- arg a;
- a.file = &*files_.rbegin ();
-
- for (a.line = 1; !is.eof (); ++a.line)
- {
- string line;
- getline (is, line);
-
- if (is.fail () && !is.eof ())
- throw file_io_failure (file);
-
- string::size_type n (line.size ());
-
- // Trim the line from leading and trailing whitespaces.
- //
- if (n != 0)
- {
- const char* f (line.c_str ());
- const char* l (f + n);
-
- const char* of (f);
- while (f < l && (*f == ' ' || *f == '\t' || *f == '\r'))
- ++f;
-
- --l;
-
- const char* ol (l);
- while (l > f && (*l == ' ' || *l == '\t' || *l == '\r'))
- --l;
-
- if (f != of || l != ol)
- line = f <= l ? string (f, l - f + 1) : string ();
- }
-
- // Ignore empty lines, those that start with #.
- //
- if (line.empty () || line[0] == '#')
- continue;
-
- string::size_type p (string::npos);
- if (line.compare (0, 1, "-") == 0)
- {
- p = line.find (' ');
-
- string::size_type q (line.find ('='));
- if (q != string::npos && q < p)
- p = q;
- }
-
- string s1;
- if (p != string::npos)
- {
- s1.assign (line, 0, p);
-
- // Skip leading whitespaces in the argument.
- //
- if (line[p] == '=')
- ++p;
- else
- {
- n = line.size ();
- for (++p; p < n; ++p)
- {
- char c (line[p]);
- if (c != ' ' && c != '\t' && c != '\r')
- break;
- }
- }
- }
- else if (!skip_)
- skip_ = (line == "--");
-
- string s2 (line, p != string::npos ? p : 0);
-
- // If the string (which is an option value or argument) is
- // wrapped in quotes, remove them.
- //
- n = s2.size ();
- char cf (s2[0]), cl (s2[n - 1]);
-
- if (cf == '"' || cf == '\'' || cl == '"' || cl == '\'')
- {
- if (n == 1 || cf != cl)
- throw unmatched_quote (s2);
-
- s2 = string (s2, 1, n - 2);
- }
-
- if (!s1.empty ())
- {
- // See if this is another file option.
- //
- const option_info* oi;
- if (!skip_ && (oi = find (s1.c_str ())))
- {
- if (s2.empty ())
- throw missing_value (oi->option);
-
- if (oi->search_func != 0)
- {
- string f (oi->search_func (s2.c_str (), oi->arg));
- if (!f.empty ())
- load (f);
- }
- else
- {
- // If the path of the file being parsed is not simple and the
- // path of the file that needs to be loaded is relative, then
- // complete the latter using the former as a base.
- //
-#ifndef _WIN32
- string::size_type p (file.find_last_of ('/'));
- bool c (p != string::npos && s2[0] != '/');
-#else
- string::size_type p (file.find_last_of ("/\\"));
- bool c (p != string::npos && s2[1] != ':');
-#endif
- if (c)
- s2.insert (0, file, 0, p + 1);
-
- load (s2);
- }
-
- continue;
- }
-
- a.value = s1;
- args_.push_back (a);
- }
-
- a.value = s2;
- args_.push_back (a);
- }
- }
-
template <typename X>
struct parser
{
diff --git a/libbuild2/b-options.hxx b/libbuild2/b-options.hxx
index dda9f08..3f8fed7 100644
--- a/libbuild2/b-options.hxx
+++ b/libbuild2/b-options.hxx
@@ -13,428 +13,12 @@
//
// End prologue.
-#include <list>
-#include <deque>
-#include <iosfwd>
-#include <string>
-#include <cstddef>
-#include <exception>
-
-#ifndef CLI_POTENTIALLY_UNUSED
-# if defined(_MSC_VER) || defined(__xlC__)
-# define CLI_POTENTIALLY_UNUSED(x) (void*)&x
-# else
-# define CLI_POTENTIALLY_UNUSED(x) (void)x
-# endif
-#endif
-
-namespace build2
-{
- namespace build
- {
- namespace cli
- {
- class usage_para
- {
- public:
- enum value
- {
- none,
- text,
- option
- };
-
- usage_para (value);
-
- operator value () const
- {
- return v_;
- }
-
- private:
- value v_;
- };
-
- class unknown_mode
- {
- public:
- enum value
- {
- skip,
- stop,
- fail
- };
-
- unknown_mode (value);
-
- operator value () const
- {
- return v_;
- }
-
- private:
- value v_;
- };
-
- // Exceptions.
- //
-
- class LIBBUILD2_SYMEXPORT exception: public std::exception
- {
- public:
- virtual void
- print (::std::ostream&) const = 0;
- };
-
- ::std::ostream&
- operator<< (::std::ostream&, const exception&);
-
- class LIBBUILD2_SYMEXPORT unknown_option: public exception
- {
- public:
- virtual
- ~unknown_option () throw ();
-
- unknown_option (const std::string& option);
-
- const std::string&
- option () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string option_;
- };
-
- class LIBBUILD2_SYMEXPORT unknown_argument: public exception
- {
- public:
- virtual
- ~unknown_argument () throw ();
-
- unknown_argument (const std::string& argument);
-
- const std::string&
- argument () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string argument_;
- };
-
- class LIBBUILD2_SYMEXPORT missing_value: public exception
- {
- public:
- virtual
- ~missing_value () throw ();
-
- missing_value (const std::string& option);
-
- const std::string&
- option () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string option_;
- };
-
- class LIBBUILD2_SYMEXPORT invalid_value: public exception
- {
- public:
- virtual
- ~invalid_value () throw ();
-
- invalid_value (const std::string& option,
- const std::string& value,
- const std::string& message = std::string ());
-
- const std::string&
- option () const;
-
- const std::string&
- value () const;
-
- const std::string&
- message () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string option_;
- std::string value_;
- std::string message_;
- };
-
- class LIBBUILD2_SYMEXPORT eos_reached: public exception
- {
- public:
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
- };
-
- class LIBBUILD2_SYMEXPORT file_io_failure: public exception
- {
- public:
- virtual
- ~file_io_failure () throw ();
-
- file_io_failure (const std::string& file);
-
- const std::string&
- file () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string file_;
- };
-
- class LIBBUILD2_SYMEXPORT unmatched_quote: public exception
- {
- public:
- virtual
- ~unmatched_quote () throw ();
-
- unmatched_quote (const std::string& argument);
-
- const std::string&
- argument () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string argument_;
- };
-
- // Command line argument scanner interface.
- //
- // The values returned by next() are guaranteed to be valid
- // 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 LIBBUILD2_SYMEXPORT scanner
- {
- public:
- virtual
- ~scanner ();
-
- virtual bool
- more () = 0;
-
- virtual const char*
- peek () = 0;
-
- virtual const char*
- next () = 0;
-
- virtual void
- skip () = 0;
-
- virtual std::size_t
- position () = 0;
- };
-
- class LIBBUILD2_SYMEXPORT argv_scanner: public scanner
- {
- public:
- 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;
-
- virtual bool
- more ();
-
- virtual const char*
- peek ();
-
- virtual const char*
- next ();
-
- virtual void
- skip ();
-
- virtual std::size_t
- position ();
-
- protected:
- std::size_t start_position_;
- int i_;
- int& argc_;
- char** argv_;
- bool erase_;
- };
-
- class LIBBUILD2_SYMEXPORT argv_file_scanner: public argv_scanner
- {
- public:
- argv_file_scanner (int& argc,
- char** argv,
- const std::string& option,
- 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,
- std::size_t start_position = 0);
-
- argv_file_scanner (const std::string& file,
- const std::string& option,
- std::size_t start_position = 0);
-
- struct option_info
- {
- // If search_func is not NULL, it is called, with the arg
- // value as the second argument, to locate the options file.
- // If it returns an empty string, then the file is ignored.
- //
- const char* option;
- std::string (*search_func) (const char*, void* arg);
- void* arg;
- };
-
- argv_file_scanner (int& argc,
- char** argv,
- const option_info* options,
- std::size_t options_count,
- 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,
- 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 start_position = 0);
-
- virtual bool
- more ();
-
- virtual const char*
- peek ();
-
- virtual const char*
- next ();
-
- 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.
- //
- const std::string&
- peek_file ();
-
- // Return the 1-based line number if the peeked at argument came from
- // a file and zero otherwise.
- //
- std::size_t
- peek_line ();
-
- private:
- const option_info*
- find (const char*) const;
-
- void
- load (const std::string& file);
-
- typedef argv_scanner base;
-
- const std::string option_;
- option_info option_info_;
- const option_info* options_;
- std::size_t options_count_;
-
- struct arg
- {
- std::string value;
- const std::string* file;
- std::size_t line;
- };
-
- std::deque<arg> args_;
- std::list<std::string> files_;
-
- // Circular buffer of two arguments.
- //
- std::string hold_[2];
- std::size_t i_;
-
- bool skip_;
-
- static int zero_argc_;
- static std::string empty_string_;
- };
-
- template <typename X>
- struct parser;
- }
- }
-}
-
#include <set>
#include <libbuild2/types.hxx>
+#include <libbuild2/common-options.hxx>
+
namespace build2
{
class LIBBUILD2_SYMEXPORT options
diff --git a/libbuild2/b-options.ixx b/libbuild2/b-options.ixx
index 62c8299..0875dbd 100644
--- a/libbuild2/b-options.ixx
+++ b/libbuild2/b-options.ixx
@@ -9,276 +9,6 @@
//
// End prologue.
-#include <cassert>
-
-namespace build2
-{
- namespace build
- {
- namespace cli
- {
- // usage_para
- //
- inline usage_para::
- usage_para (value v)
- : v_ (v)
- {
- }
-
- // unknown_mode
- //
- inline unknown_mode::
- unknown_mode (value v)
- : v_ (v)
- {
- }
-
- // exception
- //
- inline ::std::ostream&
- operator<< (::std::ostream& os, const exception& e)
- {
- e.print (os);
- return os;
- }
-
- // unknown_option
- //
- inline unknown_option::
- unknown_option (const std::string& option)
- : option_ (option)
- {
- }
-
- inline const std::string& unknown_option::
- option () const
- {
- return option_;
- }
-
- // unknown_argument
- //
- inline unknown_argument::
- unknown_argument (const std::string& argument)
- : argument_ (argument)
- {
- }
-
- inline const std::string& unknown_argument::
- argument () const
- {
- return argument_;
- }
-
- // missing_value
- //
- inline missing_value::
- missing_value (const std::string& option)
- : option_ (option)
- {
- }
-
- inline const std::string& missing_value::
- option () const
- {
- return option_;
- }
-
- // invalid_value
- //
- inline invalid_value::
- invalid_value (const std::string& option,
- const std::string& value,
- const std::string& message)
- : option_ (option),
- value_ (value),
- message_ (message)
- {
- }
-
- inline const std::string& invalid_value::
- option () const
- {
- return option_;
- }
-
- inline const std::string& invalid_value::
- value () const
- {
- return value_;
- }
-
- inline const std::string& invalid_value::
- message () const
- {
- return message_;
- }
-
- // file_io_failure
- //
- inline file_io_failure::
- file_io_failure (const std::string& file)
- : file_ (file)
- {
- }
-
- inline const std::string& file_io_failure::
- file () const
- {
- return file_;
- }
-
- // unmatched_quote
- //
- inline unmatched_quote::
- unmatched_quote (const std::string& argument)
- : argument_ (argument)
- {
- }
-
- inline const std::string& unmatched_quote::
- argument () const
- {
- return argument_;
- }
-
- // argv_scanner
- //
- inline argv_scanner::
- 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,
- std::size_t sp)
- : start_position_ (sp + static_cast<std::size_t> (start)),
- i_ (start),
- argc_ (argc),
- argv_ (argv),
- erase_ (erase)
- {
- }
-
- inline int argv_scanner::
- end () const
- {
- return i_;
- }
-
- // argv_file_scanner
- //
- inline argv_file_scanner::
- argv_file_scanner (int& argc,
- char** argv,
- const std::string& option,
- bool erase,
- std::size_t sp)
- : argv_scanner (argc, argv, erase, sp),
- option_ (option),
- options_ (&option_info_),
- options_count_ (1),
- i_ (1),
- skip_ (false)
- {
- option_info_.option = option_.c_str ();
- option_info_.search_func = 0;
- }
-
- inline argv_file_scanner::
- argv_file_scanner (int start,
- int& argc,
- char** argv,
- const std::string& option,
- bool erase,
- std::size_t sp)
- : argv_scanner (start, argc, argv, erase, sp),
- option_ (option),
- options_ (&option_info_),
- options_count_ (1),
- i_ (1),
- skip_ (false)
- {
- option_info_.option = option_.c_str ();
- option_info_.search_func = 0;
- }
-
- inline argv_file_scanner::
- argv_file_scanner (const std::string& file,
- const std::string& option,
- std::size_t sp)
- : argv_scanner (0, zero_argc_, 0, sp),
- option_ (option),
- options_ (&option_info_),
- options_count_ (1),
- i_ (1),
- skip_ (false)
- {
- option_info_.option = option_.c_str ();
- option_info_.search_func = 0;
-
- load (file);
- }
-
- inline argv_file_scanner::
- argv_file_scanner (int& argc,
- char** argv,
- const option_info* options,
- std::size_t options_count,
- bool erase,
- std::size_t sp)
- : argv_scanner (argc, argv, erase, sp),
- options_ (options),
- options_count_ (options_count),
- i_ (1),
- skip_ (false)
- {
- }
-
- inline argv_file_scanner::
- argv_file_scanner (int start,
- int& argc,
- char** argv,
- const option_info* options,
- std::size_t options_count,
- bool erase,
- std::size_t sp)
- : argv_scanner (start, argc, argv, erase, sp),
- options_ (options),
- options_count_ (options_count),
- i_ (1),
- skip_ (false)
- {
- }
-
- inline argv_file_scanner::
- argv_file_scanner (const std::string& file,
- const option_info* options,
- std::size_t options_count,
- std::size_t sp)
- : argv_scanner (0, zero_argc_, 0, sp),
- options_ (options),
- options_count_ (options_count),
- i_ (1),
- skip_ (false)
- {
- load (file);
- }
- }
- }
-}
-
namespace build2
{
// options
diff --git a/libbuild2/b.cli b/libbuild2/b.cli
index 112db2b..78eb165 100644
--- a/libbuild2/b.cli
+++ b/libbuild2/b.cli
@@ -1,9 +1,11 @@
-// file : build2/b.cli
+// file : libbuild2/b.cli
// license : MIT; see accompanying LICENSE file
include <set>;
include <libbuild2/types.hxx>;
+include <libbuild2/common.cli>;
+
"\section=1"
"\name=b"
"\summary=build system driver"
diff --git a/libbuild2/build/script/builtin-options.cxx b/libbuild2/build/script/builtin-options.cxx
index 04cd1c2..6fae0b4 100644
--- a/libbuild2/build/script/builtin-options.cxx
+++ b/libbuild2/build/script/builtin-options.cxx
@@ -6,7 +6,7 @@
// Begin prologue.
//
-#include <libbuild2/build/script/types-parsers.hxx>
+#include <libbuild2/types-parsers.hxx>
//
// End prologue.
@@ -24,365 +24,160 @@ namespace build2
{
namespace build
{
- namespace script
+ namespace cli
{
- namespace cli
+ template <typename X>
+ struct parser
{
- // unknown_option
- //
- unknown_option::
- ~unknown_option () throw ()
- {
- }
-
- void unknown_option::
- print (::std::ostream& os) const
- {
- os << "unknown option '" << option ().c_str () << "'";
- }
-
- const char* unknown_option::
- what () const throw ()
- {
- return "unknown option";
- }
-
- // unknown_argument
- //
- unknown_argument::
- ~unknown_argument () throw ()
- {
- }
-
- void unknown_argument::
- print (::std::ostream& os) const
- {
- os << "unknown argument '" << argument ().c_str () << "'";
- }
-
- const char* unknown_argument::
- what () const throw ()
- {
- return "unknown argument";
- }
-
- // missing_value
- //
- missing_value::
- ~missing_value () throw ()
- {
- }
-
- void missing_value::
- print (::std::ostream& os) const
- {
- os << "missing value for option '" << option ().c_str () << "'";
- }
-
- const char* missing_value::
- what () const throw ()
- {
- return "missing option value";
- }
-
- // invalid_value
- //
- invalid_value::
- ~invalid_value () throw ()
- {
- }
-
- void invalid_value::
- print (::std::ostream& os) const
+ static void
+ parse (X& x, bool& xs, scanner& s)
{
- os << "invalid value '" << value ().c_str () << "' for option '"
- << option ().c_str () << "'";
+ using namespace std;
- if (!message ().empty ())
- os << ": " << message ().c_str ();
- }
-
- const char* invalid_value::
- what () const throw ()
- {
- return "invalid option value";
- }
-
- // eos_reached
- //
- void eos_reached::
- print (::std::ostream& os) const
- {
- os << what ();
- }
-
- const char* eos_reached::
- what () const throw ()
- {
- return "end of argument stream reached";
- }
-
- // scanner
- //
- scanner::
- ~scanner ()
- {
- }
-
- // argv_scanner
- //
- bool argv_scanner::
- more ()
- {
- return i_ < argc_;
- }
-
- const char* argv_scanner::
- peek ()
- {
- if (i_ < argc_)
- return argv_[i_];
- else
- throw eos_reached ();
- }
-
- const char* argv_scanner::
- next ()
- {
- if (i_ < argc_)
+ const char* o (s.next ());
+ if (s.more ())
{
- const char* r (argv_[i_]);
-
- if (erase_)
- {
- for (int i (i_ + 1); i < argc_; ++i)
- argv_[i - 1] = argv_[i];
-
- --argc_;
- argv_[argc_] = 0;
- }
- else
- ++i_;
-
- ++start_position_;
- return r;
+ string v (s.next ());
+ istringstream is (v);
+ if (!(is >> x && is.peek () == istringstream::traits_type::eof ()))
+ throw invalid_value (o, v);
}
else
- throw eos_reached ();
- }
+ throw missing_value (o);
- void argv_scanner::
- skip ()
- {
- if (i_ < argc_)
- {
- ++i_;
- ++start_position_;
- }
- else
- throw eos_reached ();
+ xs = true;
}
+ };
- std::size_t argv_scanner::
- position ()
+ template <>
+ struct parser<bool>
+ {
+ static void
+ parse (bool& x, scanner& s)
{
- return start_position_;
+ s.next ();
+ x = true;
}
+ };
- // vector_scanner
- //
- bool vector_scanner::
- more ()
+ template <>
+ struct parser<std::string>
+ {
+ static void
+ parse (std::string& x, bool& xs, scanner& s)
{
- return i_ < v_.size ();
- }
+ const char* o (s.next ());
- const char* vector_scanner::
- peek ()
- {
- if (i_ < v_.size ())
- return v_[i_].c_str ();
+ if (s.more ())
+ x = s.next ();
else
- throw eos_reached ();
- }
+ throw missing_value (o);
- const char* vector_scanner::
- next ()
- {
- if (i_ < v_.size ())
- return v_[i_++].c_str ();
- else
- throw eos_reached ();
+ xs = true;
}
+ };
- void vector_scanner::
- skip ()
+ 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)
{
- if (i_ < v_.size ())
- ++i_;
- else
- throw eos_reached ();
+ x.second = s.position ();
+ parser<X>::parse (x.first, xs, s);
}
+ };
- std::size_t vector_scanner::
- position ()
- {
- return start_position_ + i_;
+ template <typename X>
+ struct parser<std::vector<X> >
+ {
+ static void
+ parse (std::vector<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.push_back (x);
+ xs = true;
}
+ };
- template <typename X>
- struct parser
- {
- static void
- parse (X& x, bool& xs, scanner& s)
- {
- using namespace std;
-
- const char* o (s.next ());
- if (s.more ())
- {
- string v (s.next ());
- istringstream is (v);
- if (!(is >> x && is.peek () == istringstream::traits_type::eof ()))
- throw invalid_value (o, v);
- }
- else
- throw missing_value (o);
-
- xs = true;
- }
- };
+ template <typename X, typename C>
+ struct parser<std::set<X, C> >
+ {
+ static void
+ parse (std::set<X, C>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.insert (x);
+ xs = true;
+ }
+ };
- template <>
- struct parser<bool>
+ template <typename K, typename V, typename C>
+ struct parser<std::map<K, V, C> >
+ {
+ static void
+ parse (std::map<K, V, C>& m, bool& xs, scanner& s)
{
- static void
- parse (bool& x, scanner& s)
- {
- s.next ();
- x = true;
- }
- };
+ const char* o (s.next ());
- template <>
- struct parser<std::string>
- {
- static void
- parse (std::string& x, bool& xs, scanner& s)
+ if (s.more ())
{
- const char* o (s.next ());
+ std::size_t pos (s.position ());
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
- if (s.more ())
- x = s.next ();
- else
- throw missing_value (o);
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
- xs = true;
- }
- };
-
- 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
- parse (std::vector<X>& c, bool& xs, scanner& s)
- {
- X x;
- bool dummy;
- parser<X>::parse (x, dummy, s);
- c.push_back (x);
- xs = true;
- }
- };
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
- template <typename X, typename C>
- struct parser<std::set<X, C> >
- {
- static void
- parse (std::set<X, C>& c, bool& xs, scanner& s)
- {
- X x;
bool dummy;
- parser<X>::parse (x, dummy, s);
- c.insert (x);
- xs = true;
- }
- };
-
- template <typename K, typename V, typename C>
- struct parser<std::map<K, V, C> >
- {
- static void
- parse (std::map<K, V, C>& m, bool& xs, scanner& s)
- {
- const char* o (s.next ());
-
- if (s.more ())
+ if (!kstr.empty ())
{
- std::size_t pos (s.position ());
- std::string ov (s.next ());
- std::string::size_type p = ov.find ('=');
-
- K k = K ();
- V v = V ();
- std::string kstr (ov, 0, p);
- std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
-
- int ac (2);
- char* av[] =
- {
- const_cast<char*> (o),
- 0
- };
-
- bool dummy;
- if (!kstr.empty ())
- {
- av[1] = const_cast<char*> (kstr.c_str ());
- 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, false, pos);
- parser<V>::parse (v, dummy, s);
- }
+ av[1] = const_cast<char*> (kstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<K>::parse (k, dummy, s);
+ }
- m[k] = v;
+ if (!vstr.empty ())
+ {
+ av[1] = const_cast<char*> (vstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<V>::parse (v, dummy, s);
}
- else
- throw missing_value (o);
- xs = true;
+ m[k] = v;
}
- };
+ else
+ throw missing_value (o);
- template <typename X, typename T, T X::*M>
- void
- thunk (X& x, scanner& s)
- {
- parser<T>::parse (x.*M, s);
+ xs = true;
}
+ };
- template <typename X, typename T, T X::*M, bool X::*S>
- void
- thunk (X& x, scanner& s)
- {
- parser<T>::parse (x.*M, x.*S, s);
- }
+ template <typename X, typename T, T X::*M>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, s);
+ }
+
+ template <typename X, typename T, T X::*M, bool X::*S>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, x.*S, s);
}
}
}
@@ -423,10 +218,10 @@ namespace build2
parse (int& argc,
char** argv,
bool erase,
- ::build2::build::script::cli::unknown_mode opt,
- ::build2::build::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
{
- ::build2::build::script::cli::argv_scanner s (argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (argc, argv, erase);
bool r = _parse (s, opt, arg);
return r;
}
@@ -436,10 +231,10 @@ namespace build2
int& argc,
char** argv,
bool erase,
- ::build2::build::script::cli::unknown_mode opt,
- ::build2::build::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
{
- ::build2::build::script::cli::argv_scanner s (start, argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (start, argc, argv, erase);
bool r = _parse (s, opt, arg);
return r;
}
@@ -449,10 +244,10 @@ namespace build2
char** argv,
int& end,
bool erase,
- ::build2::build::script::cli::unknown_mode opt,
- ::build2::build::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
{
- ::build2::build::script::cli::argv_scanner s (argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (argc, argv, erase);
bool r = _parse (s, opt, arg);
end = s.end ();
return r;
@@ -464,26 +259,26 @@ namespace build2
char** argv,
int& end,
bool erase,
- ::build2::build::script::cli::unknown_mode opt,
- ::build2::build::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
{
- ::build2::build::script::cli::argv_scanner s (start, argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (start, argc, argv, erase);
bool r = _parse (s, opt, arg);
end = s.end ();
return r;
}
bool depdb_dyndep_options::
- parse (::build2::build::script::cli::scanner& s,
- ::build2::build::script::cli::unknown_mode opt,
- ::build2::build::script::cli::unknown_mode arg)
+ parse (::build2::build::cli::scanner& s,
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
{
bool r = _parse (s, opt, arg);
return r;
}
typedef
- std::map<std::string, void (*) (depdb_dyndep_options&, ::build2::build::script::cli::scanner&)>
+ std::map<std::string, void (*) (depdb_dyndep_options&, ::build2::build::cli::scanner&)>
_cli_depdb_dyndep_options_map;
static _cli_depdb_dyndep_options_map _cli_depdb_dyndep_options_map_;
@@ -493,37 +288,37 @@ namespace build2
_cli_depdb_dyndep_options_map_init ()
{
_cli_depdb_dyndep_options_map_["--file"] =
- &::build2::build::script::cli::thunk< depdb_dyndep_options, path, &depdb_dyndep_options::file_,
+ &::build2::build::cli::thunk< depdb_dyndep_options, path, &depdb_dyndep_options::file_,
&depdb_dyndep_options::file_specified_ >;
_cli_depdb_dyndep_options_map_["--format"] =
- &::build2::build::script::cli::thunk< depdb_dyndep_options, string, &depdb_dyndep_options::format_,
+ &::build2::build::cli::thunk< depdb_dyndep_options, string, &depdb_dyndep_options::format_,
&depdb_dyndep_options::format_specified_ >;
_cli_depdb_dyndep_options_map_["--what"] =
- &::build2::build::script::cli::thunk< depdb_dyndep_options, string, &depdb_dyndep_options::what_,
+ &::build2::build::cli::thunk< depdb_dyndep_options, string, &depdb_dyndep_options::what_,
&depdb_dyndep_options::what_specified_ >;
_cli_depdb_dyndep_options_map_["--include-path"] =
- &::build2::build::script::cli::thunk< depdb_dyndep_options, dir_paths, &depdb_dyndep_options::include_path_,
+ &::build2::build::cli::thunk< depdb_dyndep_options, dir_paths, &depdb_dyndep_options::include_path_,
&depdb_dyndep_options::include_path_specified_ >;
_cli_depdb_dyndep_options_map_["-I"] =
- &::build2::build::script::cli::thunk< depdb_dyndep_options, dir_paths, &depdb_dyndep_options::include_path_,
+ &::build2::build::cli::thunk< depdb_dyndep_options, dir_paths, &depdb_dyndep_options::include_path_,
&depdb_dyndep_options::include_path_specified_ >;
_cli_depdb_dyndep_options_map_["--default-type"] =
- &::build2::build::script::cli::thunk< depdb_dyndep_options, string, &depdb_dyndep_options::default_type_,
+ &::build2::build::cli::thunk< depdb_dyndep_options, string, &depdb_dyndep_options::default_type_,
&depdb_dyndep_options::default_type_specified_ >;
_cli_depdb_dyndep_options_map_["--adhoc"] =
- &::build2::build::script::cli::thunk< depdb_dyndep_options, bool, &depdb_dyndep_options::adhoc_ >;
+ &::build2::build::cli::thunk< depdb_dyndep_options, bool, &depdb_dyndep_options::adhoc_ >;
_cli_depdb_dyndep_options_map_["--cwd"] =
- &::build2::build::script::cli::thunk< depdb_dyndep_options, dir_path, &depdb_dyndep_options::cwd_,
+ &::build2::build::cli::thunk< depdb_dyndep_options, dir_path, &depdb_dyndep_options::cwd_,
&depdb_dyndep_options::cwd_specified_ >;
_cli_depdb_dyndep_options_map_["--drop-cycles"] =
- &::build2::build::script::cli::thunk< depdb_dyndep_options, bool, &depdb_dyndep_options::drop_cycles_ >;
+ &::build2::build::cli::thunk< depdb_dyndep_options, bool, &depdb_dyndep_options::drop_cycles_ >;
}
};
static _cli_depdb_dyndep_options_map_init _cli_depdb_dyndep_options_map_init_;
bool depdb_dyndep_options::
- _parse (const char* o, ::build2::build::script::cli::scanner& s)
+ _parse (const char* o, ::build2::build::cli::scanner& s)
{
_cli_depdb_dyndep_options_map::const_iterator i (_cli_depdb_dyndep_options_map_.find (o));
@@ -537,13 +332,13 @@ namespace build2
}
bool depdb_dyndep_options::
- _parse (::build2::build::script::cli::scanner& s,
- ::build2::build::script::cli::unknown_mode opt_mode,
- ::build2::build::script::cli::unknown_mode arg_mode)
+ _parse (::build2::build::cli::scanner& s,
+ ::build2::build::cli::unknown_mode opt_mode,
+ ::build2::build::cli::unknown_mode arg_mode)
{
// Can't skip combined flags (--no-combined-flags).
//
- assert (opt_mode != ::build2::build::script::cli::unknown_mode::skip);
+ assert (opt_mode != ::build2::build::cli::unknown_mode::skip);
bool r = false;
bool opt = true;
@@ -585,14 +380,14 @@ namespace build2
const_cast<char*> (v)
};
- ::build2::build::script::cli::argv_scanner ns (0, ac, av);
+ ::build2::build::cli::argv_scanner ns (0, ac, av);
if (_parse (co.c_str (), ns))
{
// Parsed the option but not its value?
//
if (ns.end () != 2)
- throw ::build2::build::script::cli::invalid_value (co, v);
+ throw ::build2::build::cli::invalid_value (co, v);
s.next ();
r = true;
@@ -633,7 +428,7 @@ namespace build2
cf
};
- ::build2::build::script::cli::argv_scanner ns (0, ac, av);
+ ::build2::build::cli::argv_scanner ns (0, ac, av);
if (!_parse (cf, ns))
break;
@@ -658,19 +453,19 @@ namespace build2
switch (opt_mode)
{
- case ::build2::build::script::cli::unknown_mode::skip:
+ case ::build2::build::cli::unknown_mode::skip:
{
s.skip ();
r = true;
continue;
}
- case ::build2::build::script::cli::unknown_mode::stop:
+ case ::build2::build::cli::unknown_mode::stop:
{
break;
}
- case ::build2::build::script::cli::unknown_mode::fail:
+ case ::build2::build::cli::unknown_mode::fail:
{
- throw ::build2::build::script::cli::unknown_option (o);
+ throw ::build2::build::cli::unknown_option (o);
}
}
@@ -680,19 +475,19 @@ namespace build2
switch (arg_mode)
{
- case ::build2::build::script::cli::unknown_mode::skip:
+ case ::build2::build::cli::unknown_mode::skip:
{
s.skip ();
r = true;
continue;
}
- case ::build2::build::script::cli::unknown_mode::stop:
+ case ::build2::build::cli::unknown_mode::stop:
{
break;
}
- case ::build2::build::script::cli::unknown_mode::fail:
+ case ::build2::build::cli::unknown_mode::fail:
{
- throw ::build2::build::script::cli::unknown_argument (o);
+ throw ::build2::build::cli::unknown_argument (o);
}
}
diff --git a/libbuild2/build/script/builtin-options.hxx b/libbuild2/build/script/builtin-options.hxx
index 60020c9..544daca 100644
--- a/libbuild2/build/script/builtin-options.hxx
+++ b/libbuild2/build/script/builtin-options.hxx
@@ -12,285 +12,10 @@
//
// End prologue.
-#include <vector>
-#include <iosfwd>
-#include <string>
-#include <cstddef>
-#include <exception>
-
-#ifndef CLI_POTENTIALLY_UNUSED
-# if defined(_MSC_VER) || defined(__xlC__)
-# define CLI_POTENTIALLY_UNUSED(x) (void*)&x
-# else
-# define CLI_POTENTIALLY_UNUSED(x) (void)x
-# endif
-#endif
-
-namespace build2
-{
- namespace build
- {
- namespace script
- {
- namespace cli
- {
- class unknown_mode
- {
- public:
- enum value
- {
- skip,
- stop,
- fail
- };
-
- unknown_mode (value);
-
- operator value () const
- {
- return v_;
- }
-
- private:
- value v_;
- };
-
- // Exceptions.
- //
-
- class exception: public std::exception
- {
- public:
- virtual void
- print (::std::ostream&) const = 0;
- };
-
- ::std::ostream&
- operator<< (::std::ostream&, const exception&);
-
- class unknown_option: public exception
- {
- public:
- virtual
- ~unknown_option () throw ();
-
- unknown_option (const std::string& option);
-
- const std::string&
- option () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string option_;
- };
-
- class unknown_argument: public exception
- {
- public:
- virtual
- ~unknown_argument () throw ();
-
- unknown_argument (const std::string& argument);
-
- const std::string&
- argument () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string argument_;
- };
-
- class missing_value: public exception
- {
- public:
- virtual
- ~missing_value () throw ();
-
- missing_value (const std::string& option);
-
- const std::string&
- option () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string option_;
- };
-
- class invalid_value: public exception
- {
- public:
- virtual
- ~invalid_value () throw ();
-
- invalid_value (const std::string& option,
- const std::string& value,
- const std::string& message = std::string ());
-
- const std::string&
- option () const;
-
- const std::string&
- value () const;
-
- const std::string&
- message () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string option_;
- std::string value_;
- std::string message_;
- };
-
- class eos_reached: public exception
- {
- public:
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
- };
-
- // Command line argument scanner interface.
- //
- // The values returned by next() are guaranteed to be valid
- // 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:
- virtual
- ~scanner ();
-
- virtual bool
- more () = 0;
-
- virtual const char*
- peek () = 0;
-
- virtual const char*
- next () = 0;
-
- 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,
- 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;
-
- virtual bool
- more ();
-
- virtual const char*
- peek ();
-
- virtual const char*
- next ();
-
- virtual void
- skip ();
-
- virtual std::size_t
- position ();
-
- protected:
- std::size_t start_position_;
- int i_;
- int& argc_;
- char** argv_;
- bool erase_;
- };
-
- class vector_scanner: public scanner
- {
- public:
- 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, std::size_t start_position = 0);
-
- virtual bool
- more ();
-
- virtual const char*
- peek ();
-
- virtual const char*
- next ();
-
- virtual void
- skip ();
-
- virtual std::size_t
- position ();
-
- private:
- std::size_t start_position_;
- const std::vector<std::string>& v_;
- std::size_t i_;
- };
-
- template <typename X>
- struct parser;
- }
- }
- }
-}
-
#include <libbuild2/types.hxx>
+#include <libbuild2/common-options.hxx>
+
namespace build2
{
namespace build
@@ -308,24 +33,24 @@ namespace build2
parse (int& argc,
char** argv,
bool erase = false,
- ::build2::build::script::cli::unknown_mode option = ::build2::build::script::cli::unknown_mode::fail,
- ::build2::build::script::cli::unknown_mode argument = ::build2::build::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
bool
parse (int start,
int& argc,
char** argv,
bool erase = false,
- ::build2::build::script::cli::unknown_mode option = ::build2::build::script::cli::unknown_mode::fail,
- ::build2::build::script::cli::unknown_mode argument = ::build2::build::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
bool
parse (int& argc,
char** argv,
int& end,
bool erase = false,
- ::build2::build::script::cli::unknown_mode option = ::build2::build::script::cli::unknown_mode::fail,
- ::build2::build::script::cli::unknown_mode argument = ::build2::build::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
bool
parse (int start,
@@ -333,13 +58,13 @@ namespace build2
char** argv,
int& end,
bool erase = false,
- ::build2::build::script::cli::unknown_mode option = ::build2::build::script::cli::unknown_mode::fail,
- ::build2::build::script::cli::unknown_mode argument = ::build2::build::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
bool
- parse (::build2::build::script::cli::scanner&,
- ::build2::build::script::cli::unknown_mode option = ::build2::build::script::cli::unknown_mode::fail,
- ::build2::build::script::cli::unknown_mode argument = ::build2::build::script::cli::unknown_mode::stop);
+ parse (::build2::build::cli::scanner&,
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
// Option accessors and modifiers.
//
@@ -455,13 +180,13 @@ namespace build2
//
protected:
bool
- _parse (const char*, ::build2::build::script::cli::scanner&);
+ _parse (const char*, ::build2::build::cli::scanner&);
private:
bool
- _parse (::build2::build::script::cli::scanner&,
- ::build2::build::script::cli::unknown_mode option,
- ::build2::build::script::cli::unknown_mode argument);
+ _parse (::build2::build::cli::scanner&,
+ ::build2::build::cli::unknown_mode option,
+ ::build2::build::cli::unknown_mode argument);
public:
path file_;
diff --git a/libbuild2/build/script/builtin-options.ixx b/libbuild2/build/script/builtin-options.ixx
index 6f91b2c..ea06a0f 100644
--- a/libbuild2/build/script/builtin-options.ixx
+++ b/libbuild2/build/script/builtin-options.ixx
@@ -9,167 +9,6 @@
//
// End prologue.
-#include <cassert>
-
-namespace build2
-{
- namespace build
- {
- namespace script
- {
- namespace cli
- {
- // unknown_mode
- //
- inline unknown_mode::
- unknown_mode (value v)
- : v_ (v)
- {
- }
-
- // exception
- //
- inline ::std::ostream&
- operator<< (::std::ostream& os, const exception& e)
- {
- e.print (os);
- return os;
- }
-
- // unknown_option
- //
- inline unknown_option::
- unknown_option (const std::string& option)
- : option_ (option)
- {
- }
-
- inline const std::string& unknown_option::
- option () const
- {
- return option_;
- }
-
- // unknown_argument
- //
- inline unknown_argument::
- unknown_argument (const std::string& argument)
- : argument_ (argument)
- {
- }
-
- inline const std::string& unknown_argument::
- argument () const
- {
- return argument_;
- }
-
- // missing_value
- //
- inline missing_value::
- missing_value (const std::string& option)
- : option_ (option)
- {
- }
-
- inline const std::string& missing_value::
- option () const
- {
- return option_;
- }
-
- // invalid_value
- //
- inline invalid_value::
- invalid_value (const std::string& option,
- const std::string& value,
- const std::string& message)
- : option_ (option),
- value_ (value),
- message_ (message)
- {
- }
-
- inline const std::string& invalid_value::
- option () const
- {
- return option_;
- }
-
- inline const std::string& invalid_value::
- value () const
- {
- return value_;
- }
-
- inline const std::string& invalid_value::
- message () const
- {
- return message_;
- }
-
- // argv_scanner
- //
- inline argv_scanner::
- 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,
- std::size_t sp)
- : start_position_ (sp + static_cast<std::size_t> (start)),
- i_ (start),
- argc_ (argc),
- argv_ (argv),
- erase_ (erase)
- {
- }
-
- inline int argv_scanner::
- end () const
- {
- return i_;
- }
-
- // vector_scanner
- //
- inline vector_scanner::
- vector_scanner (const std::vector<std::string>& v,
- std::size_t i,
- std::size_t sp)
- : start_position_ (sp), v_ (v), i_ (i)
- {
- }
-
- inline std::size_t vector_scanner::
- end () const
- {
- return i_;
- }
-
- inline void vector_scanner::
- reset (std::size_t i, std::size_t sp)
- {
- i_ = i;
- start_position_ = sp;
- }
- }
- }
- }
-}
-
namespace build2
{
namespace build
diff --git a/libbuild2/build/script/builtin.cli b/libbuild2/build/script/builtin.cli
index 6292f48..4e2df4b 100644
--- a/libbuild2/build/script/builtin.cli
+++ b/libbuild2/build/script/builtin.cli
@@ -3,6 +3,8 @@
include <libbuild2/types.hxx>;
+include <libbuild2/common.cli>;
+
// Note that options in this file are undocumented because we generate neither
// the usage printing code nor man pages. Instead, they are documented in the
// manual.
diff --git a/libbuild2/build/script/types-parsers.cxx b/libbuild2/build/script/types-parsers.cxx
deleted file mode 100644
index 9ecfa13..0000000
--- a/libbuild2/build/script/types-parsers.cxx
+++ /dev/null
@@ -1,56 +0,0 @@
-// file : libbuild2/build/script/types-parsers.cxx -*- C++ -*-
-// license : MIT; see accompanying LICENSE file
-
-#include <libbuild2/build/script/types-parsers.hxx>
-
-#include <libbuild2/build/script/builtin-options.hxx> // cli namespace
-
-namespace build2
-{
- namespace build
- {
- namespace script
- {
- namespace cli
- {
- template <typename T>
- static void
- parse_path (T& x, scanner& s)
- {
- const char* o (s.next ());
-
- if (!s.more ())
- throw missing_value (o);
-
- const char* v (s.next ());
-
- try
- {
- x = T (v);
-
- if (x.empty ())
- throw invalid_value (o, v);
- }
- catch (const invalid_path&)
- {
- throw invalid_value (o, v);
- }
- }
-
- void parser<path>::
- parse (path& x, bool& xs, scanner& s)
- {
- xs = true;
- parse_path (x, s);
- }
-
- void parser<dir_path>::
- parse (dir_path& x, bool& xs, scanner& s)
- {
- xs = true;
- parse_path (x, s);
- }
- }
- }
- }
-}
diff --git a/libbuild2/build/script/types-parsers.hxx b/libbuild2/build/script/types-parsers.hxx
deleted file mode 100644
index a42dab7..0000000
--- a/libbuild2/build/script/types-parsers.hxx
+++ /dev/null
@@ -1,49 +0,0 @@
-// file : libbuild2/build/script/types-parsers.hxx -*- C++ -*-
-// license : MIT; see accompanying LICENSE file
-
-// CLI parsers, included into the generated source files.
-//
-
-#ifndef LIBBUILD2_BUILD_SCRIPT_TYPES_PARSERS_HXX
-#define LIBBUILD2_BUILD_SCRIPT_TYPES_PARSERS_HXX
-
-#include <libbuild2/types.hxx>
-
-namespace build2
-{
- namespace build
- {
- namespace script
- {
- namespace cli
- {
- class scanner;
-
- template <typename T>
- struct parser;
-
- template <>
- struct parser<path>
- {
- static void
- parse (path&, bool&, scanner&);
-
- static void
- merge (path& b, const path& a) {b = a;}
- };
-
- template <>
- struct parser<dir_path>
- {
- static void
- parse (dir_path&, bool&, scanner&);
-
- static void
- merge (dir_path& b, const dir_path& a) {b = a;}
- };
- }
- }
- }
-}
-
-#endif // LIBBUILD2_BUILD_SCRIPT_TYPES_PARSERS_HXX
diff --git a/libbuild2/buildfile b/libbuild2/buildfile
index 74d7485..b6c59a5 100644
--- a/libbuild2/buildfile
+++ b/libbuild2/buildfile
@@ -27,10 +27,12 @@ intf_libs = $libbutl
lib{build2}: libul{build2}: \
{hxx ixx txx cxx}{* -utility-*installed \
+ -common-options \
-b-options \
-config \
-version \
-*.test...} \
+ {hxx ixx cxx}{common-options} \
{hxx ixx cxx}{b-options} \
{hxx}{config version}
@@ -232,7 +234,7 @@ else
if $cli.configured
{
cli.options += --std c++11 -I $src_root --include-with-brackets \
---generate-specifier
+--cli-namespace build2::build::cli --generate-specifier
cli.cxx{*}:
{
@@ -249,14 +251,21 @@ if $cli.configured
backlink = overwrite
}
+ cli.cxx{common-options}: cli{common}
+ {
+ cli.options += --include-prefix libbuild2 --guard-prefix LIBBUILD2 \
+--export-symbol LIBBUILD2_SYMEXPORT \
+--hxx-prologue '#include <libbuild2/export.hxx>' \
+--generate-file-scanner --generate-vector-scanner
+ }
+
cli.cxx{b-options}: cli{b}
{
- cli.options += --cli-namespace build2::build::cli \
---include-prefix libbuild2 --guard-prefix LIBBUILD2 \
+ cli.options += --include-prefix libbuild2 --guard-prefix LIBBUILD2 \
--export-symbol LIBBUILD2_SYMEXPORT \
--hxx-prologue '#include <libbuild2/export.hxx>' \
--cxx-prologue "#include <libbuild2/types-parsers.hxx>" \
---generate-file-scanner --keep-separator --generate-parse --generate-merge
+--keep-separator --generate-parse --generate-merge
# Usage options.
#
@@ -266,9 +275,8 @@ if $cli.configured
script/cli.cxx{builtin-options}: script/cli{builtin}
{
- cli.options += --cli-namespace build2::script::cli \
---include-prefix libbuild2/script --guard-prefix LIBBUILD2_SCRIPT \
---generate-vector-scanner --generate-modifier --suppress-usage
+ cli.options += --include-prefix libbuild2/script \
+--guard-prefix LIBBUILD2_SCRIPT --generate-modifier --suppress-usage
# Don't install the generated cli headers since they are only used
# internally in the script implementation.
@@ -278,10 +286,10 @@ if $cli.configured
build/script/cli.cxx{builtin-options}: build/script/cli{builtin}
{
- cli.options += --cli-namespace build2::build::script::cli \
---include-prefix libbuild2/build/script --guard-prefix LIBBUILD2_BUILD_SCRIPT \
---cxx-prologue "#include <libbuild2/build/script/types-parsers.hxx>" \
---generate-parse --generate-vector-scanner --generate-modifier --suppress-usage
+ cli.options += --include-prefix libbuild2/build/script \
+--guard-prefix LIBBUILD2_BUILD_SCRIPT \
+--cxx-prologue "#include <libbuild2/types-parsers.hxx>" \
+--generate-parse --generate-modifier --suppress-usage
# Don't install the generated cli headers since they are only used
# internally in the buildscript implementation.
diff --git a/libbuild2/common-options.cxx b/libbuild2/common-options.cxx
new file mode 100644
index 0000000..5c58a62
--- /dev/null
+++ b/libbuild2/common-options.cxx
@@ -0,0 +1,731 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <libbuild2/common-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+#include <fstream>
+
+namespace build2
+{
+ namespace build
+ {
+ namespace cli
+ {
+ // unknown_option
+ //
+ unknown_option::
+ ~unknown_option () throw ()
+ {
+ }
+
+ void unknown_option::
+ print (::std::ostream& os) const
+ {
+ os << "unknown option '" << option ().c_str () << "'";
+ }
+
+ const char* unknown_option::
+ what () const throw ()
+ {
+ return "unknown option";
+ }
+
+ // unknown_argument
+ //
+ unknown_argument::
+ ~unknown_argument () throw ()
+ {
+ }
+
+ void unknown_argument::
+ print (::std::ostream& os) const
+ {
+ os << "unknown argument '" << argument ().c_str () << "'";
+ }
+
+ const char* unknown_argument::
+ what () const throw ()
+ {
+ return "unknown argument";
+ }
+
+ // missing_value
+ //
+ missing_value::
+ ~missing_value () throw ()
+ {
+ }
+
+ void missing_value::
+ print (::std::ostream& os) const
+ {
+ os << "missing value for option '" << option ().c_str () << "'";
+ }
+
+ const char* missing_value::
+ what () const throw ()
+ {
+ return "missing option value";
+ }
+
+ // invalid_value
+ //
+ invalid_value::
+ ~invalid_value () throw ()
+ {
+ }
+
+ void invalid_value::
+ print (::std::ostream& os) const
+ {
+ os << "invalid value '" << value ().c_str () << "' for option '"
+ << option ().c_str () << "'";
+
+ if (!message ().empty ())
+ os << ": " << message ().c_str ();
+ }
+
+ const char* invalid_value::
+ what () const throw ()
+ {
+ return "invalid option value";
+ }
+
+ // eos_reached
+ //
+ void eos_reached::
+ print (::std::ostream& os) const
+ {
+ os << what ();
+ }
+
+ const char* eos_reached::
+ what () const throw ()
+ {
+ return "end of argument stream reached";
+ }
+
+ // file_io_failure
+ //
+ file_io_failure::
+ ~file_io_failure () throw ()
+ {
+ }
+
+ void file_io_failure::
+ print (::std::ostream& os) const
+ {
+ os << "unable to open file '" << file ().c_str () << "' or read failure";
+ }
+
+ const char* file_io_failure::
+ what () const throw ()
+ {
+ return "unable to open file or read failure";
+ }
+
+ // unmatched_quote
+ //
+ unmatched_quote::
+ ~unmatched_quote () throw ()
+ {
+ }
+
+ void unmatched_quote::
+ print (::std::ostream& os) const
+ {
+ os << "unmatched quote in argument '" << argument ().c_str () << "'";
+ }
+
+ const char* unmatched_quote::
+ what () const throw ()
+ {
+ return "unmatched quote";
+ }
+
+ // scanner
+ //
+ scanner::
+ ~scanner ()
+ {
+ }
+
+ // argv_scanner
+ //
+ bool argv_scanner::
+ more ()
+ {
+ return i_ < argc_;
+ }
+
+ const char* argv_scanner::
+ peek ()
+ {
+ if (i_ < argc_)
+ return argv_[i_];
+ else
+ throw eos_reached ();
+ }
+
+ const char* argv_scanner::
+ next ()
+ {
+ if (i_ < argc_)
+ {
+ const char* r (argv_[i_]);
+
+ if (erase_)
+ {
+ for (int i (i_ + 1); i < argc_; ++i)
+ argv_[i - 1] = argv_[i];
+
+ --argc_;
+ argv_[argc_] = 0;
+ }
+ else
+ ++i_;
+
+ ++start_position_;
+ return r;
+ }
+ else
+ throw eos_reached ();
+ }
+
+ void argv_scanner::
+ 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::
+ more ()
+ {
+ return i_ < v_.size ();
+ }
+
+ const char* vector_scanner::
+ peek ()
+ {
+ if (i_ < v_.size ())
+ return v_[i_].c_str ();
+ else
+ throw eos_reached ();
+ }
+
+ const char* vector_scanner::
+ next ()
+ {
+ if (i_ < v_.size ())
+ return v_[i_++].c_str ();
+ else
+ throw eos_reached ();
+ }
+
+ void vector_scanner::
+ skip ()
+ {
+ if (i_ < v_.size ())
+ ++i_;
+ else
+ throw eos_reached ();
+ }
+
+ std::size_t vector_scanner::
+ position ()
+ {
+ return start_position_ + i_;
+ }
+
+ // argv_file_scanner
+ //
+ int argv_file_scanner::zero_argc_ = 0;
+ std::string argv_file_scanner::empty_string_;
+
+ bool argv_file_scanner::
+ more ()
+ {
+ if (!args_.empty ())
+ return true;
+
+ while (base::more ())
+ {
+ // See if the next argument is the file option.
+ //
+ const char* a (base::peek ());
+ const option_info* oi = 0;
+ const char* ov = 0;
+
+ if (!skip_)
+ {
+ if ((oi = find (a)) != 0)
+ {
+ base::next ();
+
+ if (!base::more ())
+ throw missing_value (a);
+
+ ov = base::next ();
+ }
+ else if (std::strncmp (a, "-", 1) == 0)
+ {
+ if ((ov = std::strchr (a, '=')) != 0)
+ {
+ std::string o (a, 0, ov - a);
+ if ((oi = find (o.c_str ())) != 0)
+ {
+ base::next ();
+ ++ov;
+ }
+ }
+ }
+ }
+
+ if (oi != 0)
+ {
+ if (oi->search_func != 0)
+ {
+ std::string f (oi->search_func (ov, oi->arg));
+
+ if (!f.empty ())
+ load (f);
+ }
+ else
+ load (ov);
+
+ if (!args_.empty ())
+ return true;
+ }
+ else
+ {
+ if (!skip_)
+ skip_ = (std::strcmp (a, "--") == 0);
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ const char* argv_file_scanner::
+ peek ()
+ {
+ if (!more ())
+ throw eos_reached ();
+
+ return args_.empty () ? base::peek () : args_.front ().value.c_str ();
+ }
+
+ const std::string& argv_file_scanner::
+ peek_file ()
+ {
+ if (!more ())
+ throw eos_reached ();
+
+ return args_.empty () ? empty_string_ : *args_.front ().file;
+ }
+
+ std::size_t argv_file_scanner::
+ peek_line ()
+ {
+ if (!more ())
+ throw eos_reached ();
+
+ return args_.empty () ? 0 : args_.front ().line;
+ }
+
+ const char* argv_file_scanner::
+ next ()
+ {
+ if (!more ())
+ throw eos_reached ();
+
+ if (args_.empty ())
+ return base::next ();
+ else
+ {
+ hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ().value);
+ args_.pop_front ();
+ ++start_position_;
+ return hold_[i_].c_str ();
+ }
+ }
+
+ void argv_file_scanner::
+ skip ()
+ {
+ if (!more ())
+ throw eos_reached ();
+
+ if (args_.empty ())
+ return base::skip ();
+ else
+ {
+ args_.pop_front ();
+ ++start_position_;
+ }
+ }
+
+ const argv_file_scanner::option_info* argv_file_scanner::
+ find (const char* a) const
+ {
+ for (std::size_t i (0); i < options_count_; ++i)
+ if (std::strcmp (a, options_[i].option) == 0)
+ return &options_[i];
+
+ return 0;
+ }
+
+ std::size_t argv_file_scanner::
+ position ()
+ {
+ return start_position_;
+ }
+
+ void argv_file_scanner::
+ load (const std::string& file)
+ {
+ using namespace std;
+
+ ifstream is (file.c_str ());
+
+ if (!is.is_open ())
+ throw file_io_failure (file);
+
+ files_.push_back (file);
+
+ arg a;
+ a.file = &*files_.rbegin ();
+
+ for (a.line = 1; !is.eof (); ++a.line)
+ {
+ string line;
+ getline (is, line);
+
+ if (is.fail () && !is.eof ())
+ throw file_io_failure (file);
+
+ string::size_type n (line.size ());
+
+ // Trim the line from leading and trailing whitespaces.
+ //
+ if (n != 0)
+ {
+ const char* f (line.c_str ());
+ const char* l (f + n);
+
+ const char* of (f);
+ while (f < l && (*f == ' ' || *f == '\t' || *f == '\r'))
+ ++f;
+
+ --l;
+
+ const char* ol (l);
+ while (l > f && (*l == ' ' || *l == '\t' || *l == '\r'))
+ --l;
+
+ if (f != of || l != ol)
+ line = f <= l ? string (f, l - f + 1) : string ();
+ }
+
+ // Ignore empty lines, those that start with #.
+ //
+ if (line.empty () || line[0] == '#')
+ continue;
+
+ string::size_type p (string::npos);
+ if (line.compare (0, 1, "-") == 0)
+ {
+ p = line.find (' ');
+
+ string::size_type q (line.find ('='));
+ if (q != string::npos && q < p)
+ p = q;
+ }
+
+ string s1;
+ if (p != string::npos)
+ {
+ s1.assign (line, 0, p);
+
+ // Skip leading whitespaces in the argument.
+ //
+ if (line[p] == '=')
+ ++p;
+ else
+ {
+ n = line.size ();
+ for (++p; p < n; ++p)
+ {
+ char c (line[p]);
+ if (c != ' ' && c != '\t' && c != '\r')
+ break;
+ }
+ }
+ }
+ else if (!skip_)
+ skip_ = (line == "--");
+
+ string s2 (line, p != string::npos ? p : 0);
+
+ // If the string (which is an option value or argument) is
+ // wrapped in quotes, remove them.
+ //
+ n = s2.size ();
+ char cf (s2[0]), cl (s2[n - 1]);
+
+ if (cf == '"' || cf == '\'' || cl == '"' || cl == '\'')
+ {
+ if (n == 1 || cf != cl)
+ throw unmatched_quote (s2);
+
+ s2 = string (s2, 1, n - 2);
+ }
+
+ if (!s1.empty ())
+ {
+ // See if this is another file option.
+ //
+ const option_info* oi;
+ if (!skip_ && (oi = find (s1.c_str ())))
+ {
+ if (s2.empty ())
+ throw missing_value (oi->option);
+
+ if (oi->search_func != 0)
+ {
+ string f (oi->search_func (s2.c_str (), oi->arg));
+ if (!f.empty ())
+ load (f);
+ }
+ else
+ {
+ // If the path of the file being parsed is not simple and the
+ // path of the file that needs to be loaded is relative, then
+ // complete the latter using the former as a base.
+ //
+#ifndef _WIN32
+ string::size_type p (file.find_last_of ('/'));
+ bool c (p != string::npos && s2[0] != '/');
+#else
+ string::size_type p (file.find_last_of ("/\\"));
+ bool c (p != string::npos && s2[1] != ':');
+#endif
+ if (c)
+ s2.insert (0, file, 0, p + 1);
+
+ load (s2);
+ }
+
+ continue;
+ }
+
+ a.value = s1;
+ args_.push_back (a);
+ }
+
+ a.value = s2;
+ args_.push_back (a);
+ }
+ }
+
+ template <typename X>
+ struct parser
+ {
+ static void
+ parse (X& x, bool& xs, scanner& s)
+ {
+ using namespace std;
+
+ const char* o (s.next ());
+ if (s.more ())
+ {
+ string v (s.next ());
+ istringstream is (v);
+ if (!(is >> x && is.peek () == istringstream::traits_type::eof ()))
+ throw invalid_value (o, v);
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+ };
+
+ template <>
+ struct parser<bool>
+ {
+ static void
+ parse (bool& x, scanner& s)
+ {
+ s.next ();
+ x = true;
+ }
+ };
+
+ template <>
+ struct parser<std::string>
+ {
+ static void
+ parse (std::string& x, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ x = s.next ();
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+ };
+
+ 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
+ parse (std::vector<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.push_back (x);
+ xs = true;
+ }
+ };
+
+ template <typename X, typename C>
+ struct parser<std::set<X, C> >
+ {
+ static void
+ parse (std::set<X, C>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.insert (x);
+ xs = true;
+ }
+ };
+
+ template <typename K, typename V, typename C>
+ struct parser<std::map<K, V, C> >
+ {
+ static void
+ parse (std::map<K, V, C>& m, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ std::size_t pos (s.position ());
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
+
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
+
+ bool dummy;
+ if (!kstr.empty ())
+ {
+ av[1] = const_cast<char*> (kstr.c_str ());
+ 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, false, pos);
+ parser<V>::parse (v, dummy, s);
+ }
+
+ m[k] = v;
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+ };
+
+ template <typename X, typename T, T X::*M>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, s);
+ }
+
+ template <typename X, typename T, T X::*M, bool X::*S>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, x.*S, s);
+ }
+ }
+ }
+}
+
+#include <map>
+#include <cstring>
+
+namespace build2
+{
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/libbuild2/common-options.hxx b/libbuild2/common-options.hxx
new file mode 100644
index 0000000..13f72d2
--- /dev/null
+++ b/libbuild2/common-options.hxx
@@ -0,0 +1,480 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef LIBBUILD2_COMMON_OPTIONS_HXX
+#define LIBBUILD2_COMMON_OPTIONS_HXX
+
+// Begin prologue.
+//
+#include <libbuild2/export.hxx>
+//
+// End prologue.
+
+#include <list>
+#include <deque>
+#include <vector>
+#include <iosfwd>
+#include <string>
+#include <cstddef>
+#include <exception>
+
+#ifndef CLI_POTENTIALLY_UNUSED
+# if defined(_MSC_VER) || defined(__xlC__)
+# define CLI_POTENTIALLY_UNUSED(x) (void*)&x
+# else
+# define CLI_POTENTIALLY_UNUSED(x) (void)x
+# endif
+#endif
+
+namespace build2
+{
+ namespace build
+ {
+ namespace cli
+ {
+ class usage_para
+ {
+ public:
+ enum value
+ {
+ none,
+ text,
+ option
+ };
+
+ usage_para (value);
+
+ operator value () const
+ {
+ return v_;
+ }
+
+ private:
+ value v_;
+ };
+
+ class unknown_mode
+ {
+ public:
+ enum value
+ {
+ skip,
+ stop,
+ fail
+ };
+
+ unknown_mode (value);
+
+ operator value () const
+ {
+ return v_;
+ }
+
+ private:
+ value v_;
+ };
+
+ // Exceptions.
+ //
+
+ class LIBBUILD2_SYMEXPORT exception: public std::exception
+ {
+ public:
+ virtual void
+ print (::std::ostream&) const = 0;
+ };
+
+ ::std::ostream&
+ operator<< (::std::ostream&, const exception&);
+
+ class LIBBUILD2_SYMEXPORT unknown_option: public exception
+ {
+ public:
+ virtual
+ ~unknown_option () throw ();
+
+ unknown_option (const std::string& option);
+
+ const std::string&
+ option () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string option_;
+ };
+
+ class LIBBUILD2_SYMEXPORT unknown_argument: public exception
+ {
+ public:
+ virtual
+ ~unknown_argument () throw ();
+
+ unknown_argument (const std::string& argument);
+
+ const std::string&
+ argument () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string argument_;
+ };
+
+ class LIBBUILD2_SYMEXPORT missing_value: public exception
+ {
+ public:
+ virtual
+ ~missing_value () throw ();
+
+ missing_value (const std::string& option);
+
+ const std::string&
+ option () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string option_;
+ };
+
+ class LIBBUILD2_SYMEXPORT invalid_value: public exception
+ {
+ public:
+ virtual
+ ~invalid_value () throw ();
+
+ invalid_value (const std::string& option,
+ const std::string& value,
+ const std::string& message = std::string ());
+
+ const std::string&
+ option () const;
+
+ const std::string&
+ value () const;
+
+ const std::string&
+ message () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string option_;
+ std::string value_;
+ std::string message_;
+ };
+
+ class LIBBUILD2_SYMEXPORT eos_reached: public exception
+ {
+ public:
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+ };
+
+ class LIBBUILD2_SYMEXPORT file_io_failure: public exception
+ {
+ public:
+ virtual
+ ~file_io_failure () throw ();
+
+ file_io_failure (const std::string& file);
+
+ const std::string&
+ file () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string file_;
+ };
+
+ class LIBBUILD2_SYMEXPORT unmatched_quote: public exception
+ {
+ public:
+ virtual
+ ~unmatched_quote () throw ();
+
+ unmatched_quote (const std::string& argument);
+
+ const std::string&
+ argument () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string argument_;
+ };
+
+ // Command line argument scanner interface.
+ //
+ // The values returned by next() are guaranteed to be valid
+ // 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 LIBBUILD2_SYMEXPORT scanner
+ {
+ public:
+ virtual
+ ~scanner ();
+
+ virtual bool
+ more () = 0;
+
+ virtual const char*
+ peek () = 0;
+
+ virtual const char*
+ next () = 0;
+
+ virtual void
+ skip () = 0;
+
+ virtual std::size_t
+ position () = 0;
+ };
+
+ class LIBBUILD2_SYMEXPORT argv_scanner: public scanner
+ {
+ public:
+ 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;
+
+ virtual bool
+ more ();
+
+ virtual const char*
+ peek ();
+
+ virtual const char*
+ next ();
+
+ virtual void
+ skip ();
+
+ virtual std::size_t
+ position ();
+
+ protected:
+ std::size_t start_position_;
+ int i_;
+ int& argc_;
+ char** argv_;
+ bool erase_;
+ };
+
+ class LIBBUILD2_SYMEXPORT vector_scanner: public scanner
+ {
+ public:
+ 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, std::size_t start_position = 0);
+
+ virtual bool
+ more ();
+
+ virtual const char*
+ peek ();
+
+ virtual const char*
+ next ();
+
+ virtual void
+ skip ();
+
+ virtual std::size_t
+ position ();
+
+ private:
+ std::size_t start_position_;
+ const std::vector<std::string>& v_;
+ std::size_t i_;
+ };
+
+ class LIBBUILD2_SYMEXPORT argv_file_scanner: public argv_scanner
+ {
+ public:
+ argv_file_scanner (int& argc,
+ char** argv,
+ const std::string& option,
+ 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,
+ std::size_t start_position = 0);
+
+ argv_file_scanner (const std::string& file,
+ const std::string& option,
+ std::size_t start_position = 0);
+
+ struct option_info
+ {
+ // If search_func is not NULL, it is called, with the arg
+ // value as the second argument, to locate the options file.
+ // If it returns an empty string, then the file is ignored.
+ //
+ const char* option;
+ std::string (*search_func) (const char*, void* arg);
+ void* arg;
+ };
+
+ argv_file_scanner (int& argc,
+ char** argv,
+ const option_info* options,
+ std::size_t options_count,
+ 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,
+ 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 start_position = 0);
+
+ virtual bool
+ more ();
+
+ virtual const char*
+ peek ();
+
+ virtual const char*
+ next ();
+
+ 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.
+ //
+ const std::string&
+ peek_file ();
+
+ // Return the 1-based line number if the peeked at argument came from
+ // a file and zero otherwise.
+ //
+ std::size_t
+ peek_line ();
+
+ private:
+ const option_info*
+ find (const char*) const;
+
+ void
+ load (const std::string& file);
+
+ typedef argv_scanner base;
+
+ const std::string option_;
+ option_info option_info_;
+ const option_info* options_;
+ std::size_t options_count_;
+
+ struct arg
+ {
+ std::string value;
+ const std::string* file;
+ std::size_t line;
+ };
+
+ std::deque<arg> args_;
+ std::list<std::string> files_;
+
+ // Circular buffer of two arguments.
+ //
+ std::string hold_[2];
+ std::size_t i_;
+
+ bool skip_;
+
+ static int zero_argc_;
+ static std::string empty_string_;
+ };
+
+ template <typename X>
+ struct parser;
+ }
+ }
+}
+
+namespace build2
+{
+}
+
+#include <libbuild2/common-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // LIBBUILD2_COMMON_OPTIONS_HXX
diff --git a/libbuild2/common-options.ixx b/libbuild2/common-options.ixx
new file mode 100644
index 0000000..1b7b74e
--- /dev/null
+++ b/libbuild2/common-options.ixx
@@ -0,0 +1,312 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <cassert>
+
+namespace build2
+{
+ namespace build
+ {
+ namespace cli
+ {
+ // usage_para
+ //
+ inline usage_para::
+ usage_para (value v)
+ : v_ (v)
+ {
+ }
+
+ // unknown_mode
+ //
+ inline unknown_mode::
+ unknown_mode (value v)
+ : v_ (v)
+ {
+ }
+
+ // exception
+ //
+ inline ::std::ostream&
+ operator<< (::std::ostream& os, const exception& e)
+ {
+ e.print (os);
+ return os;
+ }
+
+ // unknown_option
+ //
+ inline unknown_option::
+ unknown_option (const std::string& option)
+ : option_ (option)
+ {
+ }
+
+ inline const std::string& unknown_option::
+ option () const
+ {
+ return option_;
+ }
+
+ // unknown_argument
+ //
+ inline unknown_argument::
+ unknown_argument (const std::string& argument)
+ : argument_ (argument)
+ {
+ }
+
+ inline const std::string& unknown_argument::
+ argument () const
+ {
+ return argument_;
+ }
+
+ // missing_value
+ //
+ inline missing_value::
+ missing_value (const std::string& option)
+ : option_ (option)
+ {
+ }
+
+ inline const std::string& missing_value::
+ option () const
+ {
+ return option_;
+ }
+
+ // invalid_value
+ //
+ inline invalid_value::
+ invalid_value (const std::string& option,
+ const std::string& value,
+ const std::string& message)
+ : option_ (option),
+ value_ (value),
+ message_ (message)
+ {
+ }
+
+ inline const std::string& invalid_value::
+ option () const
+ {
+ return option_;
+ }
+
+ inline const std::string& invalid_value::
+ value () const
+ {
+ return value_;
+ }
+
+ inline const std::string& invalid_value::
+ message () const
+ {
+ return message_;
+ }
+
+ // file_io_failure
+ //
+ inline file_io_failure::
+ file_io_failure (const std::string& file)
+ : file_ (file)
+ {
+ }
+
+ inline const std::string& file_io_failure::
+ file () const
+ {
+ return file_;
+ }
+
+ // unmatched_quote
+ //
+ inline unmatched_quote::
+ unmatched_quote (const std::string& argument)
+ : argument_ (argument)
+ {
+ }
+
+ inline const std::string& unmatched_quote::
+ argument () const
+ {
+ return argument_;
+ }
+
+ // argv_scanner
+ //
+ inline argv_scanner::
+ 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,
+ std::size_t sp)
+ : start_position_ (sp + static_cast<std::size_t> (start)),
+ i_ (start),
+ argc_ (argc),
+ argv_ (argv),
+ erase_ (erase)
+ {
+ }
+
+ inline int argv_scanner::
+ end () const
+ {
+ return i_;
+ }
+
+ // vector_scanner
+ //
+ inline vector_scanner::
+ vector_scanner (const std::vector<std::string>& v,
+ std::size_t i,
+ std::size_t sp)
+ : start_position_ (sp), v_ (v), i_ (i)
+ {
+ }
+
+ inline std::size_t vector_scanner::
+ end () const
+ {
+ return i_;
+ }
+
+ inline void vector_scanner::
+ reset (std::size_t i, std::size_t sp)
+ {
+ i_ = i;
+ start_position_ = sp;
+ }
+
+ // argv_file_scanner
+ //
+ inline argv_file_scanner::
+ argv_file_scanner (int& argc,
+ char** argv,
+ const std::string& option,
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (argc, argv, erase, sp),
+ option_ (option),
+ options_ (&option_info_),
+ options_count_ (1),
+ i_ (1),
+ skip_ (false)
+ {
+ option_info_.option = option_.c_str ();
+ option_info_.search_func = 0;
+ }
+
+ inline argv_file_scanner::
+ argv_file_scanner (int start,
+ int& argc,
+ char** argv,
+ const std::string& option,
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (start, argc, argv, erase, sp),
+ option_ (option),
+ options_ (&option_info_),
+ options_count_ (1),
+ i_ (1),
+ skip_ (false)
+ {
+ option_info_.option = option_.c_str ();
+ option_info_.search_func = 0;
+ }
+
+ inline argv_file_scanner::
+ argv_file_scanner (const std::string& file,
+ const std::string& option,
+ std::size_t sp)
+ : argv_scanner (0, zero_argc_, 0, sp),
+ option_ (option),
+ options_ (&option_info_),
+ options_count_ (1),
+ i_ (1),
+ skip_ (false)
+ {
+ option_info_.option = option_.c_str ();
+ option_info_.search_func = 0;
+
+ load (file);
+ }
+
+ inline argv_file_scanner::
+ argv_file_scanner (int& argc,
+ char** argv,
+ const option_info* options,
+ std::size_t options_count,
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (argc, argv, erase, sp),
+ options_ (options),
+ options_count_ (options_count),
+ i_ (1),
+ skip_ (false)
+ {
+ }
+
+ inline argv_file_scanner::
+ argv_file_scanner (int start,
+ int& argc,
+ char** argv,
+ const option_info* options,
+ std::size_t options_count,
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (start, argc, argv, erase, sp),
+ options_ (options),
+ options_count_ (options_count),
+ i_ (1),
+ skip_ (false)
+ {
+ }
+
+ inline argv_file_scanner::
+ argv_file_scanner (const std::string& file,
+ const option_info* options,
+ std::size_t options_count,
+ std::size_t sp)
+ : argv_scanner (0, zero_argc_, 0, sp),
+ options_ (options),
+ options_count_ (options_count),
+ i_ (1),
+ skip_ (false)
+ {
+ load (file);
+ }
+ }
+ }
+}
+
+namespace build2
+{
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/libbuild2/common.cli b/libbuild2/common.cli
new file mode 100644
index 0000000..2c49ace
--- /dev/null
+++ b/libbuild2/common.cli
@@ -0,0 +1,6 @@
+// file : libbuild2/common.cli
+// license : MIT; see accompanying LICENSE file
+
+namespace build2
+{
+}
diff --git a/libbuild2/script/builtin-options.cxx b/libbuild2/script/builtin-options.cxx
index 56e7f24..7589faf 100644
--- a/libbuild2/script/builtin-options.cxx
+++ b/libbuild2/script/builtin-options.cxx
@@ -21,212 +21,10 @@
namespace build2
{
- namespace script
+ namespace build
{
namespace cli
{
- // unknown_option
- //
- unknown_option::
- ~unknown_option () throw ()
- {
- }
-
- void unknown_option::
- print (::std::ostream& os) const
- {
- os << "unknown option '" << option ().c_str () << "'";
- }
-
- const char* unknown_option::
- what () const throw ()
- {
- return "unknown option";
- }
-
- // unknown_argument
- //
- unknown_argument::
- ~unknown_argument () throw ()
- {
- }
-
- void unknown_argument::
- print (::std::ostream& os) const
- {
- os << "unknown argument '" << argument ().c_str () << "'";
- }
-
- const char* unknown_argument::
- what () const throw ()
- {
- return "unknown argument";
- }
-
- // missing_value
- //
- missing_value::
- ~missing_value () throw ()
- {
- }
-
- void missing_value::
- print (::std::ostream& os) const
- {
- os << "missing value for option '" << option ().c_str () << "'";
- }
-
- const char* missing_value::
- what () const throw ()
- {
- return "missing option value";
- }
-
- // invalid_value
- //
- invalid_value::
- ~invalid_value () throw ()
- {
- }
-
- void invalid_value::
- print (::std::ostream& os) const
- {
- os << "invalid value '" << value ().c_str () << "' for option '"
- << option ().c_str () << "'";
-
- if (!message ().empty ())
- os << ": " << message ().c_str ();
- }
-
- const char* invalid_value::
- what () const throw ()
- {
- return "invalid option value";
- }
-
- // eos_reached
- //
- void eos_reached::
- print (::std::ostream& os) const
- {
- os << what ();
- }
-
- const char* eos_reached::
- what () const throw ()
- {
- return "end of argument stream reached";
- }
-
- // scanner
- //
- scanner::
- ~scanner ()
- {
- }
-
- // argv_scanner
- //
- bool argv_scanner::
- more ()
- {
- return i_ < argc_;
- }
-
- const char* argv_scanner::
- peek ()
- {
- if (i_ < argc_)
- return argv_[i_];
- else
- throw eos_reached ();
- }
-
- const char* argv_scanner::
- next ()
- {
- if (i_ < argc_)
- {
- const char* r (argv_[i_]);
-
- if (erase_)
- {
- for (int i (i_ + 1); i < argc_; ++i)
- argv_[i - 1] = argv_[i];
-
- --argc_;
- argv_[argc_] = 0;
- }
- else
- ++i_;
-
- ++start_position_;
- return r;
- }
- else
- throw eos_reached ();
- }
-
- void argv_scanner::
- 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::
- more ()
- {
- return i_ < v_.size ();
- }
-
- const char* vector_scanner::
- peek ()
- {
- if (i_ < v_.size ())
- return v_[i_].c_str ();
- else
- throw eos_reached ();
- }
-
- const char* vector_scanner::
- next ()
- {
- if (i_ < v_.size ())
- return v_[i_++].c_str ();
- else
- throw eos_reached ();
- }
-
- void vector_scanner::
- skip ()
- {
- if (i_ < v_.size ())
- ++i_;
- else
- throw eos_reached ();
- }
-
- std::size_t vector_scanner::
- position ()
- {
- return start_position_ + i_;
- }
-
template <typename X>
struct parser
{
@@ -406,13 +204,13 @@ namespace build2
set_options (int& argc,
char** argv,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: exact_ (),
newline_ (),
whitespace_ ()
{
- ::build2::script::cli::argv_scanner s (argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (argc, argv, erase);
_parse (s, opt, arg);
}
@@ -421,13 +219,13 @@ namespace build2
int& argc,
char** argv,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: exact_ (),
newline_ (),
whitespace_ ()
{
- ::build2::script::cli::argv_scanner s (start, argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (start, argc, argv, erase);
_parse (s, opt, arg);
}
@@ -436,13 +234,13 @@ namespace build2
char** argv,
int& end,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: exact_ (),
newline_ (),
whitespace_ ()
{
- ::build2::script::cli::argv_scanner s (argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (argc, argv, erase);
_parse (s, opt, arg);
end = s.end ();
}
@@ -453,21 +251,21 @@ namespace build2
char** argv,
int& end,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: exact_ (),
newline_ (),
whitespace_ ()
{
- ::build2::script::cli::argv_scanner s (start, argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (start, argc, argv, erase);
_parse (s, opt, arg);
end = s.end ();
}
set_options::
- set_options (::build2::script::cli::scanner& s,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ set_options (::build2::build::cli::scanner& s,
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: exact_ (),
newline_ (),
whitespace_ ()
@@ -476,7 +274,7 @@ namespace build2
}
typedef
- std::map<std::string, void (*) (set_options&, ::build2::script::cli::scanner&)>
+ std::map<std::string, void (*) (set_options&, ::build2::build::cli::scanner&)>
_cli_set_options_map;
static _cli_set_options_map _cli_set_options_map_;
@@ -486,24 +284,24 @@ namespace build2
_cli_set_options_map_init ()
{
_cli_set_options_map_["--exact"] =
- &::build2::script::cli::thunk< set_options, bool, &set_options::exact_ >;
+ &::build2::build::cli::thunk< set_options, bool, &set_options::exact_ >;
_cli_set_options_map_["-e"] =
- &::build2::script::cli::thunk< set_options, bool, &set_options::exact_ >;
+ &::build2::build::cli::thunk< set_options, bool, &set_options::exact_ >;
_cli_set_options_map_["--newline"] =
- &::build2::script::cli::thunk< set_options, bool, &set_options::newline_ >;
+ &::build2::build::cli::thunk< set_options, bool, &set_options::newline_ >;
_cli_set_options_map_["-n"] =
- &::build2::script::cli::thunk< set_options, bool, &set_options::newline_ >;
+ &::build2::build::cli::thunk< set_options, bool, &set_options::newline_ >;
_cli_set_options_map_["--whitespace"] =
- &::build2::script::cli::thunk< set_options, bool, &set_options::whitespace_ >;
+ &::build2::build::cli::thunk< set_options, bool, &set_options::whitespace_ >;
_cli_set_options_map_["-w"] =
- &::build2::script::cli::thunk< set_options, bool, &set_options::whitespace_ >;
+ &::build2::build::cli::thunk< set_options, bool, &set_options::whitespace_ >;
}
};
static _cli_set_options_map_init _cli_set_options_map_init_;
bool set_options::
- _parse (const char* o, ::build2::script::cli::scanner& s)
+ _parse (const char* o, ::build2::build::cli::scanner& s)
{
_cli_set_options_map::const_iterator i (_cli_set_options_map_.find (o));
@@ -517,13 +315,13 @@ namespace build2
}
bool set_options::
- _parse (::build2::script::cli::scanner& s,
- ::build2::script::cli::unknown_mode opt_mode,
- ::build2::script::cli::unknown_mode arg_mode)
+ _parse (::build2::build::cli::scanner& s,
+ ::build2::build::cli::unknown_mode opt_mode,
+ ::build2::build::cli::unknown_mode arg_mode)
{
// Can't skip combined flags (--no-combined-flags).
//
- assert (opt_mode != ::build2::script::cli::unknown_mode::skip);
+ assert (opt_mode != ::build2::build::cli::unknown_mode::skip);
bool r = false;
bool opt = true;
@@ -565,14 +363,14 @@ namespace build2
const_cast<char*> (v)
};
- ::build2::script::cli::argv_scanner ns (0, ac, av);
+ ::build2::build::cli::argv_scanner ns (0, ac, av);
if (_parse (co.c_str (), ns))
{
// Parsed the option but not its value?
//
if (ns.end () != 2)
- throw ::build2::script::cli::invalid_value (co, v);
+ throw ::build2::build::cli::invalid_value (co, v);
s.next ();
r = true;
@@ -613,7 +411,7 @@ namespace build2
cf
};
- ::build2::script::cli::argv_scanner ns (0, ac, av);
+ ::build2::build::cli::argv_scanner ns (0, ac, av);
if (!_parse (cf, ns))
break;
@@ -638,19 +436,19 @@ namespace build2
switch (opt_mode)
{
- case ::build2::script::cli::unknown_mode::skip:
+ case ::build2::build::cli::unknown_mode::skip:
{
s.skip ();
r = true;
continue;
}
- case ::build2::script::cli::unknown_mode::stop:
+ case ::build2::build::cli::unknown_mode::stop:
{
break;
}
- case ::build2::script::cli::unknown_mode::fail:
+ case ::build2::build::cli::unknown_mode::fail:
{
- throw ::build2::script::cli::unknown_option (o);
+ throw ::build2::build::cli::unknown_option (o);
}
}
@@ -660,19 +458,19 @@ namespace build2
switch (arg_mode)
{
- case ::build2::script::cli::unknown_mode::skip:
+ case ::build2::build::cli::unknown_mode::skip:
{
s.skip ();
r = true;
continue;
}
- case ::build2::script::cli::unknown_mode::stop:
+ case ::build2::build::cli::unknown_mode::stop:
{
break;
}
- case ::build2::script::cli::unknown_mode::fail:
+ case ::build2::build::cli::unknown_mode::fail:
{
- throw ::build2::script::cli::unknown_argument (o);
+ throw ::build2::build::cli::unknown_argument (o);
}
}
@@ -695,11 +493,11 @@ namespace build2
timeout_options (int& argc,
char** argv,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: success_ ()
{
- ::build2::script::cli::argv_scanner s (argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (argc, argv, erase);
_parse (s, opt, arg);
}
@@ -708,11 +506,11 @@ namespace build2
int& argc,
char** argv,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: success_ ()
{
- ::build2::script::cli::argv_scanner s (start, argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (start, argc, argv, erase);
_parse (s, opt, arg);
}
@@ -721,11 +519,11 @@ namespace build2
char** argv,
int& end,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: success_ ()
{
- ::build2::script::cli::argv_scanner s (argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (argc, argv, erase);
_parse (s, opt, arg);
end = s.end ();
}
@@ -736,26 +534,26 @@ namespace build2
char** argv,
int& end,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: success_ ()
{
- ::build2::script::cli::argv_scanner s (start, argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (start, argc, argv, erase);
_parse (s, opt, arg);
end = s.end ();
}
timeout_options::
- timeout_options (::build2::script::cli::scanner& s,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ timeout_options (::build2::build::cli::scanner& s,
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: success_ ()
{
_parse (s, opt, arg);
}
typedef
- std::map<std::string, void (*) (timeout_options&, ::build2::script::cli::scanner&)>
+ std::map<std::string, void (*) (timeout_options&, ::build2::build::cli::scanner&)>
_cli_timeout_options_map;
static _cli_timeout_options_map _cli_timeout_options_map_;
@@ -765,16 +563,16 @@ namespace build2
_cli_timeout_options_map_init ()
{
_cli_timeout_options_map_["--success"] =
- &::build2::script::cli::thunk< timeout_options, bool, &timeout_options::success_ >;
+ &::build2::build::cli::thunk< timeout_options, bool, &timeout_options::success_ >;
_cli_timeout_options_map_["-s"] =
- &::build2::script::cli::thunk< timeout_options, bool, &timeout_options::success_ >;
+ &::build2::build::cli::thunk< timeout_options, bool, &timeout_options::success_ >;
}
};
static _cli_timeout_options_map_init _cli_timeout_options_map_init_;
bool timeout_options::
- _parse (const char* o, ::build2::script::cli::scanner& s)
+ _parse (const char* o, ::build2::build::cli::scanner& s)
{
_cli_timeout_options_map::const_iterator i (_cli_timeout_options_map_.find (o));
@@ -788,13 +586,13 @@ namespace build2
}
bool timeout_options::
- _parse (::build2::script::cli::scanner& s,
- ::build2::script::cli::unknown_mode opt_mode,
- ::build2::script::cli::unknown_mode arg_mode)
+ _parse (::build2::build::cli::scanner& s,
+ ::build2::build::cli::unknown_mode opt_mode,
+ ::build2::build::cli::unknown_mode arg_mode)
{
// Can't skip combined flags (--no-combined-flags).
//
- assert (opt_mode != ::build2::script::cli::unknown_mode::skip);
+ assert (opt_mode != ::build2::build::cli::unknown_mode::skip);
bool r = false;
bool opt = true;
@@ -836,14 +634,14 @@ namespace build2
const_cast<char*> (v)
};
- ::build2::script::cli::argv_scanner ns (0, ac, av);
+ ::build2::build::cli::argv_scanner ns (0, ac, av);
if (_parse (co.c_str (), ns))
{
// Parsed the option but not its value?
//
if (ns.end () != 2)
- throw ::build2::script::cli::invalid_value (co, v);
+ throw ::build2::build::cli::invalid_value (co, v);
s.next ();
r = true;
@@ -884,7 +682,7 @@ namespace build2
cf
};
- ::build2::script::cli::argv_scanner ns (0, ac, av);
+ ::build2::build::cli::argv_scanner ns (0, ac, av);
if (!_parse (cf, ns))
break;
@@ -909,19 +707,19 @@ namespace build2
switch (opt_mode)
{
- case ::build2::script::cli::unknown_mode::skip:
+ case ::build2::build::cli::unknown_mode::skip:
{
s.skip ();
r = true;
continue;
}
- case ::build2::script::cli::unknown_mode::stop:
+ case ::build2::build::cli::unknown_mode::stop:
{
break;
}
- case ::build2::script::cli::unknown_mode::fail:
+ case ::build2::build::cli::unknown_mode::fail:
{
- throw ::build2::script::cli::unknown_option (o);
+ throw ::build2::build::cli::unknown_option (o);
}
}
@@ -931,19 +729,19 @@ namespace build2
switch (arg_mode)
{
- case ::build2::script::cli::unknown_mode::skip:
+ case ::build2::build::cli::unknown_mode::skip:
{
s.skip ();
r = true;
continue;
}
- case ::build2::script::cli::unknown_mode::stop:
+ case ::build2::build::cli::unknown_mode::stop:
{
break;
}
- case ::build2::script::cli::unknown_mode::fail:
+ case ::build2::build::cli::unknown_mode::fail:
{
- throw ::build2::script::cli::unknown_argument (o);
+ throw ::build2::build::cli::unknown_argument (o);
}
}
@@ -969,14 +767,14 @@ namespace build2
export_options (int& argc,
char** argv,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: unset_ (),
unset_specified_ (false),
clear_ (),
clear_specified_ (false)
{
- ::build2::script::cli::argv_scanner s (argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (argc, argv, erase);
_parse (s, opt, arg);
}
@@ -985,14 +783,14 @@ namespace build2
int& argc,
char** argv,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: unset_ (),
unset_specified_ (false),
clear_ (),
clear_specified_ (false)
{
- ::build2::script::cli::argv_scanner s (start, argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (start, argc, argv, erase);
_parse (s, opt, arg);
}
@@ -1001,14 +799,14 @@ namespace build2
char** argv,
int& end,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: unset_ (),
unset_specified_ (false),
clear_ (),
clear_specified_ (false)
{
- ::build2::script::cli::argv_scanner s (argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (argc, argv, erase);
_parse (s, opt, arg);
end = s.end ();
}
@@ -1019,22 +817,22 @@ namespace build2
char** argv,
int& end,
bool erase,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: unset_ (),
unset_specified_ (false),
clear_ (),
clear_specified_ (false)
{
- ::build2::script::cli::argv_scanner s (start, argc, argv, erase);
+ ::build2::build::cli::argv_scanner s (start, argc, argv, erase);
_parse (s, opt, arg);
end = s.end ();
}
export_options::
- export_options (::build2::script::cli::scanner& s,
- ::build2::script::cli::unknown_mode opt,
- ::build2::script::cli::unknown_mode arg)
+ export_options (::build2::build::cli::scanner& s,
+ ::build2::build::cli::unknown_mode opt,
+ ::build2::build::cli::unknown_mode arg)
: unset_ (),
unset_specified_ (false),
clear_ (),
@@ -1044,7 +842,7 @@ namespace build2
}
typedef
- std::map<std::string, void (*) (export_options&, ::build2::script::cli::scanner&)>
+ std::map<std::string, void (*) (export_options&, ::build2::build::cli::scanner&)>
_cli_export_options_map;
static _cli_export_options_map _cli_export_options_map_;
@@ -1054,16 +852,16 @@ namespace build2
_cli_export_options_map_init ()
{
_cli_export_options_map_["--unset"] =
- &::build2::script::cli::thunk< export_options, vector<string>, &export_options::unset_,
+ &::build2::build::cli::thunk< export_options, vector<string>, &export_options::unset_,
&export_options::unset_specified_ >;
_cli_export_options_map_["-u"] =
- &::build2::script::cli::thunk< export_options, vector<string>, &export_options::unset_,
+ &::build2::build::cli::thunk< export_options, vector<string>, &export_options::unset_,
&export_options::unset_specified_ >;
_cli_export_options_map_["--clear"] =
- &::build2::script::cli::thunk< export_options, vector<string>, &export_options::clear_,
+ &::build2::build::cli::thunk< export_options, vector<string>, &export_options::clear_,
&export_options::clear_specified_ >;
_cli_export_options_map_["-c"] =
- &::build2::script::cli::thunk< export_options, vector<string>, &export_options::clear_,
+ &::build2::build::cli::thunk< export_options, vector<string>, &export_options::clear_,
&export_options::clear_specified_ >;
}
};
@@ -1071,7 +869,7 @@ namespace build2
static _cli_export_options_map_init _cli_export_options_map_init_;
bool export_options::
- _parse (const char* o, ::build2::script::cli::scanner& s)
+ _parse (const char* o, ::build2::build::cli::scanner& s)
{
_cli_export_options_map::const_iterator i (_cli_export_options_map_.find (o));
@@ -1085,13 +883,13 @@ namespace build2
}
bool export_options::
- _parse (::build2::script::cli::scanner& s,
- ::build2::script::cli::unknown_mode opt_mode,
- ::build2::script::cli::unknown_mode arg_mode)
+ _parse (::build2::build::cli::scanner& s,
+ ::build2::build::cli::unknown_mode opt_mode,
+ ::build2::build::cli::unknown_mode arg_mode)
{
// Can't skip combined flags (--no-combined-flags).
//
- assert (opt_mode != ::build2::script::cli::unknown_mode::skip);
+ assert (opt_mode != ::build2::build::cli::unknown_mode::skip);
bool r = false;
bool opt = true;
@@ -1133,14 +931,14 @@ namespace build2
const_cast<char*> (v)
};
- ::build2::script::cli::argv_scanner ns (0, ac, av);
+ ::build2::build::cli::argv_scanner ns (0, ac, av);
if (_parse (co.c_str (), ns))
{
// Parsed the option but not its value?
//
if (ns.end () != 2)
- throw ::build2::script::cli::invalid_value (co, v);
+ throw ::build2::build::cli::invalid_value (co, v);
s.next ();
r = true;
@@ -1181,7 +979,7 @@ namespace build2
cf
};
- ::build2::script::cli::argv_scanner ns (0, ac, av);
+ ::build2::build::cli::argv_scanner ns (0, ac, av);
if (!_parse (cf, ns))
break;
@@ -1206,19 +1004,19 @@ namespace build2
switch (opt_mode)
{
- case ::build2::script::cli::unknown_mode::skip:
+ case ::build2::build::cli::unknown_mode::skip:
{
s.skip ();
r = true;
continue;
}
- case ::build2::script::cli::unknown_mode::stop:
+ case ::build2::build::cli::unknown_mode::stop:
{
break;
}
- case ::build2::script::cli::unknown_mode::fail:
+ case ::build2::build::cli::unknown_mode::fail:
{
- throw ::build2::script::cli::unknown_option (o);
+ throw ::build2::build::cli::unknown_option (o);
}
}
@@ -1228,19 +1026,19 @@ namespace build2
switch (arg_mode)
{
- case ::build2::script::cli::unknown_mode::skip:
+ case ::build2::build::cli::unknown_mode::skip:
{
s.skip ();
r = true;
continue;
}
- case ::build2::script::cli::unknown_mode::stop:
+ case ::build2::build::cli::unknown_mode::stop:
{
break;
}
- case ::build2::script::cli::unknown_mode::fail:
+ case ::build2::build::cli::unknown_mode::fail:
{
- throw ::build2::script::cli::unknown_argument (o);
+ throw ::build2::build::cli::unknown_argument (o);
}
}
diff --git a/libbuild2/script/builtin-options.hxx b/libbuild2/script/builtin-options.hxx
index d665279..9089d46 100644
--- a/libbuild2/script/builtin-options.hxx
+++ b/libbuild2/script/builtin-options.hxx
@@ -12,282 +12,10 @@
//
// End prologue.
-#include <vector>
-#include <iosfwd>
-#include <string>
-#include <cstddef>
-#include <exception>
-
-#ifndef CLI_POTENTIALLY_UNUSED
-# if defined(_MSC_VER) || defined(__xlC__)
-# define CLI_POTENTIALLY_UNUSED(x) (void*)&x
-# else
-# define CLI_POTENTIALLY_UNUSED(x) (void)x
-# endif
-#endif
-
-namespace build2
-{
- namespace script
- {
- namespace cli
- {
- class unknown_mode
- {
- public:
- enum value
- {
- skip,
- stop,
- fail
- };
-
- unknown_mode (value);
-
- operator value () const
- {
- return v_;
- }
-
- private:
- value v_;
- };
-
- // Exceptions.
- //
-
- class exception: public std::exception
- {
- public:
- virtual void
- print (::std::ostream&) const = 0;
- };
-
- ::std::ostream&
- operator<< (::std::ostream&, const exception&);
-
- class unknown_option: public exception
- {
- public:
- virtual
- ~unknown_option () throw ();
-
- unknown_option (const std::string& option);
-
- const std::string&
- option () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string option_;
- };
-
- class unknown_argument: public exception
- {
- public:
- virtual
- ~unknown_argument () throw ();
-
- unknown_argument (const std::string& argument);
-
- const std::string&
- argument () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string argument_;
- };
-
- class missing_value: public exception
- {
- public:
- virtual
- ~missing_value () throw ();
-
- missing_value (const std::string& option);
-
- const std::string&
- option () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string option_;
- };
-
- class invalid_value: public exception
- {
- public:
- virtual
- ~invalid_value () throw ();
-
- invalid_value (const std::string& option,
- const std::string& value,
- const std::string& message = std::string ());
-
- const std::string&
- option () const;
-
- const std::string&
- value () const;
-
- const std::string&
- message () const;
-
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
-
- private:
- std::string option_;
- std::string value_;
- std::string message_;
- };
-
- class eos_reached: public exception
- {
- public:
- virtual void
- print (::std::ostream&) const;
-
- virtual const char*
- what () const throw ();
- };
-
- // Command line argument scanner interface.
- //
- // The values returned by next() are guaranteed to be valid
- // 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:
- virtual
- ~scanner ();
-
- virtual bool
- more () = 0;
-
- virtual const char*
- peek () = 0;
-
- virtual const char*
- next () = 0;
-
- 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,
- 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;
-
- virtual bool
- more ();
-
- virtual const char*
- peek ();
-
- virtual const char*
- next ();
-
- virtual void
- skip ();
-
- virtual std::size_t
- position ();
-
- protected:
- std::size_t start_position_;
- int i_;
- int& argc_;
- char** argv_;
- bool erase_;
- };
-
- class vector_scanner: public scanner
- {
- public:
- 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, std::size_t start_position = 0);
-
- virtual bool
- more ();
-
- virtual const char*
- peek ();
-
- virtual const char*
- next ();
-
- virtual void
- skip ();
-
- virtual std::size_t
- position ();
-
- private:
- std::size_t start_position_;
- const std::vector<std::string>& v_;
- std::size_t i_;
- };
-
- template <typename X>
- struct parser;
- }
- }
-}
-
#include <libbuild2/types.hxx>
+#include <libbuild2/common-options.hxx>
+
namespace build2
{
namespace script
@@ -300,34 +28,34 @@ namespace build2
set_options (int& argc,
char** argv,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
set_options (int start,
int& argc,
char** argv,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
set_options (int& argc,
char** argv,
int& end,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
set_options (int start,
int& argc,
char** argv,
int& end,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
- set_options (::build2::script::cli::scanner&,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ set_options (::build2::build::cli::scanner&,
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
// Option accessors and modifiers.
//
@@ -362,13 +90,13 @@ namespace build2
//
protected:
bool
- _parse (const char*, ::build2::script::cli::scanner&);
+ _parse (const char*, ::build2::build::cli::scanner&);
private:
bool
- _parse (::build2::script::cli::scanner&,
- ::build2::script::cli::unknown_mode option,
- ::build2::script::cli::unknown_mode argument);
+ _parse (::build2::build::cli::scanner&,
+ ::build2::build::cli::unknown_mode option,
+ ::build2::build::cli::unknown_mode argument);
public:
bool exact_;
@@ -384,34 +112,34 @@ namespace build2
timeout_options (int& argc,
char** argv,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
timeout_options (int start,
int& argc,
char** argv,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
timeout_options (int& argc,
char** argv,
int& end,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
timeout_options (int start,
int& argc,
char** argv,
int& end,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
- timeout_options (::build2::script::cli::scanner&,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ timeout_options (::build2::build::cli::scanner&,
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
// Option accessors and modifiers.
//
@@ -428,13 +156,13 @@ namespace build2
//
protected:
bool
- _parse (const char*, ::build2::script::cli::scanner&);
+ _parse (const char*, ::build2::build::cli::scanner&);
private:
bool
- _parse (::build2::script::cli::scanner&,
- ::build2::script::cli::unknown_mode option,
- ::build2::script::cli::unknown_mode argument);
+ _parse (::build2::build::cli::scanner&,
+ ::build2::build::cli::unknown_mode option,
+ ::build2::build::cli::unknown_mode argument);
public:
bool success_;
@@ -448,34 +176,34 @@ namespace build2
export_options (int& argc,
char** argv,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
export_options (int start,
int& argc,
char** argv,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
export_options (int& argc,
char** argv,
int& end,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
export_options (int start,
int& argc,
char** argv,
int& end,
bool erase = false,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
- export_options (::build2::script::cli::scanner&,
- ::build2::script::cli::unknown_mode option = ::build2::script::cli::unknown_mode::fail,
- ::build2::script::cli::unknown_mode argument = ::build2::script::cli::unknown_mode::stop);
+ export_options (::build2::build::cli::scanner&,
+ ::build2::build::cli::unknown_mode option = ::build2::build::cli::unknown_mode::fail,
+ ::build2::build::cli::unknown_mode argument = ::build2::build::cli::unknown_mode::stop);
// Option accessors and modifiers.
//
@@ -513,13 +241,13 @@ namespace build2
//
protected:
bool
- _parse (const char*, ::build2::script::cli::scanner&);
+ _parse (const char*, ::build2::build::cli::scanner&);
private:
bool
- _parse (::build2::script::cli::scanner&,
- ::build2::script::cli::unknown_mode option,
- ::build2::script::cli::unknown_mode argument);
+ _parse (::build2::build::cli::scanner&,
+ ::build2::build::cli::unknown_mode option,
+ ::build2::build::cli::unknown_mode argument);
public:
vector<string> unset_;
diff --git a/libbuild2/script/builtin-options.ixx b/libbuild2/script/builtin-options.ixx
index 8fef25a..8f84177 100644
--- a/libbuild2/script/builtin-options.ixx
+++ b/libbuild2/script/builtin-options.ixx
@@ -9,164 +9,6 @@
//
// End prologue.
-#include <cassert>
-
-namespace build2
-{
- namespace script
- {
- namespace cli
- {
- // unknown_mode
- //
- inline unknown_mode::
- unknown_mode (value v)
- : v_ (v)
- {
- }
-
- // exception
- //
- inline ::std::ostream&
- operator<< (::std::ostream& os, const exception& e)
- {
- e.print (os);
- return os;
- }
-
- // unknown_option
- //
- inline unknown_option::
- unknown_option (const std::string& option)
- : option_ (option)
- {
- }
-
- inline const std::string& unknown_option::
- option () const
- {
- return option_;
- }
-
- // unknown_argument
- //
- inline unknown_argument::
- unknown_argument (const std::string& argument)
- : argument_ (argument)
- {
- }
-
- inline const std::string& unknown_argument::
- argument () const
- {
- return argument_;
- }
-
- // missing_value
- //
- inline missing_value::
- missing_value (const std::string& option)
- : option_ (option)
- {
- }
-
- inline const std::string& missing_value::
- option () const
- {
- return option_;
- }
-
- // invalid_value
- //
- inline invalid_value::
- invalid_value (const std::string& option,
- const std::string& value,
- const std::string& message)
- : option_ (option),
- value_ (value),
- message_ (message)
- {
- }
-
- inline const std::string& invalid_value::
- option () const
- {
- return option_;
- }
-
- inline const std::string& invalid_value::
- value () const
- {
- return value_;
- }
-
- inline const std::string& invalid_value::
- message () const
- {
- return message_;
- }
-
- // argv_scanner
- //
- inline argv_scanner::
- 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,
- std::size_t sp)
- : start_position_ (sp + static_cast<std::size_t> (start)),
- i_ (start),
- argc_ (argc),
- argv_ (argv),
- erase_ (erase)
- {
- }
-
- inline int argv_scanner::
- end () const
- {
- return i_;
- }
-
- // vector_scanner
- //
- inline vector_scanner::
- vector_scanner (const std::vector<std::string>& v,
- std::size_t i,
- std::size_t sp)
- : start_position_ (sp), v_ (v), i_ (i)
- {
- }
-
- inline std::size_t vector_scanner::
- end () const
- {
- return i_;
- }
-
- inline void vector_scanner::
- reset (std::size_t i, std::size_t sp)
- {
- i_ = i;
- start_position_ = sp;
- }
- }
- }
-}
-
namespace build2
{
namespace script
diff --git a/libbuild2/script/builtin.cli b/libbuild2/script/builtin.cli
index 1e3fb45..6f2143a 100644
--- a/libbuild2/script/builtin.cli
+++ b/libbuild2/script/builtin.cli
@@ -3,6 +3,8 @@
include <libbuild2/types.hxx>;
+include <libbuild2/common.cli>;
+
// Note that options in this file are undocumented because we generate neither
// the usage printing code nor man pages. Instead, they are documented in the
// Testscript Language Manual's builtin descriptions.
diff --git a/libbuild2/script/run.cxx b/libbuild2/script/run.cxx
index 12078c4..fa6067e 100644
--- a/libbuild2/script/run.cxx
+++ b/libbuild2/script/run.cxx
@@ -26,6 +26,8 @@
using namespace std;
using namespace butl;
+namespace cli = build2::build::cli;
+
namespace build2
{
namespace script