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

// Begin prologue.
//
#include <bdep/types-parsers.hxx>
//
// End prologue.

#include <bdep/common-options.hxx>

#include <map>
#include <set>
#include <string>
#include <vector>
#include <utility>
#include <ostream>
#include <sstream>
#include <cstring>
#include <fstream>

namespace bdep
{
  namespace cli
  {
    // unknown_option
    //
    unknown_option::
    ~unknown_option () noexcept
    {
    }

    void unknown_option::
    print (::std::ostream& os) const
    {
      os << "unknown option '" << option ().c_str () << "'";
    }

    const char* unknown_option::
    what () const noexcept
    {
      return "unknown option";
    }

    // unknown_argument
    //
    unknown_argument::
    ~unknown_argument () noexcept
    {
    }

    void unknown_argument::
    print (::std::ostream& os) const
    {
      os << "unknown argument '" << argument ().c_str () << "'";
    }

    const char* unknown_argument::
    what () const noexcept
    {
      return "unknown argument";
    }

    // missing_value
    //
    missing_value::
    ~missing_value () noexcept
    {
    }

    void missing_value::
    print (::std::ostream& os) const
    {
      os << "missing value for option '" << option ().c_str () << "'";
    }

    const char* missing_value::
    what () const noexcept
    {
      return "missing option value";
    }

    // invalid_value
    //
    invalid_value::
    ~invalid_value () noexcept
    {
    }

    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 noexcept
    {
      return "invalid option value";
    }

    // eos_reached
    //
    void eos_reached::
    print (::std::ostream& os) const
    {
      os << what ();
    }

    const char* eos_reached::
    what () const noexcept
    {
      return "end of argument stream reached";
    }

    // file_io_failure
    //
    file_io_failure::
    ~file_io_failure () noexcept
    {
    }

    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 noexcept
    {
      return "unable to open file or read failure";
    }

    // unmatched_quote
    //
    unmatched_quote::
    ~unmatched_quote () noexcept
    {
    }

    void unmatched_quote::
    print (::std::ostream& os) const
    {
      os << "unmatched quote in argument '" << argument ().c_str () << "'";
    }

    const char* unmatched_quote::
    what () const noexcept
    {
      return "unmatched quote";
    }

    // unexpected_group
    //
    unexpected_group::
    ~unexpected_group () noexcept
    {
    }

    void unexpected_group::
    print (::std::ostream& os) const
    {
      os << "unexpected grouped argument '" << group_ << "' "
         << "for argument '" << argument_ << "'";
    }

    const char* unexpected_group::
    what () const noexcept
    {
      return "unexpected grouped argument";
    }

    // group_separator
    //
    group_separator::
    ~group_separator () noexcept
    {
    }

    void group_separator::
    print (::std::ostream& os) const
    {
      bool ex (!expected_.empty ());
      bool en (!encountered_.empty ());

      if (ex)
      {
        os << "expected group separator '" << expected_ << "'";
        if (en)
          os << " instead of '" << encountered_ << "'";
      }
      else
        os << "unexpected group separator '" << encountered_ << "'";

      if (en)
        os << ", use '\\" << encountered_ << "' to escape";
    }

    const char* group_separator::
    what () const noexcept
    {
      bool ex (!expected_.empty ());
      bool en (!encountered_.empty ());

      return en
        ? ex ? "wrong group separator"    : "unexpected group separator"
        : ex ? "expected group separator" : "";
    }

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

    // group_scanner
    //
    bool group_scanner::
    more ()
    {
      // We don't want to call scan_group() here since that
      // would invalidate references to previous arguments.
      // But we do need to check that the previous group was
      // handled.
      //
      if (state_ == scanned)
      {
        if (group_scan_.end () != group_.size ())
          throw unexpected_group (arg_[i_][j_], group_scan_.next ());
      }

      return j_ != 0 || scan_.more ();
    }

    const char* group_scanner::
    peek ()
    {
      if (state_ != peeked)
      {
        scan_group ();
        state_ = peeked;
      }

      // Return unescaped.
      return arg_[i_][j_ - 1].c_str ();
    }

    const char* group_scanner::
    next ()
    {
      if (state_ != peeked)
        scan_group ();
      state_ = scanned;
      // Return unescaped.
      return arg_[i_][--j_].c_str ();
    }

    void group_scanner::
    skip ()
    {
      if (state_ != peeked)
        scan_group ();
      state_ = skipped;
      --j_;
    }

    std::size_t group_scanner::
    position ()
    {
      return j_ == 0 ? scan_.position () : pos_ + (arg_[i_].size () - j_);
    }

    void group_scanner::
    scan_group ()
    {
      // If the previous argument has been scanned, then make
      // sure the group has been scanned (handled) as well.
      //
      if (state_ == scanned)
      {
        if (group_scan_.end () != group_.size ())
          throw unexpected_group (arg_[i_][j_], group_scan_.next ());
      }

      // If we still have arguments in the pack, rewind the group.
      //
      if (j_ != 0)
      {
        group_scan_.reset ();
        return;
      }

      i_ += (i_ == 0 ? 1 : -1);
      group_.clear ();
      group_scan_.reset ();
      pos_ = scan_.position ();

      // Note: using group_ won't cover empty groups and using
      // j_ won't cover single-argument packs.
      //
      bool group (false), pack (false);

      do
      {
        const char* a (scan_.next ());
        size_t i (*a == '\\' ? 1 : 0);
        separator s (sense (a + i));

        if (s == none || i != 0)
        {
          if (arg_[i_].size () != 1)
            arg_[i_].resize (1);

          arg_[i_][0] = a + (s != none ? i : 0);
          j_ = 1;
          break;
        }

        // Start of a leading group for the next argument or
        // argument pack. We will only know which once we see
        // the closing separator.
        //
        if (s != open)
          throw group_separator (a, "");

        size_t n (group_.size ());

        // Scan the group until the closing separator.
        //
        s = none;
        while (s == none && scan_.more ())
        {
          a = scan_.next ();
          i = (*a == '\\' ? 1 : 0);
          s = sense (a + i);

          if (s == none || i != 0)
          {
            group_.push_back (a + (s != none ? i : 0));
            s = none;
          }
        }

        if (s == close)
        {
          size_t m (group_.size ());

          j_ = m - n;
          if (j_ == 0)
            throw group_separator ("{", "");

          if (arg_[i_].size () != j_)
            arg_[i_].resize (j_);

          // Move from group_ to arg_. Add in reverse for ease 
          // of iteration.
          //
          for (size_t j (0); j != j_; ++j)
            arg_[i_][j] = group_[m - j - 1];
          group_.resize (n);

          pack = true;
          break;
        }
        else if (s == close_plus)
          group = true;
        else
          throw group_separator ((s != none ? a : ""), "}+");
      }
      while (scan_.more ());

      // Handle the case where we have seen the leading group
      // but there are no more arguments.
      //
      if (group && j_ == 0)
        throw group_separator ("{", "");

      // Handle trailing groups, if any.
      //
      while (scan_.more ())
      {
        const char* a (scan_.peek ());
        size_t i (*a == '\\' ? 1 : 0);
        separator s (sense (a + i));

        // Next argument, argument pack, or leading group.
        //
        if (s == none || s == open || i != 0)
          break;

        if (s != open_plus)
          throw group_separator (a, "");

        group = true;

        // Scan the group until the closing separator.
        //
        scan_.next ();
        s = none;
        while (s == none && scan_.more ())
        {
          a = scan_.next ();
          i = (*a == '\\' ? 1 : 0);
          s = sense (a + i);

          if (s == none || i != 0)
          {
            group_.push_back (a + (s != none ? i : 0));
            s = none;
          }
        }

        if (s != close)
          throw group_separator ((s != none ? a : ""), "}");
      }

      // Handle the case where we have seen the argument pack
      // without leading or trailing group.
      //
      if (pack && !group)
        throw group_separator ("{", "");
    }

