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

#ifndef LIBCOMMON_OPTIONS_HXX
#define LIBCOMMON_OPTIONS_HXX

#include <deque>
#include <iosfwd>
#include <string>
#include <exception>

namespace cli
{
  class unknown_mode
  {
    public:
    enum value
    {
      skip,
      stop,
      fail
    };

    unknown_mode (value v);

    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&
    option () const;

    const std::string&
    value () const;

    virtual void
    print (std::ostream&) const;

    virtual const char*
    what () const throw ();

    private:
    std::string option_;
    std::string value_;
  };

  class eos_reached: public exception
  {
    public:
    virtual void
    print (std::ostream&) const;

    virtual const char*
    what () const throw ();
  };

  class 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 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_;
  };

  class scanner
  {
    public:
    virtual
    ~scanner ();

    virtual bool
    more () = 0;

    virtual const char*
    peek () = 0;

    virtual const char*
    next () = 0;

    virtual void
    skip () = 0;
  };

  class argv_scanner: public scanner
  {
    public:
    argv_scanner (int& argc, char** argv, bool erase = false);
    argv_scanner (int start, int& argc, char** argv, bool erase = false);

    int
    end () const;

    virtual bool
    more ();

    virtual const char*
    peek ();

    virtual const char*
    next ();

    virtual void
    skip ();

    private:
    int i_;
    int& argc_;
    char** argv_;
    bool erase_;
  };

  class argv_file_scanner: public argv_scanner
  {
    public:
    argv_file_scanner (int& argc,
                       char** argv,
                       const std::string& file_option,
                       bool erase = false);

    argv_file_scanner (int start,
                       int& argc,
                       char** argv,
                       const std::string& file_option,
                       bool erase = false);

    virtual bool
    more ();

    virtual const char*
    peek ();

    virtual const char*
    next ();

    virtual void
    skip ();

    private:
    void
    load (const char* file);

    typedef argv_scanner base;

    const std::string option_;
    std::string hold_;
    std::deque<std::string> args_;
    bool skip_;
  };
}

#include <string>

namespace cli
{
  class mysql_options
  {
    public:

    mysql_options (int& argc,
                   char** argv,
                   bool erase = false,
                   ::cli::unknown_mode option = ::cli::unknown_mode::fail,
                   ::cli::unknown_mode argument = ::cli::unknown_mode::stop);

    mysql_options (int start,
                   int& argc,
                   char** argv,
                   bool erase = false,
                   ::cli::unknown_mode option = ::cli::unknown_mode::fail,
                   ::cli::unknown_mode argument = ::cli::unknown_mode::stop);

    mysql_options (int& argc,
                   char** argv,
                   int& end,
                   bool erase = false,
                   ::cli::unknown_mode option = ::cli::unknown_mode::fail,
                   ::cli::unknown_mode argument = ::cli::unknown_mode::stop);

    mysql_options (int start,
                   int& argc,
                   char** argv,
                   int& end,
                   bool erase = false,
                   ::cli::unknown_mode option = ::cli::unknown_mode::fail,
                   ::cli::unknown_mode argument = ::cli::unknown_mode::stop);

    mysql_options (::cli::scanner&,
                   ::cli::unknown_mode option = ::cli::unknown_mode::fail,
                   ::cli::unknown_mode argument = ::cli::unknown_mode::stop);

    // Option accessors.
    //

    const bool&
    help () const;

    const std::string&
    user () const;

    bool
    user_specified () const;

    const std::string&
    passwd () const;

    bool
    passwd_specified () const;

    const std::string&
    db_name () const;

    bool
    db_name_specified () const;

    const std::string&
    host () const;

    bool
    host_specified () const;

    const unsigned int&
    port () const;

    bool
    port_specified () const;

    const std::string&
    socket () const;

    bool
    socket_specified () const;

    const std::string&
    options_file () const;

    bool
    options_file_specified () const;

    // Print usage information.
    //
    static void
    print_usage (::std::ostream&);

    private:
    void
    _parse (::cli::scanner&,
            ::cli::unknown_mode option,
            ::cli::unknown_mode argument);

    public:
    bool help_;
    std::string user_;
    bool user_specified_;
    std::string passwd_;
    bool passwd_specified_;
    std::string db_name_;
    bool db_name_specified_;
    std::string host_;
    bool host_specified_;
    unsigned int port_;
    bool port_specified_;
    std::string socket_;
    bool socket_specified_;
    std::string options_file_;
    bool options_file_specified_;
  };
}

#include "options.ixx"

#endif // LIBCOMMON_OPTIONS_HXX