// -*- C++ -*-
//
// This file was generated by CLI, a command line interface
// compiler for C++.
//

#ifndef LIBBUILD2_BUILD_SCRIPT_BUILTIN_OPTIONS_HXX
#define LIBBUILD2_BUILD_SCRIPT_BUILTIN_OPTIONS_HXX

// Begin prologue.
//
//
// 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>

namespace build2
{
  namespace build
  {
    namespace script
    {
      class depdb_dyndep_options
      {
        public:
        depdb_dyndep_options ();

        // Return true if anything has been parsed.
        //
        bool
        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);

        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);

        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);

        bool
        parse (int start,
               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);

        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);

        // Option accessors and modifiers.
        //
        const path&
        file () const;

        path&
        file ();

        void
        file (const path&);

        bool
        file_specified () const;

        void
        file_specified (bool);

        const string&
        format () const;

        string&
        format ();

        void
        format (const string&);

        bool
        format_specified () const;

        void
        format_specified (bool);

        const string&
        what () const;

        string&
        what ();

        void
        what (const string&);

        bool
        what_specified () const;

        void
        what_specified (bool);

        const dir_paths&
        include_path () const;

        dir_paths&
        include_path ();

        void
        include_path (const dir_paths&);

        bool
        include_path_specified () const;

        void
        include_path_specified (bool);

        const string&
        default_type () const;

        string&
        default_type ();

        void
        default_type (const string&);

        bool
        default_type_specified () const;

        void
        default_type_specified (bool);

        const bool&
        adhoc () const;

        bool&
        adhoc ();

        void
        adhoc (const bool&);

        const dir_path&
        cwd () const;

        dir_path&
        cwd ();

        void
        cwd (const dir_path&);

        bool
        cwd_specified () const;

        void
        cwd_specified (bool);

        const bool&
        drop_cycles () const;

        bool&
        drop_cycles ();

        void
        drop_cycles (const bool&);

        // Implementation details.
        //
        protected:
        bool
        _parse (const char*, ::build2::build::script::cli::scanner&);

        private:
        bool
        _parse (::build2::build::script::cli::scanner&,
                ::build2::build::script::cli::unknown_mode option,
                ::build2::build::script::cli::unknown_mode argument);

        public:
        path file_;
        bool file_specified_;
        string format_;
        bool format_specified_;
        string what_;
        bool what_specified_;
        dir_paths include_path_;
        bool include_path_specified_;
        string default_type_;
        bool default_type_specified_;
        bool adhoc_;
        dir_path cwd_;
        bool cwd_specified_;
        bool drop_cycles_;
      };
    }
  }
}

#include <libbuild2/build/script/builtin-options.ixx>

// Begin epilogue.
//
//
// End epilogue.

#endif // LIBBUILD2_BUILD_SCRIPT_BUILTIN_OPTIONS_HXX