    void options::
    push_back (const option& o)
    {
      container_type::size_type n (size ());
      container_type::push_back (o);
      map_[o.name ()] = n;

      for (option_names::const_iterator i (o.aliases ().begin ());
           i != o.aliases ().end (); ++i)
        map_[*i] = n;
    }

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

      static void
      merge (X& b, const X& a)
      {
        b = a;
      }
    };

    template <>
    struct parser<bool>
    {
      static void
      parse (bool& x, bool& xs, scanner& s)
      {
        const char* o (s.next ());

        if (s.more ())
        {
          const char* v (s.next ());

          if (std::strcmp (v, "1")    == 0 ||
              std::strcmp (v, "true") == 0 ||
              std::strcmp (v, "TRUE") == 0 ||
              std::strcmp (v, "True") == 0)
            x = true;
          else if (std::strcmp (v, "0")     == 0 ||
                   std::strcmp (v, "false") == 0 ||
                   std::strcmp (v, "FALSE") == 0 ||
                   std::strcmp (v, "False") == 0)
            x = false;
          else
            throw invalid_value (o, v);
        }
        else
          throw missing_value (o);

        xs = true;
      }

      static void
      merge (bool& b, const bool&)
      {
        b = 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;
      }

      static void
      merge (std::string& b, const std::string& a)
      {
        b = a;
      }
    };

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

      static void
      merge (std::pair<X, std::size_t>& b, const std::pair<X, std::size_t>& a)
      {
        b = a;
      }
    };

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

      static void
      merge (std::vector<X>& b, const std::vector<X>& a)
      {
        b.insert (b.end (), a.begin (), a.end ());
      }
    };

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

      static void
      merge (std::set<X, C>& b, const std::set<X, C>& a)
      {
        b.insert (a.begin (), a.end ());
      }
    };

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

      static void
      merge (std::map<K, V, C>& b, const std::map<K, V, C>& a)
      {
        for (typename std::map<K, V, C>::const_iterator i (a.begin ()); 
             i != a.end (); 
             ++i)
          b[i->first] = i->second;
      }
    };

    template <typename K, typename V, typename C>
    struct parser<std::multimap<K, V, C> >
    {
      static void
      parse (std::multimap<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.insert (typename std::multimap<K, V, C>::value_type (k, v));
        }
        else
          throw missing_value (o);

        xs = true;
      }

      static void
      merge (std::multimap<K, V, C>& b, const std::multimap<K, V, C>& a)
      {
        for (typename std::multimap<K, V, C>::const_iterator i (a.begin ()); 
             i != a.end (); 
             ++i)
          b.insert (typename std::multimap<K, V, C>::value_type (i->first,
                                                                 i->second));
      }
    };

    template <typename X, typename T, T X::*M>
    void
    thunk (X& x, scanner& s)
    {
      parser<T>::parse (x.*M, s);
    }

    template <typename X, bool X::*M>
    void
    thunk (X& x, scanner& s)
    {
      s.next ();
      x.*M = 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);
    }
  }
}

#include <map>

namespace bdep
{
  // common_options
  //

  common_options::
  common_options ()
  : v_ (),
    V_ (),
    quiet_ (),
    verbose_ (1),
    verbose_specified_ (false),
    stdout_format_ (bdep::stdout_format::lines),
    stdout_format_specified_ (false),
    jobs_ (),
    jobs_specified_ (false),
    progress_ (),
    no_progress_ (),
    diag_color_ (),
    no_diag_color_ (),
    bpkg_ (),
    bpkg_specified_ (false),
    bpkg_option_ (),
    bpkg_option_specified_ (false),
    build_ (),
    build_specified_ (false),
    build_option_ (),
    build_option_specified_ (false),
    curl_ ("curl"),
    curl_specified_ (false),
    curl_option_ (),
    curl_option_specified_ (false),
    offline_ (),
    no_fetch_cache_ (),
    fetch_cache_ (),
    fetch_cache_specified_ (false),
    fetch_cache_session_ (),
    fetch_cache_session_specified_ (false),
    sqlite_synchronous_ (bdep::sqlite_synchronous::normal),
    sqlite_synchronous_specified_ (false),
    pager_ (),
    pager_specified_ (false),
    pager_option_ (),
    pager_option_specified_ (false),
    options_file_ (),
    options_file_specified_ (false),
    default_options_ (),
    default_options_specified_ (false),
    no_default_options_ ()
  {
  }

  void common_options::
  merge (const common_options& a)
  {
    CLI_POTENTIALLY_UNUSED (a);

    if (a.v_)
    {
      ::bdep::cli::parser< bool>::merge (
        this->v_, a.v_);
    }

    if (a.V_)
    {
      ::bdep::cli::parser< bool>::merge (
        this->V_, a.V_);
    }

    if (a.quiet_)
    {
      ::bdep::cli::parser< bool>::merge (
        this->quiet_, a.quiet_);
    }

    if (a.verbose_specified_)
    {
      ::bdep::cli::parser< uint16_t>::merge (
        this->verbose_, a.verbose_);
      this->verbose_specified_ = true;
    }

    if (a.stdout_format_specified_)
    {
      ::bdep::cli::parser< bdep::stdout_format>::merge (
        this->stdout_format_, a.stdout_format_);
      this->stdout_format_specified_ = true;
    }

    if (a.jobs_specified_)
    {
      ::bdep::cli::parser< int32_t>::merge (
        this->jobs_, a.jobs_);
      this->jobs_specified_ = true;
    }

    if (a.progress_)
    {
      ::bdep::cli::parser< bool>::merge (
        this->progress_, a.progress_);
    }

    if (a.no_progress_)
    {
      ::bdep::cli::parser< bool>::merge (
        this->no_progress_, a.no_progress_);
    }

    if (a.diag_color_)
    {
      ::bdep::cli::parser< bool>::merge (
        this->diag_color_, a.diag_color_);
    }

    if (a.no_diag_color_)
    {
      ::bdep::cli::parser< bool>::merge (
        this->no_diag_color_, a.no_diag_color_);
    }

    if (a.bpkg_specified_)
    {
      ::bdep::cli::parser< path>::merge (
        this->bpkg_, a.bpkg_);
      this->bpkg_specified_ = true;
    }

    if (a.bpkg_option_specified_)
    {
      ::bdep::cli::parser< strings>::merge (
        this->bpkg_option_, a.bpkg_option_);
      this->bpkg_option_specified_ = true;
    }

    if (a.build_specified_)
    {
      ::bdep::cli::parser< path>::merge (
        this->build_, a.build_);
      this->build_specified_ = true;
    }

    if (a.build_option_specified_)
    {
      ::bdep::cli::parser< strings>::merge (
        this->build_option_, a.build_option_);
      this->build_option_specified_ = true;
    }

    if (a.curl_specified_)
    {
      ::bdep::cli::parser< path>::merge (
        this->curl_, a.curl_);
      this->curl_specified_ = true;
    }

    if (a.curl_option_specified_)
    {
      ::bdep::cli::parser< strings>::merge (
        this->curl_option_, a.curl_option_);
      this->curl_option_specified_ = true;
    }

    if (a.offline_)
    {
      ::bdep::cli::parser< bool>::merge (
        this->offline_, a.offline_);
    }

    if (a.no_fetch_cache_)
    {
      ::bdep::cli::parser< bool>::merge (
        this->no_fetch_cache_, a.no_fetch_cache_);
    }

    if (a.fetch_cache_specified_)
    {
      ::bdep::cli::parser< string>::merge (
        this->fetch_cache_, a.fetch_cache_);
      this->fetch_cache_specified_ = true;
    }

    if (a.fetch_cache_session_specified_)
    {
      ::bdep::cli::parser< string>::merge (
        this->fetch_cache_session_, a.fetch_cache_session_);
      this->fetch_cache_session_specified_ = true;
    }

    if (a.sqlite_synchronous_specified_)
    {
      ::bdep::cli::parser< bdep::sqlite_synchronous>::merge (
        this->sqlite_synchronous_, a.sqlite_synchronous_);
      this->sqlite_synchronous_specified_ = true;
    }

    if (a.pager_specified_)
    {
      ::bdep::cli::parser< string>::merge (
        this->pager_, a.pager_);
      this->pager_specified_ = true;
    }

    if (a.pager_option_specified_)
    {
      ::bdep::cli::parser< strings>::merge (
        this->pager_option_, a.pager_option_);
      this->pager_option_specified_ = true;
    }

    if (a.options_file_specified_)
    {
      ::bdep::cli::parser< string>::merge (
        this->options_file_, a.options_file_);
      this->options_file_specified_ = true;
    }

    if (a.default_options_specified_)
    {
      ::bdep::cli::parser< dir_path>::merge (
        this->default_options_, a.default_options_);
      this->default_options_specified_ = true;
    }

    if (a.no_default_options_)
    {
      ::bdep::cli::parser< bool>::merge (
        this->no_default_options_, a.no_default_options_);
    }
  }

  ::bdep::cli::usage_para common_options::
  print_usage (::std::ostream& os, ::bdep::cli::usage_para p)
  {
    CLI_POTENTIALLY_UNUSED (os);

    if (p != ::bdep::cli::usage_para::none)
      os << ::std::endl;

    os << "\033[1mCOMMON OPTIONS\033[0m" << ::std::endl;

    os << std::endl
       << "The common options are summarized below with a more detailed description" << ::std::endl
       << "available in \033[1mbdep-common-options(1)\033[0m." << ::std::endl;

    os << std::endl
       << "\033[1m-v\033[0m                        Print essential underlying commands being executed." << ::std::endl;

    os << "\033[1m-V\033[0m                        Print all underlying commands being executed." << ::std::endl;

    os << "\033[1m--quiet\033[0m|\033[1m-q\033[0m                Run quietly, only printing error messages." << ::std::endl;

    os << "\033[1m--verbose\033[0m \033[4mlevel\033[0m           Set the diagnostics verbosity to \033[4mlevel\033[0m between 0 and" << ::std::endl
       << "                          6." << ::std::endl;

    os << "\033[1m--stdout-format\033[0m \033[4mformat\033[0m    Representation format to use for printing to \033[1mstdout\033[0m." << ::std::endl;

    os << "\033[1m--jobs\033[0m|\033[1m-j\033[0m \033[4mnum\033[0m             Number of jobs to perform in parallel." << ::std::endl;

    os << "\033[1m--progress\033[0m                Display progress indicators for long-lasting" << ::std::endl
       << "                          operations, such as network transfers, building, etc." << ::std::endl;

    os << "\033[1m--no-progress\033[0m             Suppress progress indicators for long-lasting" << ::std::endl
       << "                          operations, such as network transfers, building, etc." << ::std::endl;

    os << "\033[1m--diag-color\033[0m              Use color in diagnostics." << ::std::endl;

    os << "\033[1m--no-diag-color\033[0m           Don't use color in diagnostics." << ::std::endl;

    os << "\033[1m--bpkg\033[0m \033[4mpath\033[0m               The package manager program to be used for build" << ::std::endl
       << "                          configuration management." << ::std::endl;

    os << "\033[1m--bpkg-option\033[0m \033[4mopt\033[0m         Additional option to be passed to the package manager" << ::std::endl
       << "                          program." << ::std::endl;

    os << "\033[1m--build\033[0m \033[4mpath\033[0m              The build program to be used to build packages." << ::std::endl;

    os << "\033[1m--build-option\033[0m \033[4mopt\033[0m        Additional option to be passed to the build program." << ::std::endl;

    os << "\033[1m--curl\033[0m \033[4mpath\033[0m               The curl program to be used for network operations." << ::std::endl;

    os << "\033[1m--curl-option\033[0m \033[4mopt\033[0m         Additional option to be passed to the curl program." << ::std::endl;

    os << "\033[1m--offline\033[0m                 Do not attempt to download resources (packages," << ::std::endl
       << "                          repository metadata, etc), instead taking them from" << ::std::endl
       << "                          the local fetch cache if available and failing" << ::std::endl
       << "                          otherwise." << ::std::endl;

    os << "\033[1m--no-fetch-cache\033[0m          Disable local caching of download resources" << ::std::endl
       << "                          (packages, repository metadata, etc)." << ::std::endl;

    os << "\033[1m--fetch-cache\033[0m \033[4mmode\033[0m        Comma-separated list of local fetch cache modes." << ::std::endl;

    os << "\033[1m--fetch-cache-session\033[0m \033[4mid\033[0m  The local fetch cache session." << ::std::endl;

    os << "\033[1m--sqlite-synchronous\033[0m \033[4mmode\033[0m Filesystem synchronization mode for the project" << ::std::endl
       << "                          SQLite database." << ::std::endl;

    os << "\033[1m--pager\033[0m \033[4mpath\033[0m              The pager program to be used to show long text." << ::std::endl;

    os << "\033[1m--pager-option\033[0m \033[4mopt\033[0m        Additional option to be passed to the pager program." << ::std::endl;

    os << "\033[1m--options-file\033[0m \033[4mfile\033[0m       Read additional options from \033[4mfile\033[0m." << ::std::endl;

    os << "\033[1m--default-options\033[0m \033[4mdir\033[0m     The directory to load additional default options" << ::std::endl
       << "                          files from." << ::std::endl;

    os << "\033[1m--no-default-options\033[0m      Don't load default options files." << ::std::endl;

    p = ::bdep::cli::usage_para::option;

    return p;
  }

  ::bdep::cli::usage_para common_options::
  print_long_usage (::std::ostream& os, ::bdep::cli::usage_para p)
  {
    CLI_POTENTIALLY_UNUSED (os);

    if (p != ::bdep::cli::usage_para::none)
      os << ::std::endl;

    os << "\033[1mCOMMON OPTIONS\033[0m" << ::std::endl;

    os << std::endl
       << "\033[1m-v\033[0m                        Print essential underlying commands being executed." << ::std::endl
       << "                          This is equivalent to \033[1m--verbose 2\033[0m." << ::std::endl;

    os << std::endl
       << "\033[1m-V\033[0m                        Print all underlying commands being executed. This is" << ::std::endl
       << "                          equivalent to \033[1m--verbose 3\033[0m." << ::std::endl;

    os << std::endl
       << "\033[1m--quiet\033[0m|\033[1m-q\033[0m                Run quietly, only printing error messages. This is" << ::std::endl
       << "                          equivalent to \033[1m--verbose 0\033[0m." << ::std::endl;

    os << std::endl
       << "\033[1m--verbose\033[0m \033[4mlevel\033[0m           Set the diagnostics verbosity to \033[4mlevel\033[0m between 0 and" << ::std::endl
       << "                          6. Level 0 disables any non-error messages while" << ::std::endl
       << "                          level 6 produces lots of information, with level 1" << ::std::endl
       << "                          being the default. The following additional types of" << ::std::endl
       << "                          diagnostics are produced at each level:" << ::std::endl
       << ::std::endl
       << "                          1. High-level information messages." << ::std::endl
       << "                          2. Essential underlying commands being executed." << ::std::endl
       << "                          3. All underlying commands being executed." << ::std::endl
       << "                          4. Information that could be helpful to the user." << ::std::endl
       << "                          5. Information that could be helpful to the" << ::std::endl
       << "                          developer." << ::std::endl
       << "                          6. Even more detailed information." << ::std::endl;

    os << std::endl
       << "\033[1m--stdout-format\033[0m \033[4mformat\033[0m    Representation format to use for printing to \033[1mstdout\033[0m." << ::std::endl
       << "                          Valid values for this option are \033[1mlines\033[0m (default) and" << ::std::endl
       << "                          \033[1mjson\033[0m. See the JSON OUTPUT section below for details" << ::std::endl
       << "                          on the \033[1mjson\033[0m format." << ::std::endl;

    os << std::endl
       << "\033[1m--jobs\033[0m|\033[1m-j\033[0m \033[4mnum\033[0m             Number of jobs to perform in parallel. If this option" << ::std::endl
       << "                          is not specified or specified with the 0\033[0m value, then" << ::std::endl
       << "                          the number of available hardware threads is used. If" << ::std::endl
       << "                          the specified value is negative, then the number of" << ::std::endl
       << "                          available hardware threads reduced by this value is" << ::std::endl
       << "                          used. This option is also propagated when executing" << ::std::endl
       << "                          package manager commands such as \033[1mbpkg-pkg-update(1)\033[0m," << ::std::endl
       << "                          \033[1mbpkg-pkg-test(1)\033[0m, etc., which in turn propagate it to" << ::std::endl
       << "                          the build system." << ::std::endl;

    os << std::endl
       << "\033[1m--progress\033[0m                Display progress indicators for long-lasting" << ::std::endl
       << "                          operations, such as network transfers, building, etc." << ::std::endl
       << "                          If printing to a terminal the progress is displayed" << ::std::endl
       << "                          by default for low verbosity levels. Use" << ::std::endl
       << "                          \033[1m--no-progress\033[0m to suppress." << ::std::endl;

    os << std::endl
       << "\033[1m--no-progress\033[0m             Suppress progress indicators for long-lasting" << ::std::endl
       << "                          operations, such as network transfers, building, etc." << ::std::endl;

    os << std::endl
       << "\033[1m--diag-color\033[0m              Use color in diagnostics. If printing to a terminal" << ::std::endl
       << "                          the color is used by default provided the terminal is" << ::std::endl
       << "                          not dumb. Use \033[1m--no-diag-color\033[0m to suppress." << ::std::endl;

    os << std::endl
       << "\033[1m--no-diag-color\033[0m           Don't use color in diagnostics." << ::std::endl;

    os << std::endl
       << "\033[1m--bpkg\033[0m \033[4mpath\033[0m               The package manager program to be used for build" << ::std::endl
       << "                          configuration management. This should be the path to" << ::std::endl
       << "                          the \033[1mbpkg\033[0m executable. You can also specify additional" << ::std::endl
       << "                          options that should be passed to the package manager" << ::std::endl
       << "                          program with \033[1m--bpkg-option\033[0m." << ::std::endl
       << ::std::endl
       << "                          If the package manager program is not explicitly" << ::std::endl
       << "                          specified, then \033[1mbdep\033[0m will by default use \033[1mbpkg\033[0m plus an" << ::std::endl
       << "                          executable suffix if one was specified when building" << ::std::endl
       << "                          \033[1mbdep\033[0m. So, for example, if \033[1mbdep\033[0m name was set to" << ::std::endl
       << "                          \033[1mbdep-1.0\033[0m, then it will look for \033[1mbpkg-1.0\033[0m." << ::std::endl;

    os << std::endl
       << "\033[1m--bpkg-option\033[0m \033[4mopt\033[0m         Additional option to be passed to the package manager" << ::std::endl
       << "                          program. See \033[1m--bpkg\033[0m for more information on the" << ::std::endl
       << "                          package manager program. Repeat this option to" << ::std::endl
       << "                          specify multiple package manager options." << ::std::endl;

    os << std::endl
       << "\033[1m--build\033[0m \033[4mpath\033[0m              The build program to be used to build packages. This" << ::std::endl
       << "                          should be the path to the build2 \033[1mb\033[0m executable. You" << ::std::endl
       << "                          can also specify additional options that should be" << ::std::endl
       << "                          passed to the build program with \033[1m--build-option\033[0m." << ::std::endl
       << ::std::endl
       << "                          If the build program is not explicitly specified," << ::std::endl
       << "                          then \033[1mbdep\033[0m will by default use \033[1mb\033[0m plus an executable" << ::std::endl
       << "                          suffix if one was specified when building \033[1mbdep\033[0m. So," << ::std::endl
       << "                          for example, if \033[1mbdep\033[0m name was set to \033[1mbdep-1.0\033[0m, then" << ::std::endl
       << "                          it will look for \033[1mb-1.0\033[0m." << ::std::endl;

    os << std::endl
       << "\033[1m--build-option\033[0m \033[4mopt\033[0m        Additional option to be passed to the build program." << ::std::endl
       << "                          See \033[1m--build\033[0m for more information on the build" << ::std::endl
       << "                          program. Repeat this option to specify multiple build" << ::std::endl
       << "                          options." << ::std::endl;

    os << std::endl
       << "\033[1m--curl\033[0m \033[4mpath\033[0m               The curl program to be used for network operations." << ::std::endl
       << "                          You can also specify additional options that should" << ::std::endl
       << "                          be passed to the curl program with \033[1m--curl-option\033[0m." << ::std::endl
       << ::std::endl
       << "                          If the curl program is not explicitly specified, then" << ::std::endl
       << "                          \033[1mbdep\033[0m will use \033[1mcurl\033[0m by default. Note that this program" << ::std::endl
       << "                          will also be used by the underlying \033[1mbpkg\033[0m invocations" << ::std::endl
       << "                          unless overridden." << ::std::endl;

    os << std::endl
       << "\033[1m--curl-option\033[0m \033[4mopt\033[0m         Additional option to be passed to the curl program." << ::std::endl
       << "                          See \033[1m--curl\033[0m for more information on the curl program." << ::std::endl
       << "                          Repeat this option to specify multiple curl options." << ::std::endl
       << ::std::endl
       << "                          Note that these options will also be used by the" << ::std::endl
       << "                          underlying \033[1mbpkg\033[0m invocations provided that curl is" << ::std::endl
       << "                          used." << ::std::endl;

    os << std::endl
       << "\033[1m--offline\033[0m                 Do not attempt to download resources (packages," << ::std::endl
       << "                          repository metadata, etc), instead taking them from" << ::std::endl
       << "                          the local fetch cache if available and failing" << ::std::endl
       << "                          otherwise. See \033[1mbpkg-common-options(1)\033[0m for details on" << ::std::endl
       << "                          the offline mode." << ::std::endl;

    os << std::endl
       << "\033[1m--no-fetch-cache\033[0m          Disable local caching of download resources" << ::std::endl
       << "                          (packages, repository metadata, etc). By default" << ::std::endl
       << "                          these are cached in a permanent local cache. See" << ::std::endl
       << "                          \033[1mbpkg-common-options(1)\033[0m for details on the fetch" << ::std::endl
       << "                          cache." << ::std::endl;

    os << std::endl
       << "\033[1m--fetch-cache\033[0m \033[4mmode\033[0m        Comma-separated list of local fetch cache modes. See" << ::std::endl
       << "                          \033[1mbpkg-common-options(1)\033[0m for details on the available" << ::std::endl
       << "                          modes. Note that the default for \033[1mbdep\033[0m is to enable" << ::std::endl
       << "                          sharing of cached source directories for dependencies" << ::std::endl
       << "                          during the configuration creation." << ::std::endl;

    os << std::endl
       << "\033[1m--fetch-cache-session\033[0m \033[4mid\033[0m  The local fetch cache session. Specifying the same" << ::std::endl
       << "                          session id across multiple \033[1mbdep\033[0m invocations allows" << ::std::endl
       << "                          eliminating repeated up-to-date checks of repository" << ::std::endl
       << "                          metadata. Any value, such as UUID, that is guaranteed" << ::std::endl
       << "                          not to clash with previous sessions can be used as a" << ::std::endl
       << "                          session id. See \033[1mbpkg-common-options(1)\033[0m for details on" << ::std::endl
       << "                          the fetch cache." << ::std::endl;

    os << std::endl
       << "\033[1m--sqlite-synchronous\033[0m \033[4mmode\033[0m Filesystem synchronization mode for the project" << ::std::endl
       << "                          SQLite database. Valid values are \033[1moff\033[0m, \033[1mnormal\033[0m" << ::std::endl
       << "                          (default), \033[1mfull\033[0m, and \033[1mextra\033[0m. See the SQLite" << ::std::endl
       << "                          documentation on the \033[1msynchronous\033[0m pragma for details." << ::std::endl
       << "                          See also the \033[1mBUILD2_SQLITE_SYNCHRONOUS\033[0m environment" << ::std::endl
       << "                          variable." << ::std::endl
       << ::std::endl
       << "                          Note that WAL (Write-Ahead Logging) journaling mode" << ::std::endl
       << "                          is used for the project database. Note also that this" << ::std::endl
       << "                          option is not passed to the underlying \033[1mbpkg\033[0m commands" << ::std::endl
       << "                          (use \033[1m--bpkg-option\033[0m for that)." << ::std::endl;

    os << std::endl
       << "\033[1m--pager\033[0m \033[4mpath\033[0m              The pager program to be used to show long text." << ::std::endl
       << "                          Commonly used pager programs are \033[1mless\033[0m and \033[1mmore\033[0m. You" << ::std::endl
       << "                          can also specify additional options that should be" << ::std::endl
       << "                          passed to the pager program with \033[1m--pager-option\033[0m. If" << ::std::endl
       << "                          an empty string is specified as the pager program," << ::std::endl
       << "                          then no pager will be used. If the pager program is" << ::std::endl
       << "                          not explicitly specified, then \033[1mbdep\033[0m will try to use" << ::std::endl
       << "                          \033[1mless\033[0m. If it is not available, then no pager will be" << ::std::endl
       << "                          used." << ::std::endl;

    os << std::endl
       << "\033[1m--pager-option\033[0m \033[4mopt\033[0m        Additional option to be passed to the pager program." << ::std::endl
       << "                          See \033[1m--pager\033[0m for more information on the pager" << ::std::endl
       << "                          program. Repeat this option to specify multiple pager" << ::std::endl
       << "                          options." << ::std::endl;

    os << std::endl
       << "\033[1m--options-file\033[0m \033[4mfile\033[0m       Read additional options from \033[4mfile\033[0m. Each option should" << ::std::endl
       << "                          appear on a separate line optionally followed by" << ::std::endl
       << "                          space or equal sign (\033[1m=\033[0m) and an option value. Empty" << ::std::endl
       << "                          lines and lines starting with \033[1m#\033[0m are ignored. Option" << ::std::endl
       << "                          values can be enclosed in double (\033[1m\"\033[0m) or single (\033[1m'\033[0m)" << ::std::endl
       << "                          quotes to preserve leading and trailing whitespaces" << ::std::endl
       << "                          as well as to specify empty values. If the value" << ::std::endl
       << "                          itself contains trailing or leading quotes, enclose" << ::std::endl
       << "                          it with an extra pair of quotes, for example \033[1m'\"x\"'\033[0m." << ::std::endl
       << "                          Non-leading and non-trailing quotes are interpreted" << ::std::endl
       << "                          as being part of the option value." << ::std::endl
       << ::std::endl
       << "                          The semantics of providing options in a file is" << ::std::endl
       << "                          equivalent to providing the same set of options in" << ::std::endl
       << "                          the same order on the command line at the point where" << ::std::endl
       << "                          the \033[1m--options-file\033[0m option is specified except that" << ::std::endl
       << "                          the shell escaping and quoting is not required." << ::std::endl
       << "                          Repeat this option to specify more than one options" << ::std::endl
       << "                          file." << ::std::endl;

    os << std::endl
       << "\033[1m--default-options\033[0m \033[4mdir\033[0m     The directory to load additional default options" << ::std::endl
       << "                          files from." << ::std::endl;

    os << std::endl
       << "\033[1m--no-default-options\033[0m      Don't load default options files." << ::std::endl;

    p = ::bdep::cli::usage_para::option;

    return p;
  }

  struct _cli_common_options_desc_type: ::bdep::cli::options
  {
    _cli_common_options_desc_type ()
    {
      ::bdep::common_options::fill (*this);
    }
  };

  void common_options::
  fill (::bdep::cli::options& os)
  {
    // -v
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("-v", a, true, dv);
      os.push_back (o);
    }

    // -V
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("-V", a, true, dv);
      os.push_back (o);
    }

    // --quiet
    //
    {
      ::bdep::cli::option_names a;
      a.push_back ("-q");
      std::string dv;
      ::bdep::cli::option o ("--quiet", a, true, dv);
      os.push_back (o);
    }

    // --verbose
    //
    {
      ::bdep::cli::option_names a;
      std::string dv ("1");
      ::bdep::cli::option o ("--verbose", a, false, dv);
      os.push_back (o);
    }

    // --stdout-format
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--stdout-format", a, false, dv);
      os.push_back (o);
    }

    // --jobs
    //
    {
      ::bdep::cli::option_names a;
      a.push_back ("-j");
      std::string dv;
      ::bdep::cli::option o ("--jobs", a, false, dv);
      os.push_back (o);
    }

    // --progress
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--progress", a, true, dv);
      os.push_back (o);
    }

    // --no-progress
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--no-progress", a, true, dv);
      os.push_back (o);
    }

    // --diag-color
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--diag-color", a, true, dv);
      os.push_back (o);
    }

    // --no-diag-color
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--no-diag-color", a, true, dv);
      os.push_back (o);
    }

    // --bpkg
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--bpkg", a, false, dv);
      os.push_back (o);
    }

    // --bpkg-option
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--bpkg-option", a, false, dv);
      os.push_back (o);
    }

    // --build
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--build", a, false, dv);
      os.push_back (o);
    }

    // --build-option
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--build-option", a, false, dv);
      os.push_back (o);
    }

    // --curl
    //
    {
      ::bdep::cli::option_names a;
      std::string dv ("curl");
      ::bdep::cli::option o ("--curl", a, false, dv);
      os.push_back (o);
    }

    // --curl-option
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--curl-option", a, false, dv);
      os.push_back (o);
    }

    // --offline
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--offline", a, true, dv);
      os.push_back (o);
    }

    // --no-fetch-cache
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--no-fetch-cache", a, true, dv);
      os.push_back (o);
    }

    // --fetch-cache
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--fetch-cache", a, false, dv);
      os.push_back (o);
    }

    // --fetch-cache-session
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--fetch-cache-session", a, false, dv);
      os.push_back (o);
    }

    // --sqlite-synchronous
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--sqlite-synchronous", a, false, dv);
      os.push_back (o);
    }

    // --pager
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--pager", a, false, dv);
      os.push_back (o);
    }

    // --pager-option
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--pager-option", a, false, dv);
      os.push_back (o);
    }

    // --options-file
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--options-file", a, false, dv);
      os.push_back (o);
    }

    // --default-options
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--default-options", a, false, dv);
      os.push_back (o);
    }

    // --no-default-options
    //
    {
      ::bdep::cli::option_names a;
      std::string dv;
      ::bdep::cli::option o ("--no-default-options", a, true, dv);
      os.push_back (o);
    }
  }

  const ::bdep::cli::options& common_options::
  description ()
  {
    static _cli_common_options_desc_type _cli_common_options_desc_;
    return _cli_common_options_desc_;
  }

  typedef
  std::map<std::string, void (*) (common_options&, ::bdep::cli::scanner&)>
  _cli_common_options_map;

  static _cli_common_options_map _cli_common_options_map_;

  struct _cli_common_options_map_init
  {
    _cli_common_options_map_init ()
    {
      _cli_common_options_map_["-v"] =
      &::bdep::cli::thunk< common_options, &common_options::v_ >;
      _cli_common_options_map_["-V"] =
      &::bdep::cli::thunk< common_options, &common_options::V_ >;
      _cli_common_options_map_["--quiet"] =
      &::bdep::cli::thunk< common_options, &common_options::quiet_ >;
      _cli_common_options_map_["-q"] =
      &::bdep::cli::thunk< common_options, &common_options::quiet_ >;
      _cli_common_options_map_["--verbose"] =
      &::bdep::cli::thunk< common_options, uint16_t, &common_options::verbose_,
        &common_options::verbose_specified_ >;
      _cli_common_options_map_["--stdout-format"] =
      &::bdep::cli::thunk< common_options, bdep::stdout_format, &common_options::stdout_format_,
        &common_options::stdout_format_specified_ >;
      _cli_common_options_map_["--jobs"] =
      &::bdep::cli::thunk< common_options, int32_t, &common_options::jobs_,
        &common_options::jobs_specified_ >;
      _cli_common_options_map_["-j"] =
      &::bdep::cli::thunk< common_options, int32_t, &common_options::jobs_,
        &common_options::jobs_specified_ >;
      _cli_common_options_map_["--progress"] =
      &::bdep::cli::thunk< common_options, &common_options::progress_ >;
      _cli_common_options_map_["--no-progress"] =
      &::bdep::cli::thunk< common_options, &common_options::no_progress_ >;
      _cli_common_options_map_["--diag-color"] =
      &::bdep::cli::thunk< common_options, &common_options::diag_color_ >;
      _cli_common_options_map_["--no-diag-color"] =
      &::bdep::cli::thunk< common_options, &common_options::no_diag_color_ >;
      _cli_common_options_map_["--bpkg"] =
      &::bdep::cli::thunk< common_options, path, &common_options::bpkg_,
        &common_options::bpkg_specified_ >;
      _cli_common_options_map_["--bpkg-option"] =
      &::bdep::cli::thunk< common_options, strings, &common_options::bpkg_option_,
        &common_options::bpkg_option_specified_ >;
      _cli_common_options_map_["--build"] =
      &::bdep::cli::thunk< common_options, path, &common_options::build_,
        &common_options::build_specified_ >;
      _cli_common_options_map_["--build-option"] =
      &::bdep::cli::thunk< common_options, strings, &common_options::build_option_,
        &common_options::build_option_specified_ >;
      _cli_common_options_map_["--curl"] =
      &::bdep::cli::thunk< common_options, path, &common_options::curl_,
        &common_options::curl_specified_ >;
      _cli_common_options_map_["--curl-option"] =
      &::bdep::cli::thunk< common_options, strings, &common_options::curl_option_,
        &common_options::curl_option_specified_ >;
      _cli_common_options_map_["--offline"] =
      &::bdep::cli::thunk< common_options, &common_options::offline_ >;
      _cli_common_options_map_["--no-fetch-cache"] =
      &::bdep::cli::thunk< common_options, &common_options::no_fetch_cache_ >;
      _cli_common_options_map_["--fetch-cache"] =
      &::bdep::cli::thunk< common_options, string, &common_options::fetch_cache_,
        &common_options::fetch_cache_specified_ >;
      _cli_common_options_map_["--fetch-cache-session"] =
      &::bdep::cli::thunk< common_options, string, &common_options::fetch_cache_session_,
        &common_options::fetch_cache_session_specified_ >;
      _cli_common_options_map_["--sqlite-synchronous"] =
      &::bdep::cli::thunk< common_options, bdep::sqlite_synchronous, &common_options::sqlite_synchronous_,
        &common_options::sqlite_synchronous_specified_ >;
      _cli_common_options_map_["--pager"] =
      &::bdep::cli::thunk< common_options, string, &common_options::pager_,
        &common_options::pager_specified_ >;
      _cli_common_options_map_["--pager-option"] =
      &::bdep::cli::thunk< common_options, strings, &common_options::pager_option_,
        &common_options::pager_option_specified_ >;
      _cli_common_options_map_["--options-file"] =
      &::bdep::cli::thunk< common_options, string, &common_options::options_file_,
        &common_options::options_file_specified_ >;
      _cli_common_options_map_["--default-options"] =
      &::bdep::cli::thunk< common_options, dir_path, &common_options::default_options_,
        &common_options::default_options_specified_ >;
      _cli_common_options_map_["--no-default-options"] =
      &::bdep::cli::thunk< common_options, &common_options::no_default_options_ >;
    }
  };

  static _cli_common_options_map_init _cli_common_options_map_init_;

  bool common_options::
  _parse (const char* o, ::bdep::cli::scanner& s)
  {
    _cli_common_options_map::const_iterator i (_cli_common_options_map_.find (o));

    if (i != _cli_common_options_map_.end ())
    {
      (*(i->second)) (*this, s);
      return true;
    }

    return false;
  }
}

namespace bdep
{
  ::bdep::cli::usage_para
  print_bdep_common_options_usage (::std::ostream& os, ::bdep::cli::usage_para p)
  {
    CLI_POTENTIALLY_UNUSED (os);

    if (p != ::bdep::cli::usage_para::none)
      os << ::std::endl;

    os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
       << ::std::endl
       << "\033[1mbdep\033[0m [\033[4mcommon-options\033[0m] ...\033[0m" << ::std::endl
       << ::std::endl
       << "\033[1mDESCRIPTION\033[0m" << ::std::endl
       << ::std::endl
       << "The common options control behavior that is common to all or most of the \033[1mbdep\033[0m" << ::std::endl
       << "commands. They can be specified either before the command or after, together" << ::std::endl
       << "with the command-specific options." << ::std::endl;

    p = ::bdep::common_options::print_usage (os, ::bdep::cli::usage_para::text);

    if (p != ::bdep::cli::usage_para::none)
      os << ::std::endl;

    os << "\033[1mJSON OUTPUT\033[0m" << ::std::endl
       << ::std::endl
       << "Commands that support the JSON output specify their formats as a serialized" << ::std::endl
       << "representation of a C++ \033[1mstruct\033[0m or an array thereof. For example:" << ::std::endl
       << ::std::endl
       << "struct package" << ::std::endl
       << "{" << ::std::endl
       << "  string name;" << ::std::endl
       << "};" << ::std::endl
       << ::std::endl
       << "struct configuration" << ::std::endl
       << "{" << ::std::endl
       << "  uint64_t         id;" << ::std::endl
       << "  string           path;" << ::std::endl
       << "  optional<string> name;" << ::std::endl
       << "  bool             default;" << ::std::endl
       << "  vector<package>  packages;" << ::std::endl
       << "};" << ::std::endl
       << ::std::endl
       << "An example of the serialized JSON representation of \033[1mstruct\033[0m \033[1mconfiguration\033[0m:" << ::std::endl
       << ::std::endl
       << "{" << ::std::endl
       << "  \"id\": 1," << ::std::endl
       << "  \"path\": \"/tmp/hello-gcc\"," << ::std::endl
       << "  \"name\": \"gcc\"," << ::std::endl
       << "  \"default\": true," << ::std::endl
       << "  \"packages\": [" << ::std::endl
       << "    {" << ::std::endl
       << "      \"name\": \"hello\"" << ::std::endl
       << "    }" << ::std::endl
       << "  ]" << ::std::endl
       << "}" << ::std::endl
       << ::std::endl
       << "This sections provides details on the overall properties of such formats and" << ::std::endl
       << "the semantics of the \033[1mstruct\033[0m serialization." << ::std::endl
       << ::std::endl
       << "The order of members in a JSON object is fixed as specified in the" << ::std::endl
       << "corresponding \033[1mstruct\033[0m. While new members may be added in the future (and should" << ::std::endl
       << "be ignored by older consumers), the semantics of the existing members" << ::std::endl
       << "(including whether the top-level entry is an object or array) may not change." << ::std::endl
       << ::std::endl
       << "An object member is required unless its type is \033[1moptional<>\033[0m, \033[1mbool\033[0m, or \033[1mvector<>\033[0m" << ::std::endl
       << "(array). For \033[1mbool\033[0m members absent means \033[1mfalse\033[0m. For \033[1mvector<>\033[0m members absent means" << ::std::endl
       << "empty. An empty top-level array is always present." << ::std::endl
       << ::std::endl
       << "For example, the following JSON text is a possible serialization of the above" << ::std::endl
       << "\033[1mstruct\033[0m \033[1mconfiguration\033[0m:" << ::std::endl
       << ::std::endl
       << "{" << ::std::endl
       << "  \"id\": 1," << ::std::endl
       << "  \"path\": \"/tmp/hello-gcc\"" << ::std::endl
       << "}" << ::std::endl;

    os << std::endl
       << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
       << ::std::endl
       << "See \033[1mbdep-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
       << "The following common options cannot be specified in the default options files:" << ::std::endl
       << ::std::endl
       << "--fetch-cache-session" << ::std::endl;

    p = ::bdep::cli::usage_para::text;

    return p;
  }

  ::bdep::cli::usage_para
  print_bdep_common_options_long_usage (::std::ostream& os, ::bdep::cli::usage_para p)
  {
    CLI_POTENTIALLY_UNUSED (os);

    if (p != ::bdep::cli::usage_para::none)
      os << ::std::endl;

    os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
       << ::std::endl
       << "\033[1mbdep\033[0m [\033[4mcommon-options\033[0m] ...\033[0m" << ::std::endl
       << ::std::endl
       << "\033[1mDESCRIPTION\033[0m" << ::std::endl
       << ::std::endl
       << "The common options control behavior that is common to all or most of the \033[1mbdep\033[0m" << ::std::endl
       << "commands. They can be specified either before the command or after, together" << ::std::endl
       << "with the command-specific options." << ::std::endl;

    p = ::bdep::common_options::print_long_usage (os, ::bdep::cli::usage_para::text);

    if (p != ::bdep::cli::usage_para::none)
      os << ::std::endl;

    os << "\033[1mJSON OUTPUT\033[0m" << ::std::endl
       << ::std::endl
       << "Commands that support the JSON output specify their formats as a serialized" << ::std::endl
       << "representation of a C++ \033[1mstruct\033[0m or an array thereof. For example:" << ::std::endl
       << ::std::endl
       << "struct package" << ::std::endl
       << "{" << ::std::endl
       << "  string name;" << ::std::endl
       << "};" << ::std::endl
       << ::std::endl
       << "struct configuration" << ::std::endl
       << "{" << ::std::endl
       << "  uint64_t         id;" << ::std::endl
       << "  string           path;" << ::std::endl
       << "  optional<string> name;" << ::std::endl
       << "  bool             default;" << ::std::endl
       << "  vector<package>  packages;" << ::std::endl
       << "};" << ::std::endl
       << ::std::endl
       << "An example of the serialized JSON representation of \033[1mstruct\033[0m \033[1mconfiguration\033[0m:" << ::std::endl
       << ::std::endl
       << "{" << ::std::endl
       << "  \"id\": 1," << ::std::endl
       << "  \"path\": \"/tmp/hello-gcc\"," << ::std::endl
       << "  \"name\": \"gcc\"," << ::std::endl
       << "  \"default\": true," << ::std::endl
       << "  \"packages\": [" << ::std::endl
       << "    {" << ::std::endl
       << "      \"name\": \"hello\"" << ::std::endl
       << "    }" << ::std::endl
       << "  ]" << ::std::endl
       << "}" << ::std::endl
       << ::std::endl
       << "This sections provides details on the overall properties of such formats and" << ::std::endl
       << "the semantics of the \033[1mstruct\033[0m serialization." << ::std::endl
       << ::std::endl
       << "The order of members in a JSON object is fixed as specified in the" << ::std::endl
       << "corresponding \033[1mstruct\033[0m. While new members may be added in the future (and should" << ::std::endl
       << "be ignored by older consumers), the semantics of the existing members" << ::std::endl
       << "(including whether the top-level entry is an object or array) may not change." << ::std::endl
       << ::std::endl
       << "An object member is required unless its type is \033[1moptional<>\033[0m, \033[1mbool\033[0m, or \033[1mvector<>\033[0m" << ::std::endl
       << "(array). For \033[1mbool\033[0m members absent means \033[1mfalse\033[0m. For \033[1mvector<>\033[0m members absent means" << ::std::endl
       << "empty. An empty top-level array is always present." << ::std::endl
       << ::std::endl
       << "For example, the following JSON text is a possible serialization of the above" << ::std::endl
       << "\033[1mstruct\033[0m \033[1mconfiguration\033[0m:" << ::std::endl
       << ::std::endl
       << "{" << ::std::endl
       << "  \"id\": 1," << ::std::endl
       << "  \"path\": \"/tmp/hello-gcc\"" << ::std::endl
       << "}" << ::std::endl;

    os << std::endl
       << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
       << ::std::endl
       << "See \033[1mbdep-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
       << "The following common options cannot be specified in the default options files:" << ::std::endl
       << ::std::endl
       << "--fetch-cache-session" << ::std::endl;

    p = ::bdep::cli::usage_para::text;

    return p;
  }
}

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

