aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/argument-grouping.cxx84
-rw-r--r--bpkg/argument-grouping.hxx31
-rw-r--r--bpkg/bpkg-options.cxx1664
-rw-r--r--bpkg/bpkg-options.hxx391
-rw-r--r--bpkg/bpkg-options.ixx231
-rw-r--r--bpkg/cfg-create-options.cxx883
-rw-r--r--bpkg/cfg-create-options.hxx173
-rw-r--r--bpkg/cfg-create-options.ixx117
-rw-r--r--bpkg/cfg-info-options.cxx745
-rw-r--r--bpkg/cfg-info-options.hxx125
-rw-r--r--bpkg/cfg-info-options.ixx45
-rw-r--r--bpkg/cfg-link-options.cxx715
-rw-r--r--bpkg/cfg-link-options.hxx121
-rw-r--r--bpkg/cfg-link-options.ixx39
-rw-r--r--bpkg/cfg-unlink-options.cxx732
-rw-r--r--bpkg/cfg-unlink-options.hxx137
-rw-r--r--bpkg/cfg-unlink-options.ixx63
-rw-r--r--bpkg/common-options.cxx2230
-rw-r--r--bpkg/common-options.hxx1235
-rw-r--r--bpkg/common-options.ixx1436
-rw-r--r--bpkg/configuration-options.cxx653
-rw-r--r--bpkg/configuration-options.hxx117
-rw-r--r--bpkg/configuration-options.ixx33
-rw-r--r--bpkg/default-options-files.cxx91
-rw-r--r--bpkg/default-options-files.hxx31
-rw-r--r--bpkg/fetch-git.cxx24
-rw-r--r--bpkg/help-options.cxx657
-rw-r--r--bpkg/help-options.hxx109
-rw-r--r--bpkg/help-options.ixx21
-rw-r--r--bpkg/package-odb.cxx19100
-rw-r--r--bpkg/package-odb.hxx6023
-rw-r--r--bpkg/package-odb.ixx1038
-rw-r--r--bpkg/pkg-bindist-options.cxx3081
-rw-r--r--bpkg/pkg-bindist-options.hxx742
-rw-r--r--bpkg/pkg-bindist-options.ixx537
-rw-r--r--bpkg/pkg-build-options.cxx1846
-rw-r--r--bpkg/pkg-build-options.hxx738
-rw-r--r--bpkg/pkg-build-options.ixx1014
-rw-r--r--bpkg/pkg-checkout-options.cxx728
-rw-r--r--bpkg/pkg-checkout-options.hxx125
-rw-r--r--bpkg/pkg-checkout-options.ixx45
-rw-r--r--bpkg/pkg-clean-options.cxx742
-rw-r--r--bpkg/pkg-clean-options.hxx129
-rw-r--r--bpkg/pkg-clean-options.ixx51
-rw-r--r--bpkg/pkg-configure-options.cxx679
-rw-r--r--bpkg/pkg-configure-options.hxx109
-rw-r--r--bpkg/pkg-configure-options.ixx21
-rw-r--r--bpkg/pkg-disfigure-options.cxx701
-rw-r--r--bpkg/pkg-disfigure-options.hxx117
-rw-r--r--bpkg/pkg-disfigure-options.ixx33
-rw-r--r--bpkg/pkg-drop-options.cxx845
-rw-r--r--bpkg/pkg-drop-options.hxx165
-rw-r--r--bpkg/pkg-drop-options.ixx105
-rw-r--r--bpkg/pkg-fetch-options.cxx727
-rw-r--r--bpkg/pkg-fetch-options.hxx121
-rw-r--r--bpkg/pkg-fetch-options.ixx39
-rw-r--r--bpkg/pkg-install-options.cxx750
-rw-r--r--bpkg/pkg-install-options.hxx129
-rw-r--r--bpkg/pkg-install-options.ixx51
-rw-r--r--bpkg/pkg-purge-options.cxx707
-rw-r--r--bpkg/pkg-purge-options.hxx117
-rw-r--r--bpkg/pkg-purge-options.ixx33
-rw-r--r--bpkg/pkg-status-options.cxx973
-rw-r--r--bpkg/pkg-status-options.hxx149
-rw-r--r--bpkg/pkg-status-options.ixx81
-rw-r--r--bpkg/pkg-test-options.cxx758
-rw-r--r--bpkg/pkg-test-options.hxx133
-rw-r--r--bpkg/pkg-test-options.ixx57
-rw-r--r--bpkg/pkg-uninstall-options.cxx743
-rw-r--r--bpkg/pkg-uninstall-options.hxx129
-rw-r--r--bpkg/pkg-uninstall-options.ixx51
-rw-r--r--bpkg/pkg-unpack-options.cxx741
-rw-r--r--bpkg/pkg-unpack-options.hxx121
-rw-r--r--bpkg/pkg-unpack-options.ixx39
-rw-r--r--bpkg/pkg-update-options.cxx763
-rw-r--r--bpkg/pkg-update-options.hxx137
-rw-r--r--bpkg/pkg-update-options.ixx63
-rw-r--r--bpkg/pkg-verify-options.cxx731
-rw-r--r--bpkg/pkg-verify-options.hxx125
-rw-r--r--bpkg/pkg-verify-options.ixx45
-rw-r--r--bpkg/rep-add-options.cxx703
-rw-r--r--bpkg/rep-add-options.hxx119
-rw-r--r--bpkg/rep-add-options.ixx33
-rw-r--r--bpkg/rep-create-options.cxx727
-rw-r--r--bpkg/rep-create-options.hxx129
-rw-r--r--bpkg/rep-create-options.ixx51
-rw-r--r--bpkg/rep-fetch-options.cxx694
-rw-r--r--bpkg/rep-fetch-options.hxx113
-rw-r--r--bpkg/rep-fetch-options.ixx27
-rw-r--r--bpkg/rep-info-options.cxx902
-rw-r--r--bpkg/rep-info-options.hxx183
-rw-r--r--bpkg/rep-info-options.ixx129
-rw-r--r--bpkg/rep-list-options.cxx701
-rw-r--r--bpkg/rep-list-options.hxx119
-rw-r--r--bpkg/rep-list-options.ixx33
-rw-r--r--bpkg/rep-remove-options.cxx704
-rw-r--r--bpkg/rep-remove-options.hxx119
-rw-r--r--bpkg/rep-remove-options.ixx33
-rw-r--r--bpkg/repository-signing.cxx205
-rw-r--r--bpkg/repository-signing.hxx31
-rw-r--r--bpkg/repository-types.cxx206
-rw-r--r--bpkg/repository-types.hxx31
-rw-r--r--bpkg/system-package-manager-fedora.cxx299
-rw-r--r--bpkg/system-package-manager-fedora.hxx8
-rw-r--r--bpkg/system-package-manager-fedora.test.testscript194
-rw-r--r--buildfile2
-rw-r--r--doc/manual.cli15
-rw-r--r--repositories.manifest11
108 files changed, 66508 insertions, 173 deletions
diff --git a/bpkg/argument-grouping.cxx b/bpkg/argument-grouping.cxx
new file mode 100644
index 0000000..998b7ea
--- /dev/null
+++ b/bpkg/argument-grouping.cxx
@@ -0,0 +1,84 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/argument-grouping.hxx>
+
+#include <map>
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_argument_grouping_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg\033[0m \033[1m{\033[0m \033[4moptions\033[0m \033[1m}+\033[0m \033[4margument\033[0m \033[1m+{\033[0m \033[4moptions\033[0m \033[1m}\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "For certain commands certain options and command line variables can be grouped" << ::std::endl
+ << "to only apply to specific arguments. This help topic describes the argument" << ::std::endl
+ << "grouping facility used for this purpose." << ::std::endl
+ << ::std::endl
+ << "Groups can be specified before (leading) and/or after (trailing) the argument" << ::std::endl
+ << "they apply to. A leading group starts with '\033[1m{\033[0m' and ends with '\033[1m}+\033[0m' while a" << ::std::endl
+ << "trailing group starts with '\033[1m+{\033[0m' and ends with '\033[1m}\033[0m'. For example:" << ::std::endl
+ << ::std::endl
+ << "{ --foo --bar }+ arg # 'arg' with '--foo' '--bar'" << ::std::endl
+ << "arg +{ fox=1 baz=2 } # 'arg' with 'fox=1' 'baz=2'" << ::std::endl
+ << ::std::endl
+ << "Multiple leading and/or trailing groups can be specified for the same argument." << ::std::endl
+ << "For example:" << ::std::endl
+ << ::std::endl
+ << "{ -f }+ { -b }+ arg +{ f=1 } +{ b=2 } # 'arg' with '-f' 'b' 'f=1' 'b=2'" << ::std::endl
+ << ::std::endl
+ << "The group applies to a single argument only unless multiple arguments are" << ::std::endl
+ << "themselves grouped with '\033[1m{\033[0m' and '\033[1m}\033[0m'. For example:" << ::std::endl
+ << ::std::endl
+ << "{ --foo }+ arg1 arg2 +{ --bar } # 'arg1' with '--foo'" << ::std::endl
+ << " # 'arg2' with '--bar'" << ::std::endl
+ << ::std::endl
+ << "{ --foo }+ { arg1 arg2 } +{ --bar } # 'arg1' with '--foo' '--bar'" << ::std::endl
+ << " # 'arg2' with '--foo' '--bar'" << ::std::endl
+ << ::std::endl
+ << "The group separators ('\033[1m{\033[0m', '\033[1m}+'\033[0m, etc) must be separate command line arguments." << ::std::endl
+ << "In particular, they must not be adjacent either to the arguments inside the" << ::std::endl
+ << "group nor to the argument they apply to. All such cases will be treated as" << ::std::endl
+ << "ordinary arguments. For example:" << ::std::endl
+ << ::std::endl
+ << "{--foo}+ arg # '{--foo}+' ..." << ::std::endl
+ << "arg+{ --foo } # 'arg+{' ..." << ::std::endl
+ << ::std::endl
+ << "If one of the group separators needs to be specified as an argument verbatim," << ::std::endl
+ << "then it must be escaped with '\033[1m\\\033[0m'. For example:" << ::std::endl
+ << ::std::endl
+ << "} # error: unexpected group separator" << ::std::endl
+ << "}x # '}x'" << ::std::endl
+ << "\\} # '}'" << ::std::endl
+ << "{ \\}+ }+ arg # 'arg' with '}+'" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/argument-grouping.hxx b/bpkg/argument-grouping.hxx
new file mode 100644
index 0000000..64019de
--- /dev/null
+++ b/bpkg/argument-grouping.hxx
@@ -0,0 +1,31 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_ARGUMENT_GROUPING_HXX
+#define BPKG_ARGUMENT_GROUPING_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_argument_grouping_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_ARGUMENT_GROUPING_HXX
diff --git a/bpkg/bpkg-options.cxx b/bpkg/bpkg-options.cxx
new file mode 100644
index 0000000..5604d2a
--- /dev/null
+++ b/bpkg/bpkg-options.cxx
@@ -0,0 +1,1664 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/bpkg-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // commands
+ //
+
+ commands::
+ commands ()
+ : help_ (),
+ cfg_create_ (),
+ cfg_info_ (),
+ cfg_link_ (),
+ cfg_unlink_ (),
+ rep_info_ (),
+ rep_add_ (),
+ rep_remove_ (),
+ rep_list_ (),
+ rep_fetch_ (),
+ rep_create_ (),
+ pkg_status_ (),
+ pkg_build_ (),
+ pkg_drop_ (),
+ pkg_install_ (),
+ pkg_uninstall_ (),
+ pkg_update_ (),
+ pkg_test_ (),
+ pkg_clean_ (),
+ pkg_bindist_ (),
+ pkg_verify_ (),
+ pkg_fetch_ (),
+ pkg_unpack_ (),
+ pkg_checkout_ (),
+ pkg_configure_ (),
+ pkg_disfigure_ (),
+ pkg_purge_ ()
+ {
+ }
+
+ bool commands::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool commands::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool commands::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool commands::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool commands::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void commands::
+ merge (const commands& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ if (a.help_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->help_, a.help_);
+ }
+
+ if (a.cfg_create_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->cfg_create_, a.cfg_create_);
+ }
+
+ if (a.cfg_info_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->cfg_info_, a.cfg_info_);
+ }
+
+ if (a.cfg_link_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->cfg_link_, a.cfg_link_);
+ }
+
+ if (a.cfg_unlink_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->cfg_unlink_, a.cfg_unlink_);
+ }
+
+ if (a.rep_info_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_info_, a.rep_info_);
+ }
+
+ if (a.rep_add_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_add_, a.rep_add_);
+ }
+
+ if (a.rep_remove_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_remove_, a.rep_remove_);
+ }
+
+ if (a.rep_list_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_list_, a.rep_list_);
+ }
+
+ if (a.rep_fetch_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_fetch_, a.rep_fetch_);
+ }
+
+ if (a.rep_create_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_create_, a.rep_create_);
+ }
+
+ if (a.pkg_status_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_status_, a.pkg_status_);
+ }
+
+ if (a.pkg_build_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_build_, a.pkg_build_);
+ }
+
+ if (a.pkg_drop_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_drop_, a.pkg_drop_);
+ }
+
+ if (a.pkg_install_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_install_, a.pkg_install_);
+ }
+
+ if (a.pkg_uninstall_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_uninstall_, a.pkg_uninstall_);
+ }
+
+ if (a.pkg_update_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_update_, a.pkg_update_);
+ }
+
+ if (a.pkg_test_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_test_, a.pkg_test_);
+ }
+
+ if (a.pkg_clean_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_clean_, a.pkg_clean_);
+ }
+
+ if (a.pkg_bindist_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_bindist_, a.pkg_bindist_);
+ }
+
+ if (a.pkg_verify_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_verify_, a.pkg_verify_);
+ }
+
+ if (a.pkg_fetch_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_fetch_, a.pkg_fetch_);
+ }
+
+ if (a.pkg_unpack_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_unpack_, a.pkg_unpack_);
+ }
+
+ if (a.pkg_checkout_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_checkout_, a.pkg_checkout_);
+ }
+
+ if (a.pkg_configure_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_configure_, a.pkg_configure_);
+ }
+
+ if (a.pkg_disfigure_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_disfigure_, a.pkg_disfigure_);
+ }
+
+ if (a.pkg_purge_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_purge_, a.pkg_purge_);
+ }
+ }
+
+ ::bpkg::cli::usage_para commands::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mCOMMANDS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1mhelp\033[0m [\033[4mtopic\033[0m] \033[1mbpkg-help(1)\033[0m -- show help for a command or help topic" << ::std::endl;
+
+ os << "\033[1mcfg-create\033[0m|\033[1mcreate\033[0m \033[1mbpkg-cfg-create(1)\033[0m -- create configuration" << ::std::endl;
+
+ os << "\033[1mcfg-info\033[0m \033[1mbpkg-cfg-info(1)\033[0m -- print configuration information" << ::std::endl;
+
+ os << "\033[1mcfg-link\033[0m|\033[1mlink\033[0m \033[1mbpkg-cfg-link(1)\033[0m -- link configuration" << ::std::endl;
+
+ os << "\033[1mcfg-unlink\033[0m|\033[1munlink\033[0m \033[1mbpkg-cfg-unlink(1)\033[0m -- unlink configuration" << ::std::endl;
+
+ os << "\033[1mrep-info\033[0m \033[1mbpkg-rep-info(1)\033[0m -- print repository information" << ::std::endl;
+
+ os << "\033[1mrep-add\033[0m|\033[1madd\033[0m \033[1mbpkg-rep-add(1)\033[0m -- add repository to configuration" << ::std::endl;
+
+ os << "\033[1mrep-remove\033[0m|\033[1mremove\033[0m \033[1mbpkg-rep-remove(1)\033[0m -- remove repository from" << ::std::endl
+ << " configuration" << ::std::endl;
+
+ os << "\033[1mrep-list\033[0m|\033[1mlist\033[0m \033[1mbpkg-rep-list(1)\033[0m -- list repositories in" << ::std::endl
+ << " configuration" << ::std::endl;
+
+ os << "\033[1mrep-fetch\033[0m|\033[1mfetch\033[0m \033[1mbpkg-rep-fetch(1)\033[0m -- fetch list of available packages" << ::std::endl;
+
+ os << "\033[1mrep-create\033[0m \033[1mbpkg-rep-create(1)\033[0m -- create repository" << ::std::endl;
+
+ os << "\033[1mpkg-status\033[0m|\033[1mstatus\033[0m \033[1mbpkg-pkg-status(1)\033[0m -- print package status" << ::std::endl;
+
+ os << "\033[1mpkg-build\033[0m|\033[1mbuild\033[0m \033[1mbpkg-pkg-build(1)\033[0m -- build package" << ::std::endl;
+
+ os << "\033[1mpkg-drop\033[0m|\033[1mdrop\033[0m \033[1mbpkg-pkg-drop(1)\033[0m -- drop package" << ::std::endl;
+
+ os << "\033[1mpkg-install\033[0m|\033[1minstall\033[0m \033[1mbpkg-pkg-install(1)\033[0m -- install package" << ::std::endl;
+
+ os << "\033[1mpkg-uninstall\033[0m|\033[1muninstall\033[0m \033[1mbpkg-pkg-uninstall(1)\033[0m -- uninstall package" << ::std::endl;
+
+ os << "\033[1mpkg-update\033[0m|\033[1mupdate\033[0m \033[1mbpkg-pkg-update(1)\033[0m -- update package" << ::std::endl;
+
+ os << "\033[1mpkg-test\033[0m|\033[1mtest\033[0m \033[1mbpkg-pkg-test(1)\033[0m -- test package" << ::std::endl;
+
+ os << "\033[1mpkg-clean\033[0m|\033[1mclean\033[0m \033[1mbpkg-pkg-clean(1)\033[0m -- clean package" << ::std::endl;
+
+ os << "\033[1mpkg-bindist\033[0m|\033[1mbindist\033[0m \033[1mbpkg-pkg-bindist(1)\033[0m -- generate binary distribution" << ::std::endl
+ << " package" << ::std::endl;
+
+ os << "\033[1mpkg-verify\033[0m \033[1mbpkg-pkg-verify(1)\033[0m -- verify package archive" << ::std::endl;
+
+ os << "\033[1mpkg-fetch\033[0m \033[1mbpkg-pkg-fetch(1)\033[0m -- fetch package archive" << ::std::endl;
+
+ os << "\033[1mpkg-unpack\033[0m \033[1mbpkg-pkg-unpack(1)\033[0m -- unpack package archive" << ::std::endl;
+
+ os << "\033[1mpkg-checkout\033[0m \033[1mbpkg-pkg-checkout(1)\033[0m -- check out package version" << ::std::endl;
+
+ os << "\033[1mpkg-configure\033[0m \033[1mbpkg-pkg-configure(1)\033[0m -- configure package" << ::std::endl;
+
+ os << "\033[1mpkg-disfigure\033[0m \033[1mbpkg-pkg-disfigure(1)\033[0m -- disfigure package" << ::std::endl;
+
+ os << "\033[1mpkg-purge\033[0m \033[1mbpkg-pkg-purge(1)\033[0m -- purge package" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (commands&, ::bpkg::cli::scanner&)>
+ _cli_commands_map;
+
+ static _cli_commands_map _cli_commands_map_;
+
+ struct _cli_commands_map_init
+ {
+ _cli_commands_map_init ()
+ {
+ _cli_commands_map_["help"] =
+ &::bpkg::cli::thunk< commands, &commands::help_ >;
+ _cli_commands_map_["cfg-create"] =
+ &::bpkg::cli::thunk< commands, &commands::cfg_create_ >;
+ _cli_commands_map_["create"] =
+ &::bpkg::cli::thunk< commands, &commands::cfg_create_ >;
+ _cli_commands_map_["cfg-info"] =
+ &::bpkg::cli::thunk< commands, &commands::cfg_info_ >;
+ _cli_commands_map_["cfg-link"] =
+ &::bpkg::cli::thunk< commands, &commands::cfg_link_ >;
+ _cli_commands_map_["link"] =
+ &::bpkg::cli::thunk< commands, &commands::cfg_link_ >;
+ _cli_commands_map_["cfg-unlink"] =
+ &::bpkg::cli::thunk< commands, &commands::cfg_unlink_ >;
+ _cli_commands_map_["unlink"] =
+ &::bpkg::cli::thunk< commands, &commands::cfg_unlink_ >;
+ _cli_commands_map_["rep-info"] =
+ &::bpkg::cli::thunk< commands, &commands::rep_info_ >;
+ _cli_commands_map_["rep-add"] =
+ &::bpkg::cli::thunk< commands, &commands::rep_add_ >;
+ _cli_commands_map_["add"] =
+ &::bpkg::cli::thunk< commands, &commands::rep_add_ >;
+ _cli_commands_map_["rep-remove"] =
+ &::bpkg::cli::thunk< commands, &commands::rep_remove_ >;
+ _cli_commands_map_["remove"] =
+ &::bpkg::cli::thunk< commands, &commands::rep_remove_ >;
+ _cli_commands_map_["rep-list"] =
+ &::bpkg::cli::thunk< commands, &commands::rep_list_ >;
+ _cli_commands_map_["list"] =
+ &::bpkg::cli::thunk< commands, &commands::rep_list_ >;
+ _cli_commands_map_["rep-fetch"] =
+ &::bpkg::cli::thunk< commands, &commands::rep_fetch_ >;
+ _cli_commands_map_["fetch"] =
+ &::bpkg::cli::thunk< commands, &commands::rep_fetch_ >;
+ _cli_commands_map_["rep-create"] =
+ &::bpkg::cli::thunk< commands, &commands::rep_create_ >;
+ _cli_commands_map_["pkg-status"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_status_ >;
+ _cli_commands_map_["status"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_status_ >;
+ _cli_commands_map_["pkg-build"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_build_ >;
+ _cli_commands_map_["build"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_build_ >;
+ _cli_commands_map_["pkg-drop"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_drop_ >;
+ _cli_commands_map_["drop"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_drop_ >;
+ _cli_commands_map_["pkg-install"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_install_ >;
+ _cli_commands_map_["install"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_install_ >;
+ _cli_commands_map_["pkg-uninstall"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_uninstall_ >;
+ _cli_commands_map_["uninstall"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_uninstall_ >;
+ _cli_commands_map_["pkg-update"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_update_ >;
+ _cli_commands_map_["update"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_update_ >;
+ _cli_commands_map_["pkg-test"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_test_ >;
+ _cli_commands_map_["test"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_test_ >;
+ _cli_commands_map_["pkg-clean"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_clean_ >;
+ _cli_commands_map_["clean"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_clean_ >;
+ _cli_commands_map_["pkg-bindist"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_bindist_ >;
+ _cli_commands_map_["bindist"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_bindist_ >;
+ _cli_commands_map_["pkg-verify"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_verify_ >;
+ _cli_commands_map_["pkg-fetch"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_fetch_ >;
+ _cli_commands_map_["pkg-unpack"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_unpack_ >;
+ _cli_commands_map_["pkg-checkout"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_checkout_ >;
+ _cli_commands_map_["pkg-configure"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_configure_ >;
+ _cli_commands_map_["pkg-disfigure"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_disfigure_ >;
+ _cli_commands_map_["pkg-purge"] =
+ &::bpkg::cli::thunk< commands, &commands::pkg_purge_ >;
+ }
+ };
+
+ static _cli_commands_map_init _cli_commands_map_init_;
+
+ bool commands::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_commands_map::const_iterator i (_cli_commands_map_.find (o));
+
+ if (i != _cli_commands_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool commands::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+
+ // topics
+ //
+
+ topics::
+ topics ()
+ : common_options_ (),
+ default_options_files_ (),
+ repository_types_ (),
+ repository_signing_ (),
+ argument_grouping_ ()
+ {
+ }
+
+ bool topics::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool topics::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool topics::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool topics::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool topics::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void topics::
+ merge (const topics& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ if (a.common_options_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->common_options_, a.common_options_);
+ }
+
+ if (a.default_options_files_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->default_options_files_, a.default_options_files_);
+ }
+
+ if (a.repository_types_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->repository_types_, a.repository_types_);
+ }
+
+ if (a.repository_signing_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->repository_signing_, a.repository_signing_);
+ }
+
+ if (a.argument_grouping_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->argument_grouping_, a.argument_grouping_);
+ }
+ }
+
+ ::bpkg::cli::usage_para topics::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mHELP TOPICS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1mcommon-options\033[0m \033[1mbpkg-common-options(1)\033[0m -- details on common options" << ::std::endl;
+
+ os << "\033[1mdefault-options-files\033[0m \033[1mbpkg-default-options-files(1)\033[0m -- specifying default" << ::std::endl
+ << " options" << ::std::endl;
+
+ os << "\033[1mrepository-types\033[0m \033[1mbpkg-repository-types(1)\033[0m -- repository types," << ::std::endl
+ << " structure, and URLs" << ::std::endl;
+
+ os << "\033[1mrepository-signing\033[0m \033[1mbpkg-repository-signing(1)\033[0m -- how to sign repository" << ::std::endl;
+
+ os << "\033[1margument-grouping\033[0m \033[1mbpkg-argument-grouping(1)\033[0m -- argument grouping" << ::std::endl
+ << " facility" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (topics&, ::bpkg::cli::scanner&)>
+ _cli_topics_map;
+
+ static _cli_topics_map _cli_topics_map_;
+
+ struct _cli_topics_map_init
+ {
+ _cli_topics_map_init ()
+ {
+ _cli_topics_map_["common-options"] =
+ &::bpkg::cli::thunk< topics, &topics::common_options_ >;
+ _cli_topics_map_["default-options-files"] =
+ &::bpkg::cli::thunk< topics, &topics::default_options_files_ >;
+ _cli_topics_map_["repository-types"] =
+ &::bpkg::cli::thunk< topics, &topics::repository_types_ >;
+ _cli_topics_map_["repository-signing"] =
+ &::bpkg::cli::thunk< topics, &topics::repository_signing_ >;
+ _cli_topics_map_["argument-grouping"] =
+ &::bpkg::cli::thunk< topics, &topics::argument_grouping_ >;
+ }
+ };
+
+ static _cli_topics_map_init _cli_topics_map_init_;
+
+ bool topics::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_topics_map::const_iterator i (_cli_topics_map_.find (o));
+
+ if (i != _cli_topics_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool topics::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+
+ // options
+ //
+
+ options::
+ options ()
+ : help_ (),
+ version_ ()
+ {
+ }
+
+ bool options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void options::
+ merge (const options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+
+ if (a.help_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->help_, a.help_);
+ }
+
+ if (a.version_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->version_, a.version_);
+ }
+ }
+
+ ::bpkg::cli::usage_para options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (options&, ::bpkg::cli::scanner&)>
+ _cli_options_map;
+
+ static _cli_options_map _cli_options_map_;
+
+ struct _cli_options_map_init
+ {
+ _cli_options_map_init ()
+ {
+ _cli_options_map_["--help"] =
+ &::bpkg::cli::thunk< options, &options::help_ >;
+ _cli_options_map_["--version"] =
+ &::bpkg::cli::thunk< options, &options::version_ >;
+ }
+ };
+
+ static _cli_options_map_init _cli_options_map_init_;
+
+ bool options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_options_map::const_iterator i (_cli_options_map_.find (o));
+
+ if (i != _cli_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg --help\033[0m" << ::std::endl
+ << "\033[1mbpkg --version\033[0m" << ::std::endl
+ << "\033[1mbpkg help\033[0m [\033[4mcommand\033[0m | \033[4mtopic\033[0m]" << ::std::endl
+ << "\033[1mbpkg\033[0m [\033[4mcommon-options\033[0m] \033[4mcommand\033[0m [\033[4mcommand-options\033[0m] \033[4mcommand-args\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mbuild2\033[0m package dependency manager is used to manipulate build" << ::std::endl
+ << "configurations, packages, and repositories using a set of commands that are" << ::std::endl
+ << "summarized below." << ::std::endl
+ << ::std::endl
+ << "For a detailed description of any command or help topic, use the \033[1mhelp\033[0m command" << ::std::endl
+ << "or see the corresponding man page (the man pages have the \033[1mbpkg-\033[0m prefix, for" << ::std::endl
+ << "example \033[1mbpkg-help(1)\033[0m). Note also that \033[4mcommand-options\033[0m and \033[4mcommand-args\033[0m can be" << ::std::endl
+ << "specified in any order and \033[4mcommon-options\033[0m can be specified as part of" << ::std::endl
+ << "\033[4mcommand-options\033[0m." << ::std::endl;
+
+ p = ::bpkg::commands::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ p = ::bpkg::topics::print_usage (os, p);
+
+ p = ::bpkg::options::print_usage (os, p);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mENVIRONMENT\033[0m" << ::std::endl
+ << ::std::endl
+ << "Commands executed by \033[1mbpkg\033[0m while the current and linked build configuration" << ::std::endl
+ << "databases are open will have the \033[1mBPKG_OPEN_CONFIGS\033[0m environment variable set to" << ::std::endl
+ << "the space-separated, \033[1m\"\033[0m-quoted list of absolute and normalized configuration" << ::std::endl
+ << "directory paths. This can be used by build system hooks and/or programs that" << ::std::endl
+ << "they execute." << ::std::endl;
+
+ os << std::endl
+ << "\033[1mEXIT STATUS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1m0\033[0m" << ::std::endl
+ << " Success." << ::std::endl
+ << "\033[1m1\033[0m" << ::std::endl
+ << " Fatal error." << ::std::endl
+ << "\033[1m2\033[0m" << ::std::endl
+ << " Recoverable error which is likely to disappear if the command is" << ::std::endl
+ << " re-executed." << ::std::endl
+ << ::std::endl
+ << "\033[1mENVIRONMENT\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mBPKG_DEF_OPT\033[0m environment variable is used to suppress loading of default" << ::std::endl
+ << "options files in nested \033[1mbpkg\033[0m invocations. Its values are \033[1mfalse\033[0m or \033[1m0\033[0m to suppress" << ::std::endl
+ << "and \033[1mtrue\033[0m or \033[1m1\033[0m to load." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/bpkg-options.hxx b/bpkg/bpkg-options.hxx
new file mode 100644
index 0000000..9dda684
--- /dev/null
+++ b/bpkg/bpkg-options.hxx
@@ -0,0 +1,391 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_BPKG_OPTIONS_HXX
+#define BPKG_BPKG_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class commands
+ {
+ public:
+ commands ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const commands&);
+
+ // Option accessors.
+ //
+ const bool&
+ help () const;
+
+ const bool&
+ cfg_create () const;
+
+ const bool&
+ cfg_info () const;
+
+ const bool&
+ cfg_link () const;
+
+ const bool&
+ cfg_unlink () const;
+
+ const bool&
+ rep_info () const;
+
+ const bool&
+ rep_add () const;
+
+ const bool&
+ rep_remove () const;
+
+ const bool&
+ rep_list () const;
+
+ const bool&
+ rep_fetch () const;
+
+ const bool&
+ rep_create () const;
+
+ const bool&
+ pkg_status () const;
+
+ const bool&
+ pkg_build () const;
+
+ const bool&
+ pkg_drop () const;
+
+ const bool&
+ pkg_install () const;
+
+ const bool&
+ pkg_uninstall () const;
+
+ const bool&
+ pkg_update () const;
+
+ const bool&
+ pkg_test () const;
+
+ const bool&
+ pkg_clean () const;
+
+ const bool&
+ pkg_bindist () const;
+
+ const bool&
+ pkg_verify () const;
+
+ const bool&
+ pkg_fetch () const;
+
+ const bool&
+ pkg_unpack () const;
+
+ const bool&
+ pkg_checkout () const;
+
+ const bool&
+ pkg_configure () const;
+
+ const bool&
+ pkg_disfigure () const;
+
+ const bool&
+ pkg_purge () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool help_;
+ bool cfg_create_;
+ bool cfg_info_;
+ bool cfg_link_;
+ bool cfg_unlink_;
+ bool rep_info_;
+ bool rep_add_;
+ bool rep_remove_;
+ bool rep_list_;
+ bool rep_fetch_;
+ bool rep_create_;
+ bool pkg_status_;
+ bool pkg_build_;
+ bool pkg_drop_;
+ bool pkg_install_;
+ bool pkg_uninstall_;
+ bool pkg_update_;
+ bool pkg_test_;
+ bool pkg_clean_;
+ bool pkg_bindist_;
+ bool pkg_verify_;
+ bool pkg_fetch_;
+ bool pkg_unpack_;
+ bool pkg_checkout_;
+ bool pkg_configure_;
+ bool pkg_disfigure_;
+ bool pkg_purge_;
+ };
+
+ class topics
+ {
+ public:
+ topics ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const topics&);
+
+ // Option accessors.
+ //
+ const bool&
+ common_options () const;
+
+ const bool&
+ default_options_files () const;
+
+ const bool&
+ repository_types () const;
+
+ const bool&
+ repository_signing () const;
+
+ const bool&
+ argument_grouping () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool common_options_;
+ bool default_options_files_;
+ bool repository_types_;
+ bool repository_signing_;
+ bool argument_grouping_;
+ };
+
+ class options: public ::bpkg::common_options
+ {
+ public:
+ options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const options&);
+
+ // Option accessors.
+ //
+ const bool&
+ help () const;
+
+ const bool&
+ version () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool help_;
+ bool version_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/bpkg-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_BPKG_OPTIONS_HXX
diff --git a/bpkg/bpkg-options.ixx b/bpkg/bpkg-options.ixx
new file mode 100644
index 0000000..fe5b6d4
--- /dev/null
+++ b/bpkg/bpkg-options.ixx
@@ -0,0 +1,231 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // commands
+ //
+
+ inline const bool& commands::
+ help () const
+ {
+ return this->help_;
+ }
+
+ inline const bool& commands::
+ cfg_create () const
+ {
+ return this->cfg_create_;
+ }
+
+ inline const bool& commands::
+ cfg_info () const
+ {
+ return this->cfg_info_;
+ }
+
+ inline const bool& commands::
+ cfg_link () const
+ {
+ return this->cfg_link_;
+ }
+
+ inline const bool& commands::
+ cfg_unlink () const
+ {
+ return this->cfg_unlink_;
+ }
+
+ inline const bool& commands::
+ rep_info () const
+ {
+ return this->rep_info_;
+ }
+
+ inline const bool& commands::
+ rep_add () const
+ {
+ return this->rep_add_;
+ }
+
+ inline const bool& commands::
+ rep_remove () const
+ {
+ return this->rep_remove_;
+ }
+
+ inline const bool& commands::
+ rep_list () const
+ {
+ return this->rep_list_;
+ }
+
+ inline const bool& commands::
+ rep_fetch () const
+ {
+ return this->rep_fetch_;
+ }
+
+ inline const bool& commands::
+ rep_create () const
+ {
+ return this->rep_create_;
+ }
+
+ inline const bool& commands::
+ pkg_status () const
+ {
+ return this->pkg_status_;
+ }
+
+ inline const bool& commands::
+ pkg_build () const
+ {
+ return this->pkg_build_;
+ }
+
+ inline const bool& commands::
+ pkg_drop () const
+ {
+ return this->pkg_drop_;
+ }
+
+ inline const bool& commands::
+ pkg_install () const
+ {
+ return this->pkg_install_;
+ }
+
+ inline const bool& commands::
+ pkg_uninstall () const
+ {
+ return this->pkg_uninstall_;
+ }
+
+ inline const bool& commands::
+ pkg_update () const
+ {
+ return this->pkg_update_;
+ }
+
+ inline const bool& commands::
+ pkg_test () const
+ {
+ return this->pkg_test_;
+ }
+
+ inline const bool& commands::
+ pkg_clean () const
+ {
+ return this->pkg_clean_;
+ }
+
+ inline const bool& commands::
+ pkg_bindist () const
+ {
+ return this->pkg_bindist_;
+ }
+
+ inline const bool& commands::
+ pkg_verify () const
+ {
+ return this->pkg_verify_;
+ }
+
+ inline const bool& commands::
+ pkg_fetch () const
+ {
+ return this->pkg_fetch_;
+ }
+
+ inline const bool& commands::
+ pkg_unpack () const
+ {
+ return this->pkg_unpack_;
+ }
+
+ inline const bool& commands::
+ pkg_checkout () const
+ {
+ return this->pkg_checkout_;
+ }
+
+ inline const bool& commands::
+ pkg_configure () const
+ {
+ return this->pkg_configure_;
+ }
+
+ inline const bool& commands::
+ pkg_disfigure () const
+ {
+ return this->pkg_disfigure_;
+ }
+
+ inline const bool& commands::
+ pkg_purge () const
+ {
+ return this->pkg_purge_;
+ }
+
+ // topics
+ //
+
+ inline const bool& topics::
+ common_options () const
+ {
+ return this->common_options_;
+ }
+
+ inline const bool& topics::
+ default_options_files () const
+ {
+ return this->default_options_files_;
+ }
+
+ inline const bool& topics::
+ repository_types () const
+ {
+ return this->repository_types_;
+ }
+
+ inline const bool& topics::
+ repository_signing () const
+ {
+ return this->repository_signing_;
+ }
+
+ inline const bool& topics::
+ argument_grouping () const
+ {
+ return this->argument_grouping_;
+ }
+
+ // options
+ //
+
+ inline const bool& options::
+ help () const
+ {
+ return this->help_;
+ }
+
+ inline const bool& options::
+ version () const
+ {
+ return this->version_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/cfg-create-options.cxx b/bpkg/cfg-create-options.cxx
new file mode 100644
index 0000000..27979a1
--- /dev/null
+++ b/bpkg/cfg-create-options.cxx
@@ -0,0 +1,883 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/cfg-create-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // cfg_create_options
+ //
+
+ cfg_create_options::
+ cfg_create_options ()
+ : directory_ ("."),
+ directory_specified_ (false),
+ existing_ (),
+ wipe_ (),
+ host_config_ (),
+ host_config_specified_ (false),
+ no_host_config_ (),
+ build2_config_ (),
+ build2_config_specified_ (false),
+ no_build2_config_ (),
+ name_ (),
+ name_specified_ (false),
+ type_ ("target"),
+ type_specified_ (false),
+ uuid_ (),
+ uuid_specified_ (false)
+ {
+ }
+
+ bool cfg_create_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool cfg_create_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool cfg_create_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool cfg_create_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool cfg_create_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void cfg_create_options::
+ merge (const cfg_create_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+
+ if (a.directory_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->directory_, a.directory_);
+ this->directory_specified_ = true;
+ }
+
+ if (a.existing_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->existing_, a.existing_);
+ }
+
+ if (a.wipe_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->wipe_, a.wipe_);
+ }
+
+ if (a.host_config_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->host_config_, a.host_config_);
+ this->host_config_specified_ = true;
+ }
+
+ if (a.no_host_config_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_host_config_, a.no_host_config_);
+ }
+
+ if (a.build2_config_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->build2_config_, a.build2_config_);
+ this->build2_config_specified_ = true;
+ }
+
+ if (a.no_build2_config_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_build2_config_, a.no_build2_config_);
+ }
+
+ if (a.name_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->name_, a.name_);
+ this->name_specified_ = true;
+ }
+
+ if (a.type_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->type_, a.type_);
+ this->type_specified_ = true;
+ }
+
+ if (a.uuid_specified_)
+ {
+ ::bpkg::cli::parser< uuid_type>::merge (
+ this->uuid_, a.uuid_);
+ this->uuid_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para cfg_create_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mCFG-CREATE OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--directory\033[0m|\033[1m-d\033[0m \033[4mdir\033[0m Create the configuration in \033[4mdir\033[0m rather than in the" << ::std::endl
+ << " current working directory." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--existing\033[0m|\033[1m-e\033[0m Initialize a \033[1mbpkg\033[0m configuration based on an existing" << ::std::endl
+ << " build system configuration." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--wipe\033[0m Wipe the configuration directory clean before" << ::std::endl
+ << " creating the new configuration. For safety, this" << ::std::endl
+ << " option requires that you specify the configuration" << ::std::endl
+ << " directory explicitly with \033[1m--directory|-d\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--host-config\033[0m \033[4mdir\033[0m Link the specified host configuration with the" << ::std::endl
+ << " configuration being created as if by running the" << ::std::endl
+ << " \033[1mbpkg-cfg-link(1)\033[0m command." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-host-config\033[0m Ignore any specified \033[1m--host-config\033[0m options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--build2-config\033[0m \033[4mdir\033[0m Link the specified build system module configuration" << ::std::endl
+ << " with the configuration being created as if by running" << ::std::endl
+ << " the \033[1mbpkg-cfg-link(1)\033[0m command." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-build2-config\033[0m Ignore any specified \033[1m--build2-config\033[0m options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--name\033[0m \033[4mname\033[0m The name of the configuration being created. If this" << ::std::endl
+ << " configuration is linked with another configuration" << ::std::endl
+ << " using \033[1mbpkg-cfg-link(1)\033[0m, this name will be used as the" << ::std::endl
+ << " link name unless overridden. By default the" << ::std::endl
+ << " configuration is created unnamed." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--type\033[0m \033[4mtype\033[0m The type of the configuration being created. By" << ::std::endl
+ << " default, configuration of type \033[1mtarget\033[0m is created." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--uuid\033[0m \033[4muuid\033[0m Use the specified UUID as the configuration id" << ::std::endl
+ << " instead of generating one automatically." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (cfg_create_options&, ::bpkg::cli::scanner&)>
+ _cli_cfg_create_options_map;
+
+ static _cli_cfg_create_options_map _cli_cfg_create_options_map_;
+
+ struct _cli_cfg_create_options_map_init
+ {
+ _cli_cfg_create_options_map_init ()
+ {
+ _cli_cfg_create_options_map_["--directory"] =
+ &::bpkg::cli::thunk< cfg_create_options, dir_path, &cfg_create_options::directory_,
+ &cfg_create_options::directory_specified_ >;
+ _cli_cfg_create_options_map_["-d"] =
+ &::bpkg::cli::thunk< cfg_create_options, dir_path, &cfg_create_options::directory_,
+ &cfg_create_options::directory_specified_ >;
+ _cli_cfg_create_options_map_["--existing"] =
+ &::bpkg::cli::thunk< cfg_create_options, &cfg_create_options::existing_ >;
+ _cli_cfg_create_options_map_["-e"] =
+ &::bpkg::cli::thunk< cfg_create_options, &cfg_create_options::existing_ >;
+ _cli_cfg_create_options_map_["--wipe"] =
+ &::bpkg::cli::thunk< cfg_create_options, &cfg_create_options::wipe_ >;
+ _cli_cfg_create_options_map_["--host-config"] =
+ &::bpkg::cli::thunk< cfg_create_options, dir_path, &cfg_create_options::host_config_,
+ &cfg_create_options::host_config_specified_ >;
+ _cli_cfg_create_options_map_["--no-host-config"] =
+ &::bpkg::cli::thunk< cfg_create_options, &cfg_create_options::no_host_config_ >;
+ _cli_cfg_create_options_map_["--build2-config"] =
+ &::bpkg::cli::thunk< cfg_create_options, dir_path, &cfg_create_options::build2_config_,
+ &cfg_create_options::build2_config_specified_ >;
+ _cli_cfg_create_options_map_["--no-build2-config"] =
+ &::bpkg::cli::thunk< cfg_create_options, &cfg_create_options::no_build2_config_ >;
+ _cli_cfg_create_options_map_["--name"] =
+ &::bpkg::cli::thunk< cfg_create_options, string, &cfg_create_options::name_,
+ &cfg_create_options::name_specified_ >;
+ _cli_cfg_create_options_map_["--type"] =
+ &::bpkg::cli::thunk< cfg_create_options, string, &cfg_create_options::type_,
+ &cfg_create_options::type_specified_ >;
+ _cli_cfg_create_options_map_["--uuid"] =
+ &::bpkg::cli::thunk< cfg_create_options, uuid_type, &cfg_create_options::uuid_,
+ &cfg_create_options::uuid_specified_ >;
+ }
+ };
+
+ static _cli_cfg_create_options_map_init _cli_cfg_create_options_map_init_;
+
+ bool cfg_create_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_cfg_create_options_map::const_iterator i (_cli_cfg_create_options_map_.find (o));
+
+ if (i != _cli_cfg_create_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool cfg_create_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_cfg_create_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg cfg-create\033[0m|\033[1mcreate\033[0m [\033[4moptions\033[0m] [\033[4mcfg-args\033[0m]" << ::std::endl
+ << "\033[1mbpkg cfg-create\033[0m|\033[1mcreate\033[0m [\033[4moptions\033[0m] \033[1m--existing|-e\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[4mcfg-args\033[0m = (\033[4mmodule\033[0m | \033[4mcfg-var\033[0m)...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mcfg-create\033[0m command creates a new \033[1mbpkg\033[0m configuration with the specified" << ::std::endl
+ << "\033[1mbuild2\033[0m modules and configuration variables (the first form) or initializes one" << ::std::endl
+ << "based on an existing build system configuration (the second form). The \033[1mbpkg\033[0m" << ::std::endl
+ << "configuration itself is a build system configuration; see build system driver" << ::std::endl
+ << "(\033[1mb(1)\033[0m) \033[1mcreate\033[0m meta-operation for details." << ::std::endl
+ << ::std::endl
+ << "Unless the \033[1m--existing|-e\033[0m or \033[1m--wipe\033[0m option is specified, \033[1mcfg-create\033[0m expects the" << ::std::endl
+ << "configuration directory to be empty or to not exist (in which case it will be" << ::std::endl
+ << "created)." << ::std::endl
+ << ::std::endl
+ << "By default, the configuration created with the first form loads the \033[1mconfig\033[0m," << ::std::endl
+ << "\033[1mtest\033[0m, \033[1mdist\033[0m, and \033[1minstall\033[0m modules. However, additional modules and, if required," << ::std::endl
+ << "their configuration variables can be specified as the \033[1mcfg-create\033[0m arguments. For" << ::std::endl
+ << "example:" << ::std::endl
+ << ::std::endl
+ << "bpkg create cxx config.cxx=clang++ config.install.root=/usr/local" << ::std::endl
+ << ::std::endl
+ << "By default, \033[1mbpkg\033[0m appends \033[1m.config\033[0m to the names of the modules that you specify" << ::std::endl
+ << "so that only their configurations are loaded. You can override this behavior by" << ::std::endl
+ << "specifying the period (\033[1m.\033[0m) after the module name. You can also instruct \033[1mbpkg\033[0m to" << ::std::endl
+ << "use the optional module load by prefixing the module name with the question" << ::std::endl
+ << "mark (\033[1m?\033[0m). For example:" << ::std::endl
+ << ::std::endl
+ << "bpkg create cxx. \"?cli\"" << ::std::endl
+ << ::std::endl
+ << "Configurations can be linked with each other to allow a package to be built in" << ::std::endl
+ << "one configuration while its dependencies in one or more linked configurations." << ::std::endl
+ << "This can be used to create a \"base\" configuration with common dependencies that" << ::std::endl
+ << "are shared between multiple configurations. This mechanism is also used to" << ::std::endl
+ << "provide a host configuration that is used to build build-time dependencies." << ::std::endl
+ << ::std::endl
+ << "Each configuration is assigned an automatically-generated UUID unless one is" << ::std::endl
+ << "specified with the \033[1m--uuid\033[0m option. This UUID is used to check the integrity of" << ::std::endl
+ << "configuration links. For convenience of referring to linked configurations, a" << ::std::endl
+ << "configuration can also be assigned a name with the \033[1m--name\033[0m option." << ::std::endl
+ << ::std::endl
+ << "A configuration also has a type specified with the \033[1m--type\033[0m option. Three" << ::std::endl
+ << "predefined types are \033[1mtarget\033[0m, \033[1mhost\033[0m, and \033[1mbuild2\033[0m. If the type is not specified" << ::std::endl
+ << "explicitly, then \033[1mtarget\033[0m is assumed. When satisfying a dependency of one package" << ::std::endl
+ << "on another, a linked configuration will only be considered if (1) it has the" << ::std::endl
+ << "same type as the other configuration for run-time dependencies, (2) it has the" << ::std::endl
+ << "\033[1mhost\033[0m type for regular build-time dependencies, and (3) it has the \033[1mbuild2\033[0m type" << ::std::endl
+ << "for build system module build-time dependencies. Note that a host configuration" << ::std::endl
+ << "is a target configuration for the host machine. So to create a self-hosted" << ::std::endl
+ << "configuration, use type \033[1mhost\033[0m." << ::std::endl
+ << ::std::endl
+ << "To link a configuration we use the \033[1mbpkg-cfg-link(1)\033[0m command. As a shortcut," << ::std::endl
+ << "host and build system module configurations can also be linked during the" << ::std::endl
+ << "configuration creation with the \033[1m--host-config\033[0m and \033[1m--build2-config\033[0m options," << ::std::endl
+ << "respectively. If a build-time dependency is encountered in a configuration that" << ::std::endl
+ << "has no linked configuration of a suitable type (\033[1mhost\033[0m or \033[1mbuild2\033[0m, nor is itself" << ::std::endl
+ << "of a suitable type), then a private host or build system module configuration" << ::std::endl
+ << "named \033[1mhost\033[0m or \033[1mbuild2\033[0m, respectively, is created automatically inside the" << ::std::endl
+ << "configuration's .bpkg/\033[0m subdirectory." << ::std::endl;
+
+ p = ::bpkg::cfg_create_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mcfg-create\033[0m command the search start directory is the parent directory" << ::std::endl
+ << "of the new configuration. The following options files are searched for in each" << ::std::endl
+ << "directory and, if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-cfg-create.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mcfg-create\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl
+ << "--wipe" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/cfg-create-options.hxx b/bpkg/cfg-create-options.hxx
new file mode 100644
index 0000000..f47594d
--- /dev/null
+++ b/bpkg/cfg-create-options.hxx
@@ -0,0 +1,173 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_CFG_CREATE_OPTIONS_HXX
+#define BPKG_CFG_CREATE_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class cfg_create_options: public ::bpkg::common_options
+ {
+ public:
+ cfg_create_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const cfg_create_options&);
+
+ // Option accessors.
+ //
+ const dir_path&
+ directory () const;
+
+ bool
+ directory_specified () const;
+
+ const bool&
+ existing () const;
+
+ const bool&
+ wipe () const;
+
+ const dir_path&
+ host_config () const;
+
+ bool
+ host_config_specified () const;
+
+ const bool&
+ no_host_config () const;
+
+ const dir_path&
+ build2_config () const;
+
+ bool
+ build2_config_specified () const;
+
+ const bool&
+ no_build2_config () const;
+
+ const string&
+ name () const;
+
+ bool
+ name_specified () const;
+
+ const string&
+ type () const;
+
+ bool
+ type_specified () const;
+
+ const uuid_type&
+ uuid () const;
+
+ bool
+ uuid_specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ dir_path directory_;
+ bool directory_specified_;
+ bool existing_;
+ bool wipe_;
+ dir_path host_config_;
+ bool host_config_specified_;
+ bool no_host_config_;
+ dir_path build2_config_;
+ bool build2_config_specified_;
+ bool no_build2_config_;
+ string name_;
+ bool name_specified_;
+ string type_;
+ bool type_specified_;
+ uuid_type uuid_;
+ bool uuid_specified_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_cfg_create_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/cfg-create-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_CFG_CREATE_OPTIONS_HXX
diff --git a/bpkg/cfg-create-options.ixx b/bpkg/cfg-create-options.ixx
new file mode 100644
index 0000000..9e8b1f6
--- /dev/null
+++ b/bpkg/cfg-create-options.ixx
@@ -0,0 +1,117 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // cfg_create_options
+ //
+
+ inline const dir_path& cfg_create_options::
+ directory () const
+ {
+ return this->directory_;
+ }
+
+ inline bool cfg_create_options::
+ directory_specified () const
+ {
+ return this->directory_specified_;
+ }
+
+ inline const bool& cfg_create_options::
+ existing () const
+ {
+ return this->existing_;
+ }
+
+ inline const bool& cfg_create_options::
+ wipe () const
+ {
+ return this->wipe_;
+ }
+
+ inline const dir_path& cfg_create_options::
+ host_config () const
+ {
+ return this->host_config_;
+ }
+
+ inline bool cfg_create_options::
+ host_config_specified () const
+ {
+ return this->host_config_specified_;
+ }
+
+ inline const bool& cfg_create_options::
+ no_host_config () const
+ {
+ return this->no_host_config_;
+ }
+
+ inline const dir_path& cfg_create_options::
+ build2_config () const
+ {
+ return this->build2_config_;
+ }
+
+ inline bool cfg_create_options::
+ build2_config_specified () const
+ {
+ return this->build2_config_specified_;
+ }
+
+ inline const bool& cfg_create_options::
+ no_build2_config () const
+ {
+ return this->no_build2_config_;
+ }
+
+ inline const string& cfg_create_options::
+ name () const
+ {
+ return this->name_;
+ }
+
+ inline bool cfg_create_options::
+ name_specified () const
+ {
+ return this->name_specified_;
+ }
+
+ inline const string& cfg_create_options::
+ type () const
+ {
+ return this->type_;
+ }
+
+ inline bool cfg_create_options::
+ type_specified () const
+ {
+ return this->type_specified_;
+ }
+
+ inline const uuid_type& cfg_create_options::
+ uuid () const
+ {
+ return this->uuid_;
+ }
+
+ inline bool cfg_create_options::
+ uuid_specified () const
+ {
+ return this->uuid_specified_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/cfg-info-options.cxx b/bpkg/cfg-info-options.cxx
new file mode 100644
index 0000000..51758f4
--- /dev/null
+++ b/bpkg/cfg-info-options.cxx
@@ -0,0 +1,745 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/cfg-info-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // cfg_info_options
+ //
+
+ cfg_info_options::
+ cfg_info_options ()
+ : link_ (),
+ backlink_ (),
+ dangling_ (),
+ recursive_ ()
+ {
+ }
+
+ bool cfg_info_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool cfg_info_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool cfg_info_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool cfg_info_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool cfg_info_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void cfg_info_options::
+ merge (const cfg_info_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.link_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->link_, a.link_);
+ }
+
+ if (a.backlink_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->backlink_, a.backlink_);
+ }
+
+ if (a.dangling_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->dangling_, a.dangling_);
+ }
+
+ if (a.recursive_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->recursive_, a.recursive_);
+ }
+ }
+
+ ::bpkg::cli::usage_para cfg_info_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mCFG-INFO OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--link\033[0m Print linked configurations." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--backlink\033[0m Print implicitly backlinked configurations." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--dangling\033[0m Print dangling implicit backlinks." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--recursive\033[0m Print linked configurations recursively." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (cfg_info_options&, ::bpkg::cli::scanner&)>
+ _cli_cfg_info_options_map;
+
+ static _cli_cfg_info_options_map _cli_cfg_info_options_map_;
+
+ struct _cli_cfg_info_options_map_init
+ {
+ _cli_cfg_info_options_map_init ()
+ {
+ _cli_cfg_info_options_map_["--link"] =
+ &::bpkg::cli::thunk< cfg_info_options, &cfg_info_options::link_ >;
+ _cli_cfg_info_options_map_["--backlink"] =
+ &::bpkg::cli::thunk< cfg_info_options, &cfg_info_options::backlink_ >;
+ _cli_cfg_info_options_map_["--dangling"] =
+ &::bpkg::cli::thunk< cfg_info_options, &cfg_info_options::dangling_ >;
+ _cli_cfg_info_options_map_["--recursive"] =
+ &::bpkg::cli::thunk< cfg_info_options, &cfg_info_options::recursive_ >;
+ }
+ };
+
+ static _cli_cfg_info_options_map_init _cli_cfg_info_options_map_init_;
+
+ bool cfg_info_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_cfg_info_options_map::const_iterator i (_cli_cfg_info_options_map_.find (o));
+
+ if (i != _cli_cfg_info_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool cfg_info_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_cfg_info_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg cfg-info\033[0m [\033[4moptions\033[0m]\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mcfg-info\033[0m command prints the current configuration's absolute path, id," << ::std::endl
+ << "type, and name. If the \033[1m--link\033[0m and/or \033[1m--backlink\033[0m options are specified, then" << ::std::endl
+ << "this information is also printed for each linked and/or implicitly backlinked" << ::std::endl
+ << "configuration, if any. Note that the dangling implicit backlinks are silently" << ::std::endl
+ << "skipped, unless \033[1m--dangling\033[0m is specified, in which case this information is also" << ::std::endl
+ << "printed for them. Note that the information is written to \033[1mstdout\033[0m, not \033[1mstderr\033[0m." << ::std::endl
+ << ::std::endl
+ << "If the \033[1m--recursive\033[0m option is specified together with \033[1m--link\033[0m and/or \033[1m--backlink\033[0m," << ::std::endl
+ << "then this information is printed for linked and/or implicitly backlinked" << ::std::endl
+ << "configuration, recursively." << ::std::endl
+ << ::std::endl
+ << "The output format is regular with each value printed on a separate line and" << ::std::endl
+ << "prefixed with the value name. If the \033[1m--link\033[0m, \033[1m--backlink\033[0m, and/or \033[1m--dangling\033[0m" << ::std::endl
+ << "options are specified, then information blocks corresponding to linked" << ::std::endl
+ << "configurations are separated with blank lines. For example:" << ::std::endl
+ << ::std::endl
+ << "path: /path/to/cfg/" << ::std::endl
+ << "uuid: 8d439f03-7342-4502-8b1c-74b173869478" << ::std::endl
+ << "type: target" << ::std::endl
+ << "name: foo" << ::std::endl
+ << ::std::endl
+ << "path: /path/to/host-cfg/" << ::std::endl
+ << "uuid: 7ee4dab3-07d9-4163-81c0-3779166a7213" << ::std::endl
+ << "type: host" << ::std::endl
+ << "name: tools" << ::std::endl
+ << ::std::endl
+ << "path: /path/to/build2-cfg/" << ::std::endl
+ << "uuid: d453aa2a-92c4-4066-87e4-c8672eed06e1" << ::std::endl
+ << "type: build2" << ::std::endl
+ << "name: modules" << ::std::endl;
+
+ p = ::bpkg::cfg_info_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mcfg-info\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-cfg-info.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mcfg-info\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/cfg-info-options.hxx b/bpkg/cfg-info-options.hxx
new file mode 100644
index 0000000..2024bf6
--- /dev/null
+++ b/bpkg/cfg-info-options.hxx
@@ -0,0 +1,125 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_CFG_INFO_OPTIONS_HXX
+#define BPKG_CFG_INFO_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class cfg_info_options: public ::bpkg::configuration_options
+ {
+ public:
+ cfg_info_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const cfg_info_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ link () const;
+
+ const bool&
+ backlink () const;
+
+ const bool&
+ dangling () const;
+
+ const bool&
+ recursive () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool link_;
+ bool backlink_;
+ bool dangling_;
+ bool recursive_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_cfg_info_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/cfg-info-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_CFG_INFO_OPTIONS_HXX
diff --git a/bpkg/cfg-info-options.ixx b/bpkg/cfg-info-options.ixx
new file mode 100644
index 0000000..3eb43b3
--- /dev/null
+++ b/bpkg/cfg-info-options.ixx
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // cfg_info_options
+ //
+
+ inline const bool& cfg_info_options::
+ link () const
+ {
+ return this->link_;
+ }
+
+ inline const bool& cfg_info_options::
+ backlink () const
+ {
+ return this->backlink_;
+ }
+
+ inline const bool& cfg_info_options::
+ dangling () const
+ {
+ return this->dangling_;
+ }
+
+ inline const bool& cfg_info_options::
+ recursive () const
+ {
+ return this->recursive_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/cfg-link-options.cxx b/bpkg/cfg-link-options.cxx
new file mode 100644
index 0000000..6479d14
--- /dev/null
+++ b/bpkg/cfg-link-options.cxx
@@ -0,0 +1,715 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/cfg-link-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // cfg_link_options
+ //
+
+ cfg_link_options::
+ cfg_link_options ()
+ : name_ (),
+ name_specified_ (false),
+ relative_ ()
+ {
+ }
+
+ bool cfg_link_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool cfg_link_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool cfg_link_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool cfg_link_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool cfg_link_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void cfg_link_options::
+ merge (const cfg_link_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.name_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->name_, a.name_);
+ this->name_specified_ = true;
+ }
+
+ if (a.relative_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->relative_, a.relative_);
+ }
+ }
+
+ ::bpkg::cli::usage_para cfg_link_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mCFG-LINK OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--name\033[0m \033[4mname\033[0m Alternative link name. If this option is not" << ::std::endl
+ << " specified, then the configuration name is used as the" << ::std::endl
+ << " link name (see \033[1mbpkg-cfg-create(1)\033[0m for details)." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--relative\033[0m Rebase the absolute linked configuration path" << ::std::endl
+ << " relative to the current configuration directory." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (cfg_link_options&, ::bpkg::cli::scanner&)>
+ _cli_cfg_link_options_map;
+
+ static _cli_cfg_link_options_map _cli_cfg_link_options_map_;
+
+ struct _cli_cfg_link_options_map_init
+ {
+ _cli_cfg_link_options_map_init ()
+ {
+ _cli_cfg_link_options_map_["--name"] =
+ &::bpkg::cli::thunk< cfg_link_options, string, &cfg_link_options::name_,
+ &cfg_link_options::name_specified_ >;
+ _cli_cfg_link_options_map_["--relative"] =
+ &::bpkg::cli::thunk< cfg_link_options, &cfg_link_options::relative_ >;
+ }
+ };
+
+ static _cli_cfg_link_options_map_init _cli_cfg_link_options_map_init_;
+
+ bool cfg_link_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_cfg_link_options_map::const_iterator i (_cli_cfg_link_options_map_.find (o));
+
+ if (i != _cli_cfg_link_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool cfg_link_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_cfg_link_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg cfg-link\033[0m [\033[4moptions\033[0m] \033[4mdir\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mcfg-link\033[0m command links the specified \033[1mbpkg\033[0m configuration with the current" << ::std::endl
+ << "configuration. Note that it also establishes an implicit backlink from the" << ::std::endl
+ << "specified to the current configuration. See \033[1mbpkg-cfg-create(1)\033[0m for background" << ::std::endl
+ << "on linked configurations. To unlink previously linked configurations use" << ::std::endl
+ << "\033[1mbpkg-cfg-unlink(1)\033[0m." << ::std::endl
+ << ::std::endl
+ << "The linked configurations are normally referred to using names when specified" << ::std::endl
+ << "on the \033[1mbpkg\033[0m command line. Unless overridden with the \033[1m--name\033[0m option, the" << ::std::endl
+ << "original configuration name is used to name the link. If the link is unnamed," << ::std::endl
+ << "then it can be referred to using the numeric id that is automatically assigned" << ::std::endl
+ << "when establishing the link or using the configuration UUID." << ::std::endl
+ << ::std::endl
+ << "If the specified configuration path is relative, then it is rebased relative to" << ::std::endl
+ << "the current configuration directory. This way, when the linked configurations" << ::std::endl
+ << "are moved around together, the stored relative paths remain valid. If the" << ::std::endl
+ << "specified directory path is absolute, then it is stored as absolute unless the" << ::std::endl
+ << "\033[1m--relative\033[0m option is specified in which case it is also rebased relative to the" << ::std::endl
+ << "current configuration directory." << ::std::endl;
+
+ p = ::bpkg::cfg_link_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mcfg-link\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-cfg-link.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mcfg-link\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/cfg-link-options.hxx b/bpkg/cfg-link-options.hxx
new file mode 100644
index 0000000..9c506ce
--- /dev/null
+++ b/bpkg/cfg-link-options.hxx
@@ -0,0 +1,121 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_CFG_LINK_OPTIONS_HXX
+#define BPKG_CFG_LINK_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class cfg_link_options: public ::bpkg::configuration_options
+ {
+ public:
+ cfg_link_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const cfg_link_options&);
+
+ // Option accessors.
+ //
+ const string&
+ name () const;
+
+ bool
+ name_specified () const;
+
+ const bool&
+ relative () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ string name_;
+ bool name_specified_;
+ bool relative_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_cfg_link_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/cfg-link-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_CFG_LINK_OPTIONS_HXX
diff --git a/bpkg/cfg-link-options.ixx b/bpkg/cfg-link-options.ixx
new file mode 100644
index 0000000..685f89e
--- /dev/null
+++ b/bpkg/cfg-link-options.ixx
@@ -0,0 +1,39 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // cfg_link_options
+ //
+
+ inline const string& cfg_link_options::
+ name () const
+ {
+ return this->name_;
+ }
+
+ inline bool cfg_link_options::
+ name_specified () const
+ {
+ return this->name_specified_;
+ }
+
+ inline const bool& cfg_link_options::
+ relative () const
+ {
+ return this->relative_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/cfg-unlink-options.cxx b/bpkg/cfg-unlink-options.cxx
new file mode 100644
index 0000000..82b08d6
--- /dev/null
+++ b/bpkg/cfg-unlink-options.cxx
@@ -0,0 +1,732 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/cfg-unlink-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // cfg_unlink_options
+ //
+
+ cfg_unlink_options::
+ cfg_unlink_options ()
+ : name_ (),
+ name_specified_ (false),
+ id_ (),
+ id_specified_ (false),
+ uuid_ (),
+ uuid_specified_ (false),
+ dangling_ ()
+ {
+ }
+
+ bool cfg_unlink_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool cfg_unlink_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool cfg_unlink_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool cfg_unlink_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool cfg_unlink_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void cfg_unlink_options::
+ merge (const cfg_unlink_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.name_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->name_, a.name_);
+ this->name_specified_ = true;
+ }
+
+ if (a.id_specified_)
+ {
+ ::bpkg::cli::parser< uint64_t>::merge (
+ this->id_, a.id_);
+ this->id_specified_ = true;
+ }
+
+ if (a.uuid_specified_)
+ {
+ ::bpkg::cli::parser< uuid_type>::merge (
+ this->uuid_, a.uuid_);
+ this->uuid_specified_ = true;
+ }
+
+ if (a.dangling_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->dangling_, a.dangling_);
+ }
+ }
+
+ ::bpkg::cli::usage_para cfg_unlink_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mCFG-UNLINK OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--name\033[0m \033[4mname\033[0m Name of the configuration to unlink." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--id\033[0m \033[4mid\033[0m Numeric id of the configuration to unlink." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--uuid\033[0m \033[4muuid\033[0m UUID of the configuration to unlink." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--dangling\033[0m Remove dangling implicit backlinks." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (cfg_unlink_options&, ::bpkg::cli::scanner&)>
+ _cli_cfg_unlink_options_map;
+
+ static _cli_cfg_unlink_options_map _cli_cfg_unlink_options_map_;
+
+ struct _cli_cfg_unlink_options_map_init
+ {
+ _cli_cfg_unlink_options_map_init ()
+ {
+ _cli_cfg_unlink_options_map_["--name"] =
+ &::bpkg::cli::thunk< cfg_unlink_options, string, &cfg_unlink_options::name_,
+ &cfg_unlink_options::name_specified_ >;
+ _cli_cfg_unlink_options_map_["--id"] =
+ &::bpkg::cli::thunk< cfg_unlink_options, uint64_t, &cfg_unlink_options::id_,
+ &cfg_unlink_options::id_specified_ >;
+ _cli_cfg_unlink_options_map_["--uuid"] =
+ &::bpkg::cli::thunk< cfg_unlink_options, uuid_type, &cfg_unlink_options::uuid_,
+ &cfg_unlink_options::uuid_specified_ >;
+ _cli_cfg_unlink_options_map_["--dangling"] =
+ &::bpkg::cli::thunk< cfg_unlink_options, &cfg_unlink_options::dangling_ >;
+ }
+ };
+
+ static _cli_cfg_unlink_options_map_init _cli_cfg_unlink_options_map_init_;
+
+ bool cfg_unlink_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_cfg_unlink_options_map::const_iterator i (_cli_cfg_unlink_options_map_.find (o));
+
+ if (i != _cli_cfg_unlink_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool cfg_unlink_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_cfg_unlink_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg cfg-unlink\033[0m [\033[4moptions\033[0m] [\033[4mdir\033[0m]" << ::std::endl
+ << "\033[1mbpkg cfg-unlink\033[0m [\033[4moptions\033[0m] \033[1m--dangling\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mcfg-unlink\033[0m command unlinks the specified \033[1mbpkg\033[0m configuration from the" << ::std::endl
+ << "current configuration (the first form) or removes dangling implicit backlinks" << ::std::endl
+ << "(the second form). See \033[1mbpkg-cfg-create(1)\033[0m for background on linked" << ::std::endl
+ << "configurations." << ::std::endl
+ << ::std::endl
+ << "In the first form the configuration to unlink can be specified either as" << ::std::endl
+ << "configuration directory (\033[4mdir\033[0m), name (\033[1m--name\033[0m), id (\033[1m--id\033[0m), or UUID (\033[1m--uuid\033[0m)." << ::std::endl;
+
+ p = ::bpkg::cfg_unlink_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mcfg-unlink\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-cfg-unlink.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mcfg-unlink\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/cfg-unlink-options.hxx b/bpkg/cfg-unlink-options.hxx
new file mode 100644
index 0000000..14c9aa4
--- /dev/null
+++ b/bpkg/cfg-unlink-options.hxx
@@ -0,0 +1,137 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_CFG_UNLINK_OPTIONS_HXX
+#define BPKG_CFG_UNLINK_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class cfg_unlink_options: public ::bpkg::configuration_options
+ {
+ public:
+ cfg_unlink_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const cfg_unlink_options&);
+
+ // Option accessors.
+ //
+ const string&
+ name () const;
+
+ bool
+ name_specified () const;
+
+ const uint64_t&
+ id () const;
+
+ bool
+ id_specified () const;
+
+ const uuid_type&
+ uuid () const;
+
+ bool
+ uuid_specified () const;
+
+ const bool&
+ dangling () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ string name_;
+ bool name_specified_;
+ uint64_t id_;
+ bool id_specified_;
+ uuid_type uuid_;
+ bool uuid_specified_;
+ bool dangling_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_cfg_unlink_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/cfg-unlink-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_CFG_UNLINK_OPTIONS_HXX
diff --git a/bpkg/cfg-unlink-options.ixx b/bpkg/cfg-unlink-options.ixx
new file mode 100644
index 0000000..7d9d63c
--- /dev/null
+++ b/bpkg/cfg-unlink-options.ixx
@@ -0,0 +1,63 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // cfg_unlink_options
+ //
+
+ inline const string& cfg_unlink_options::
+ name () const
+ {
+ return this->name_;
+ }
+
+ inline bool cfg_unlink_options::
+ name_specified () const
+ {
+ return this->name_specified_;
+ }
+
+ inline const uint64_t& cfg_unlink_options::
+ id () const
+ {
+ return this->id_;
+ }
+
+ inline bool cfg_unlink_options::
+ id_specified () const
+ {
+ return this->id_specified_;
+ }
+
+ inline const uuid_type& cfg_unlink_options::
+ uuid () const
+ {
+ return this->uuid_;
+ }
+
+ inline bool cfg_unlink_options::
+ uuid_specified () const
+ {
+ return this->uuid_specified_;
+ }
+
+ inline const bool& cfg_unlink_options::
+ dangling () const
+ {
+ return this->dangling_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/common-options.cxx b/bpkg/common-options.cxx
new file mode 100644
index 0000000..e841232
--- /dev/null
+++ b/bpkg/common-options.cxx
@@ -0,0 +1,2230 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+#include <fstream>
+
+namespace bpkg
+{
+ 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 ("{", "");
+ }
+
+ 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 bpkg
+{
+ // common_options
+ //
+
+ common_options::
+ common_options ()
+ : v_ (),
+ V_ (),
+ quiet_ (),
+ verbose_ (1),
+ verbose_specified_ (false),
+ stdout_format_ (bpkg::stdout_format::lines),
+ stdout_format_specified_ (false),
+ jobs_ (),
+ jobs_specified_ (false),
+ no_result_ (),
+ structured_result_ (),
+ structured_result_specified_ (false),
+ progress_ (),
+ no_progress_ (),
+ diag_color_ (),
+ no_diag_color_ (),
+ build_ (),
+ build_specified_ (false),
+ build_option_ (),
+ build_option_specified_ (false),
+ fetch_ (),
+ fetch_specified_ (false),
+ fetch_option_ (),
+ fetch_option_specified_ (false),
+ curl_ (),
+ curl_specified_ (false),
+ curl_option_ (),
+ curl_option_specified_ (false),
+ fetch_timeout_ (),
+ fetch_timeout_specified_ (false),
+ pkg_proxy_ (),
+ pkg_proxy_specified_ (false),
+ git_ ("git"),
+ git_specified_ (false),
+ git_option_ (),
+ git_option_specified_ (false),
+ sha256_ (),
+ sha256_specified_ (false),
+ sha256_option_ (),
+ sha256_option_specified_ (false),
+ tar_ (),
+ tar_specified_ (false),
+ tar_option_ (),
+ tar_option_specified_ (false),
+ openssl_ ("openssl"),
+ openssl_specified_ (false),
+ openssl_option_ (),
+ openssl_option_specified_ (false),
+ auth_ (bpkg::auth::remote),
+ auth_specified_ (false),
+ trust_ (),
+ trust_specified_ (false),
+ trust_yes_ (),
+ trust_no_ (),
+ git_capabilities_ (),
+ git_capabilities_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_ (),
+ keep_tmp_ ()
+ {
+ }
+
+ void common_options::
+ merge (const common_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ if (a.v_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->v_, a.v_);
+ }
+
+ if (a.V_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->V_, a.V_);
+ }
+
+ if (a.quiet_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->quiet_, a.quiet_);
+ }
+
+ if (a.verbose_specified_)
+ {
+ ::bpkg::cli::parser< uint16_t>::merge (
+ this->verbose_, a.verbose_);
+ this->verbose_specified_ = true;
+ }
+
+ if (a.stdout_format_specified_)
+ {
+ ::bpkg::cli::parser< bpkg::stdout_format>::merge (
+ this->stdout_format_, a.stdout_format_);
+ this->stdout_format_specified_ = true;
+ }
+
+ if (a.jobs_specified_)
+ {
+ ::bpkg::cli::parser< size_t>::merge (
+ this->jobs_, a.jobs_);
+ this->jobs_specified_ = true;
+ }
+
+ if (a.no_result_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_result_, a.no_result_);
+ }
+
+ if (a.structured_result_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->structured_result_, a.structured_result_);
+ this->structured_result_specified_ = true;
+ }
+
+ if (a.progress_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->progress_, a.progress_);
+ }
+
+ if (a.no_progress_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_progress_, a.no_progress_);
+ }
+
+ if (a.diag_color_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->diag_color_, a.diag_color_);
+ }
+
+ if (a.no_diag_color_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_diag_color_, a.no_diag_color_);
+ }
+
+ if (a.build_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->build_, a.build_);
+ this->build_specified_ = true;
+ }
+
+ if (a.build_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->build_option_, a.build_option_);
+ this->build_option_specified_ = true;
+ }
+
+ if (a.fetch_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->fetch_, a.fetch_);
+ this->fetch_specified_ = true;
+ }
+
+ if (a.fetch_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->fetch_option_, a.fetch_option_);
+ this->fetch_option_specified_ = true;
+ }
+
+ if (a.curl_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->curl_, a.curl_);
+ this->curl_specified_ = true;
+ }
+
+ if (a.curl_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->curl_option_, a.curl_option_);
+ this->curl_option_specified_ = true;
+ }
+
+ if (a.fetch_timeout_specified_)
+ {
+ ::bpkg::cli::parser< size_t>::merge (
+ this->fetch_timeout_, a.fetch_timeout_);
+ this->fetch_timeout_specified_ = true;
+ }
+
+ if (a.pkg_proxy_specified_)
+ {
+ ::bpkg::cli::parser< butl::url>::merge (
+ this->pkg_proxy_, a.pkg_proxy_);
+ this->pkg_proxy_specified_ = true;
+ }
+
+ if (a.git_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->git_, a.git_);
+ this->git_specified_ = true;
+ }
+
+ if (a.git_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->git_option_, a.git_option_);
+ this->git_option_specified_ = true;
+ }
+
+ if (a.sha256_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->sha256_, a.sha256_);
+ this->sha256_specified_ = true;
+ }
+
+ if (a.sha256_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->sha256_option_, a.sha256_option_);
+ this->sha256_option_specified_ = true;
+ }
+
+ if (a.tar_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->tar_, a.tar_);
+ this->tar_specified_ = true;
+ }
+
+ if (a.tar_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->tar_option_, a.tar_option_);
+ this->tar_option_specified_ = true;
+ }
+
+ if (a.openssl_specified_)
+ {
+ ::bpkg::cli::parser< qualified_option<openssl_commands, path>>::merge (
+ this->openssl_, a.openssl_);
+ this->openssl_specified_ = true;
+ }
+
+ if (a.openssl_option_specified_)
+ {
+ ::bpkg::cli::parser< qualified_option<openssl_commands, strings>>::merge (
+ this->openssl_option_, a.openssl_option_);
+ this->openssl_option_specified_ = true;
+ }
+
+ if (a.auth_specified_)
+ {
+ ::bpkg::cli::parser< bpkg::auth>::merge (
+ this->auth_, a.auth_);
+ this->auth_specified_ = true;
+ }
+
+ if (a.trust_specified_)
+ {
+ ::bpkg::cli::parser< std::set<string, icase_compare_string>>::merge (
+ this->trust_, a.trust_);
+ this->trust_specified_ = true;
+ }
+
+ if (a.trust_yes_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->trust_yes_, a.trust_yes_);
+ }
+
+ if (a.trust_no_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->trust_no_, a.trust_no_);
+ }
+
+ if (a.git_capabilities_specified_)
+ {
+ ::bpkg::cli::parser< git_capabilities_map>::merge (
+ this->git_capabilities_, a.git_capabilities_);
+ this->git_capabilities_specified_ = true;
+ }
+
+ if (a.pager_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->pager_, a.pager_);
+ this->pager_specified_ = true;
+ }
+
+ if (a.pager_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->pager_option_, a.pager_option_);
+ this->pager_option_specified_ = true;
+ }
+
+ if (a.options_file_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->options_file_, a.options_file_);
+ this->options_file_specified_ = true;
+ }
+
+ if (a.default_options_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->default_options_, a.default_options_);
+ this->default_options_specified_ = true;
+ }
+
+ if (a.no_default_options_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_default_options_, a.no_default_options_);
+ }
+
+ if (a.keep_tmp_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->keep_tmp_, a.keep_tmp_);
+ }
+ }
+
+ ::bpkg::cli::usage_para common_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::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[1mbpkg-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--no-result\033[0m Don't print informational messages about the outcome" << ::std::endl
+ << " of performing a command or some of its parts." << ::std::endl;
+
+ os << "\033[1m--structured-result\033[0m \033[4mfmt\033[0m Write the result of performing a command in a" << ::std::endl
+ << " structured form." << ::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--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--fetch\033[0m \033[4mpath\033[0m The fetch program to be used to download resources." << ::std::endl;
+
+ os << "\033[1m--fetch-option\033[0m \033[4mopt\033[0m Additional option to be passed to the fetch program." << ::std::endl;
+
+ os << "\033[1m--fetch-timeout\033[0m \033[4msec\033[0m The fetch and fetch-like (for example, \033[1mgit\033[0m) program" << ::std::endl
+ << " timeout." << ::std::endl;
+
+ os << "\033[1m--pkg-proxy\033[0m \033[4murl\033[0m HTTP proxy server to use when fetching package" << ::std::endl
+ << " manifests and archives from remote \033[1mpkg\033[0m repositories." << ::std::endl;
+
+ os << "\033[1m--git\033[0m \033[4mpath\033[0m The git program to be used to fetch git repositories." << ::std::endl;
+
+ os << "\033[1m--git-option\033[0m \033[4mopt\033[0m Additional common option to be passed to the git" << ::std::endl
+ << " program." << ::std::endl;
+
+ os << "\033[1m--sha256\033[0m \033[4mpath\033[0m The sha256 program to be used to calculate SHA256" << ::std::endl
+ << " sums." << ::std::endl;
+
+ os << "\033[1m--sha256-option\033[0m \033[4mopt\033[0m Additional option to be passed to the sha256 program." << ::std::endl;
+
+ os << "\033[1m--tar\033[0m \033[4mpath\033[0m The tar program to be used to extract package" << ::std::endl
+ << " archives." << ::std::endl;
+
+ os << "\033[1m--tar-option\033[0m \033[4mopt\033[0m Additional option to be passed to the tar program." << ::std::endl;
+
+ os << "\033[1m--openssl\033[0m \033[4mpath\033[0m The openssl program to be used for crypto operations." << ::std::endl;
+
+ os << "\033[1m--openssl-option\033[0m \033[4mopt\033[0m Additional option to be passed to the openssl" << ::std::endl
+ << " program." << ::std::endl;
+
+ os << "\033[1m--auth\033[0m \033[4mtype\033[0m Types of repositories to authenticate." << ::std::endl;
+
+ os << "\033[1m--trust\033[0m \033[4mfingerprint\033[0m Trust repository certificate with a SHA256" << ::std::endl
+ << " \033[4mfingerprint\033[0m." << ::std::endl;
+
+ os << "\033[1m--trust-yes\033[0m Assume the answer to all authentication prompts is" << ::std::endl
+ << " \033[1myes\033[0m." << ::std::endl;
+
+ os << "\033[1m--trust-no\033[0m Assume the answer to all authentication prompts is" << ::std::endl
+ << " \033[1mno\033[0m." << ::std::endl;
+
+ os << "\033[1m--git-capabilities\033[0m \033[4mup\033[0m=\033[4mpc\033[0m Protocol capabilities (\033[4mpc\033[0m) for a \033[1mgit\033[0m repository URL" << ::std::endl
+ << " prefix (\033[4mup\033[0m)." << ::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;
+
+ os << "\033[1m--keep-tmp\033[0m Don't remove the \033[1mbpkg\033[0m's temporary directory at the" << ::std::endl
+ << " end of the command execution and print its path at" << ::std::endl
+ << " the verbosity level 2 or higher." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ ::bpkg::cli::usage_para common_options::
+ print_long_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::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." << ::std::endl
+ << " This option is also propagated when performing build" << ::std::endl
+ << " system operations such as \033[1mupdate\033[0m, \033[1mtest\033[0m, etc." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-result\033[0m Don't print informational messages about the outcome" << ::std::endl
+ << " of performing a command or some of its parts. Note" << ::std::endl
+ << " that if this option is specified, then for certain" << ::std::endl
+ << " long-running command parts progress is displayed" << ::std::endl
+ << " instead, unless suppressed with \033[1m--no-progress\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--structured-result\033[0m \033[4mfmt\033[0m Write the result of performing a command in a" << ::std::endl
+ << " structured form. In this mode, instead of printing to" << ::std::endl
+ << " \033[1mstderr\033[0m informational messages about the outcome of" << ::std::endl
+ << " performing a command or some of its parts, \033[1mbpkg\033[0m" << ::std::endl
+ << " writes to \033[1mstdout\033[0m a machine-readable result" << ::std::endl
+ << " description in the specified format. Not all commands" << ::std::endl
+ << " support producing structured result and valid \033[4mfmt\033[0m" << ::std::endl
+ << " values are command-specific. Consult the command" << ::std::endl
+ << " documentation for details." << ::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--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[1mbpkg\033[0m will by default use \033[1mb\033[0m plus an executable" << ::std::endl
+ << " suffix if one was specified when building \033[1mbpkg\033[0m. So," << ::std::endl
+ << " for example, if \033[1mbpkg\033[0m name was set to \033[1mbpkg-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--fetch\033[0m \033[4mpath\033[0m The fetch program to be used to download resources." << ::std::endl
+ << " Currently, \033[1mbpkg\033[0m recognizes \033[1mcurl\033[0m, \033[1mwget\033[0m, and \033[1mfetch\033[0m." << ::std::endl
+ << " Note that the last component of \033[4mpath\033[0m must contain one" << ::std::endl
+ << " of these names as a substring in order for \033[1mbpkg\033[0m to" << ::std::endl
+ << " recognize which program is being used. You can also" << ::std::endl
+ << " specify additional options that should be passed to" << ::std::endl
+ << " the fetch program with \033[1m--fetch-option\033[0m." << ::std::endl
+ << ::std::endl
+ << " If the fetch program is not specified, then \033[1mbpkg\033[0m will" << ::std::endl
+ << " try to discover if one of the above programs is" << ::std::endl
+ << " available and use that. Currently, \033[1mbpkg\033[0m has the" << ::std::endl
+ << " following preference order: \033[1mcurl\033[0m, \033[1mwget\033[0m, and \033[1mfetch\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fetch-option\033[0m \033[4mopt\033[0m Additional option to be passed to the fetch program." << ::std::endl
+ << " See \033[1m--fetch\033[0m for more information on the fetch" << ::std::endl
+ << " program. Repeat this option to specify multiple fetch" << ::std::endl
+ << " options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fetch-timeout\033[0m \033[4msec\033[0m The fetch and fetch-like (for example, \033[1mgit\033[0m) program" << ::std::endl
+ << " timeout. While the exact semantics of the value" << ::std::endl
+ << " depends on the program used, at a minimum it" << ::std::endl
+ << " specifies in seconds the maximum time that can be" << ::std::endl
+ << " spent without any network activity." << ::std::endl
+ << ::std::endl
+ << " Specifically, it is translated to the \033[1m--max-time\033[0m" << ::std::endl
+ << " option for \033[1mcurl\033[0m and to the \033[1m--timeout\033[0m option for \033[1mwget\033[0m" << ::std::endl
+ << " and \033[1mfetch\033[0m. For \033[1mgit\033[0m over HTTP/HTTPS this semantics is" << ::std::endl
+ << " achieved using the \033[1mhttp.lowSpeedLimit\033[0m=\033[4m1\033[0m" << ::std::endl
+ << " \033[1mhttp.lowSpeedTime\033[0m=\033[4msec\033[0m configuration values (the" << ::std::endl
+ << " \033[1mgit://\033[0m and \033[1mssh://\033[0m protocols currently do not support" << ::std::endl
+ << " timeouts)." << ::std::endl
+ << ::std::endl
+ << " See \033[1m--fetch\033[0m and \033[1m--git\033[0m for more information on the" << ::std::endl
+ << " fetch programs." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--pkg-proxy\033[0m \033[4murl\033[0m HTTP proxy server to use when fetching package" << ::std::endl
+ << " manifests and archives from remote \033[1mpkg\033[0m repositories." << ::std::endl
+ << " If specified, the proxy \033[4murl\033[0m must be in the" << ::std::endl
+ << " \033[1mhttp://\033[0m\033[4mhost\033[0m[\033[1m:\033[0m\033[4mport\033[0m]\033[0m form. If \033[4mport\033[0m is omitted, 80 is" << ::std::endl
+ << " used by default." << ::std::endl
+ << ::std::endl
+ << " Note that to allow caching, the proxied \033[1mhttps://\033[0m URLs" << ::std::endl
+ << " are converted to \033[1mhttp://\033[0m in order to prevent the" << ::std::endl
+ << " fetch program from tunneling (which is the standard" << ::std::endl
+ << " approach for proxying HTTPS). If both HTTP and HTTPS" << ::std::endl
+ << " repositories are used, it is assumed that the proxy" << ::std::endl
+ << " server can figure out which URLs need to be converted" << ::std::endl
+ << " back to \033[1mhttps://\033[0m based on the request information" << ::std::endl
+ << " (for example, host name). For security, this" << ::std::endl
+ << " mechanism should only be used with signed" << ::std::endl
+ << " repositories or when the proxy is located inside a" << ::std::endl
+ << " trusted network." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--git\033[0m \033[4mpath\033[0m The git program to be used to fetch git repositories." << ::std::endl
+ << " You can also specify additional options that should" << ::std::endl
+ << " be passed to the git program with \033[1m--git-option\033[0m." << ::std::endl
+ << ::std::endl
+ << " If the git program is not explicitly specified, then" << ::std::endl
+ << " \033[1mbpkg\033[0m will use \033[1mgit\033[0m by default." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--git-option\033[0m \033[4mopt\033[0m Additional common option to be passed to the git" << ::std::endl
+ << " program. Note that the common options are the ones" << ::std::endl
+ << " that precede the \033[1mgit\033[0m command. See \033[1m--git\033[0m for more" << ::std::endl
+ << " information on the git program. Repeat this option to" << ::std::endl
+ << " specify multiple git options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sha256\033[0m \033[4mpath\033[0m The sha256 program to be used to calculate SHA256" << ::std::endl
+ << " sums. Currently, \033[1mbpkg\033[0m recognizes \033[1msha256\033[0m, \033[1msha256sum\033[0m," << ::std::endl
+ << " and \033[1mshasum\033[0m. Note that the last component of \033[4mpath\033[0m must" << ::std::endl
+ << " contain one of these names as a substring in order" << ::std::endl
+ << " for \033[1mbpkg\033[0m to recognize which program is being used." << ::std::endl
+ << " You can also specify additional options that should" << ::std::endl
+ << " be passed to the sha256 program with \033[1m--sha256-option\033[0m." << ::std::endl
+ << ::std::endl
+ << " If the sha256 program is not specified, then \033[1mbpkg\033[0m" << ::std::endl
+ << " will try to discover if one of the above programs is" << ::std::endl
+ << " available and use that. Currently, \033[1mbpkg\033[0m has the" << ::std::endl
+ << " following preference order: \033[1msha256\033[0m, \033[1msha256sum\033[0m, and" << ::std::endl
+ << " \033[1mshasum\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sha256-option\033[0m \033[4mopt\033[0m Additional option to be passed to the sha256 program." << ::std::endl
+ << " See \033[1m--sha256\033[0m for more information on the sha256" << ::std::endl
+ << " program. Repeat this option to specify multiple" << ::std::endl
+ << " sha256 options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--tar\033[0m \033[4mpath\033[0m The tar program to be used to extract package" << ::std::endl
+ << " archives. For example, \033[1mgtar\033[0m or \033[1mbsdtar\033[0m. You can also" << ::std::endl
+ << " specify additional options that should be passed to" << ::std::endl
+ << " the tar program with \033[1m--tar-option\033[0m. If the tar program" << ::std::endl
+ << " is not explicitly specified, then \033[1mbpkg\033[0m will use \033[1mtar\033[0m" << ::std::endl
+ << " by default." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--tar-option\033[0m \033[4mopt\033[0m Additional option to be passed to the tar program." << ::std::endl
+ << " See \033[1m--tar\033[0m for more information on the tar program." << ::std::endl
+ << " Repeat this option to specify multiple tar options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--openssl\033[0m \033[4mpath\033[0m The openssl program to be used for crypto operations." << ::std::endl
+ << " You can also specify additional options that should" << ::std::endl
+ << " be passed to the openssl program with" << ::std::endl
+ << " \033[1m--openssl-option\033[0m. If the openssl program is not" << ::std::endl
+ << " explicitly specified, then \033[1mbpkg\033[0m will use \033[1mopenssl\033[0m by" << ::std::endl
+ << " default." << ::std::endl
+ << ::std::endl
+ << " The \033[1m--openssl*\033[0m values can be optionally qualified" << ::std::endl
+ << " with the openssl command in the \033[4mcommand\033[0m\033[1m:\033[0m\033[4mvalue\033[0m\033[0m form." << ::std::endl
+ << " This makes the value only applicable to the specific" << ::std::endl
+ << " command, for example:" << ::std::endl
+ << ::std::endl
+ << " bpkg rep-create \\" << ::std::endl
+ << " --openssl pkeyutl:/path/to/openssl \\" << ::std::endl
+ << " --openssl-option pkeyutl:-engine \\" << ::std::endl
+ << " --openssl-option pkeyutl:pkcs11 \\" << ::std::endl
+ << " ..." << ::std::endl
+ << ::std::endl
+ << " Note that for \033[1mopenssl\033[0m versions prior to \033[1m3.0.0\033[0m \033[1mbpkg\033[0m" << ::std::endl
+ << " uses the \033[1mrsautl\033[0m command instead of \033[1mpkeyutl\033[0m for the" << ::std::endl
+ << " data signing and recovery operations." << ::std::endl
+ << ::std::endl
+ << " An unqualified value that contains a colon can be" << ::std::endl
+ << " specified as qualified with an empty command, for" << ::std::endl
+ << " example, \033[1m--openssl :C:\\bin\\openssl\033[0m. To see openssl" << ::std::endl
+ << " commands executed by \033[1mbpkg\033[0m, use the verbose mode (\033[1m-v\033[0m" << ::std::endl
+ << " option)." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--openssl-option\033[0m \033[4mopt\033[0m Additional option to be passed to the openssl" << ::std::endl
+ << " program. See \033[1m--openssl\033[0m for more information on the" << ::std::endl
+ << " openssl program. The values can be optionally" << ::std::endl
+ << " qualified with the openssl command, as discussed in" << ::std::endl
+ << " \033[1m--openssl\033[0m. Repeat this option to specify multiple" << ::std::endl
+ << " openssl options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--auth\033[0m \033[4mtype\033[0m Types of repositories to authenticate. Valid values" << ::std::endl
+ << " for this option are \033[1mnone\033[0m, \033[1mremote\033[0m, \033[1mall\033[0m. By default" << ::std::endl
+ << " only remote repositories are authenticated. You can" << ::std::endl
+ << " request authentication of local repositories by" << ::std::endl
+ << " passing \033[1mall\033[0m or disable authentication completely by" << ::std::endl
+ << " passing \033[1mnone\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--trust\033[0m \033[4mfingerprint\033[0m Trust repository certificate with a SHA256" << ::std::endl
+ << " \033[4mfingerprint\033[0m. Such a certificate is trusted" << ::std::endl
+ << " automatically, without prompting the user for a" << ::std::endl
+ << " confirmation. Repeat this option to trust multiple" << ::std::endl
+ << " certificates." << ::std::endl
+ << ::std::endl
+ << " Note that by default \033[1mopenssl\033[0m prints a SHA1" << ::std::endl
+ << " fingerprint and to obtain a SHA256 one you will need" << ::std::endl
+ << " to pass the \033[1m-sha256\033[0m option, for example:" << ::std::endl
+ << ::std::endl
+ << " openssl x509 -sha256 -fingerprint -noout -in cert.pem" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--trust-yes\033[0m Assume the answer to all authentication prompts is" << ::std::endl
+ << " \033[1myes\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--trust-no\033[0m Assume the answer to all authentication prompts is" << ::std::endl
+ << " \033[1mno\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--git-capabilities\033[0m \033[4mup\033[0m=\033[4mpc\033[0m Protocol capabilities (\033[4mpc\033[0m) for a \033[1mgit\033[0m repository URL" << ::std::endl
+ << " prefix (\033[4mup\033[0m). Valid values for the capabilities are" << ::std::endl
+ << " \033[1mdumb\033[0m (no shallow clone support), \033[1msmart\033[0m (support for" << ::std::endl
+ << " shallow clone, but not for fetching unadvertised" << ::std::endl
+ << " commits), \033[1munadv\033[0m (support for shallow clone and for" << ::std::endl
+ << " fetching unadvertised commits). For example:" << ::std::endl
+ << ::std::endl
+ << " bpkg build https://example.org/foo.git#master \\" << ::std::endl
+ << " --git-capabilities https://example.org=smart" << ::std::endl
+ << ::std::endl
+ << " See \033[1mbpkg-repository-types(1)\033[0m for details on the \033[1mgit\033[0m" << ::std::endl
+ << " protocol capabilities." << ::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[1mbpkg\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;
+
+ os << std::endl
+ << "\033[1m--keep-tmp\033[0m Don't remove the \033[1mbpkg\033[0m's temporary directory at the" << ::std::endl
+ << " end of the command execution and print its path at" << ::std::endl
+ << " the verbosity level 2 or higher. This option is" << ::std::endl
+ << " primarily useful for troubleshooting." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (common_options&, ::bpkg::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"] =
+ &::bpkg::cli::thunk< common_options, &common_options::v_ >;
+ _cli_common_options_map_["-V"] =
+ &::bpkg::cli::thunk< common_options, &common_options::V_ >;
+ _cli_common_options_map_["--quiet"] =
+ &::bpkg::cli::thunk< common_options, &common_options::quiet_ >;
+ _cli_common_options_map_["-q"] =
+ &::bpkg::cli::thunk< common_options, &common_options::quiet_ >;
+ _cli_common_options_map_["--verbose"] =
+ &::bpkg::cli::thunk< common_options, uint16_t, &common_options::verbose_,
+ &common_options::verbose_specified_ >;
+ _cli_common_options_map_["--stdout-format"] =
+ &::bpkg::cli::thunk< common_options, bpkg::stdout_format, &common_options::stdout_format_,
+ &common_options::stdout_format_specified_ >;
+ _cli_common_options_map_["--jobs"] =
+ &::bpkg::cli::thunk< common_options, size_t, &common_options::jobs_,
+ &common_options::jobs_specified_ >;
+ _cli_common_options_map_["-j"] =
+ &::bpkg::cli::thunk< common_options, size_t, &common_options::jobs_,
+ &common_options::jobs_specified_ >;
+ _cli_common_options_map_["--no-result"] =
+ &::bpkg::cli::thunk< common_options, &common_options::no_result_ >;
+ _cli_common_options_map_["--structured-result"] =
+ &::bpkg::cli::thunk< common_options, string, &common_options::structured_result_,
+ &common_options::structured_result_specified_ >;
+ _cli_common_options_map_["--progress"] =
+ &::bpkg::cli::thunk< common_options, &common_options::progress_ >;
+ _cli_common_options_map_["--no-progress"] =
+ &::bpkg::cli::thunk< common_options, &common_options::no_progress_ >;
+ _cli_common_options_map_["--diag-color"] =
+ &::bpkg::cli::thunk< common_options, &common_options::diag_color_ >;
+ _cli_common_options_map_["--no-diag-color"] =
+ &::bpkg::cli::thunk< common_options, &common_options::no_diag_color_ >;
+ _cli_common_options_map_["--build"] =
+ &::bpkg::cli::thunk< common_options, path, &common_options::build_,
+ &common_options::build_specified_ >;
+ _cli_common_options_map_["--build-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::build_option_,
+ &common_options::build_option_specified_ >;
+ _cli_common_options_map_["--fetch"] =
+ &::bpkg::cli::thunk< common_options, path, &common_options::fetch_,
+ &common_options::fetch_specified_ >;
+ _cli_common_options_map_["--fetch-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::fetch_option_,
+ &common_options::fetch_option_specified_ >;
+ _cli_common_options_map_["--curl"] =
+ &::bpkg::cli::thunk< common_options, path, &common_options::curl_,
+ &common_options::curl_specified_ >;
+ _cli_common_options_map_["--curl-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::curl_option_,
+ &common_options::curl_option_specified_ >;
+ _cli_common_options_map_["--fetch-timeout"] =
+ &::bpkg::cli::thunk< common_options, size_t, &common_options::fetch_timeout_,
+ &common_options::fetch_timeout_specified_ >;
+ _cli_common_options_map_["--pkg-proxy"] =
+ &::bpkg::cli::thunk< common_options, butl::url, &common_options::pkg_proxy_,
+ &common_options::pkg_proxy_specified_ >;
+ _cli_common_options_map_["--git"] =
+ &::bpkg::cli::thunk< common_options, path, &common_options::git_,
+ &common_options::git_specified_ >;
+ _cli_common_options_map_["--git-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::git_option_,
+ &common_options::git_option_specified_ >;
+ _cli_common_options_map_["--sha256"] =
+ &::bpkg::cli::thunk< common_options, path, &common_options::sha256_,
+ &common_options::sha256_specified_ >;
+ _cli_common_options_map_["--sha256-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::sha256_option_,
+ &common_options::sha256_option_specified_ >;
+ _cli_common_options_map_["--tar"] =
+ &::bpkg::cli::thunk< common_options, path, &common_options::tar_,
+ &common_options::tar_specified_ >;
+ _cli_common_options_map_["--tar-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::tar_option_,
+ &common_options::tar_option_specified_ >;
+ _cli_common_options_map_["--openssl"] =
+ &::bpkg::cli::thunk< common_options, qualified_option<openssl_commands, path>, &common_options::openssl_,
+ &common_options::openssl_specified_ >;
+ _cli_common_options_map_["--openssl-option"] =
+ &::bpkg::cli::thunk< common_options, qualified_option<openssl_commands, strings>, &common_options::openssl_option_,
+ &common_options::openssl_option_specified_ >;
+ _cli_common_options_map_["--auth"] =
+ &::bpkg::cli::thunk< common_options, bpkg::auth, &common_options::auth_,
+ &common_options::auth_specified_ >;
+ _cli_common_options_map_["--trust"] =
+ &::bpkg::cli::thunk< common_options, std::set<string, icase_compare_string>, &common_options::trust_,
+ &common_options::trust_specified_ >;
+ _cli_common_options_map_["--trust-yes"] =
+ &::bpkg::cli::thunk< common_options, &common_options::trust_yes_ >;
+ _cli_common_options_map_["--trust-no"] =
+ &::bpkg::cli::thunk< common_options, &common_options::trust_no_ >;
+ _cli_common_options_map_["--git-capabilities"] =
+ &::bpkg::cli::thunk< common_options, git_capabilities_map, &common_options::git_capabilities_,
+ &common_options::git_capabilities_specified_ >;
+ _cli_common_options_map_["--pager"] =
+ &::bpkg::cli::thunk< common_options, string, &common_options::pager_,
+ &common_options::pager_specified_ >;
+ _cli_common_options_map_["--pager-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::pager_option_,
+ &common_options::pager_option_specified_ >;
+ _cli_common_options_map_["--options-file"] =
+ &::bpkg::cli::thunk< common_options, string, &common_options::options_file_,
+ &common_options::options_file_specified_ >;
+ _cli_common_options_map_["--default-options"] =
+ &::bpkg::cli::thunk< common_options, dir_path, &common_options::default_options_,
+ &common_options::default_options_specified_ >;
+ _cli_common_options_map_["--no-default-options"] =
+ &::bpkg::cli::thunk< common_options, &common_options::no_default_options_ >;
+ _cli_common_options_map_["--keep-tmp"] =
+ &::bpkg::cli::thunk< common_options, &common_options::keep_tmp_ >;
+ }
+ };
+
+ static _cli_common_options_map_init _cli_common_options_map_init_;
+
+ bool common_options::
+ _parse (const char* o, ::bpkg::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 bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_common_options_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg\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[1mbpkg\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 = ::bpkg::common_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::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;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+
+ ::bpkg::cli::usage_para
+ print_bpkg_common_options_long_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg\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[1mbpkg\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 = ::bpkg::common_options::print_long_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::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;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/common-options.hxx b/bpkg/common-options.hxx
new file mode 100644
index 0000000..0df9871
--- /dev/null
+++ b/bpkg/common-options.hxx
@@ -0,0 +1,1235 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_COMMON_OPTIONS_HXX
+#define BPKG_COMMON_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// 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 bpkg
+{
+ 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 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 () noexcept;
+
+ unknown_option (const std::string& option);
+
+ const std::string&
+ option () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const noexcept;
+
+ private:
+ std::string option_;
+ };
+
+ class unknown_argument: public exception
+ {
+ public:
+ virtual
+ ~unknown_argument () noexcept;
+
+ unknown_argument (const std::string& argument);
+
+ const std::string&
+ argument () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const noexcept;
+
+ private:
+ std::string argument_;
+ };
+
+ class missing_value: public exception
+ {
+ public:
+ virtual
+ ~missing_value () noexcept;
+
+ missing_value (const std::string& option);
+
+ const std::string&
+ option () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const noexcept;
+
+ private:
+ std::string option_;
+ };
+
+ class invalid_value: public exception
+ {
+ public:
+ virtual
+ ~invalid_value () noexcept;
+
+ 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 noexcept;
+
+ 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 noexcept;
+ };
+
+ class file_io_failure: public exception
+ {
+ public:
+ virtual
+ ~file_io_failure () noexcept;
+
+ file_io_failure (const std::string& file);
+
+ const std::string&
+ file () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const noexcept;
+
+ private:
+ std::string file_;
+ };
+
+ class unmatched_quote: public exception
+ {
+ public:
+ virtual
+ ~unmatched_quote () noexcept;
+
+ unmatched_quote (const std::string& argument);
+
+ const std::string&
+ argument () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const noexcept;
+
+ private:
+ std::string argument_;
+ };
+
+ class unexpected_group: public exception
+ {
+ public:
+ virtual
+ ~unexpected_group () noexcept;
+
+ unexpected_group (const std::string& argument,
+ const std::string& group);
+
+ const std::string&
+ argument () const;
+
+ const std::string&
+ group () const;
+
+ virtual void
+ print (std::ostream&) const;
+
+ virtual const char*
+ what () const noexcept;
+
+ private:
+ std::string argument_;
+ std::string group_;
+ };
+
+ class group_separator: public exception
+ {
+ public:
+ virtual
+ ~group_separator () noexcept;
+
+ // Note: either (but not both) can be empty.
+ //
+ group_separator (const std::string& encountered,
+ const std::string& expected);
+
+ const std::string&
+ encountered () const;
+
+ const std::string&
+ expected () const;
+
+ virtual void
+ print (std::ostream&) const;
+
+ virtual const char*
+ what () const noexcept;
+
+ private:
+ std::string encountered_;
+ std::string expected_;
+ };
+
+ // 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_;
+ };
+
+ class 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_;
+ };
+
+ class group_scanner: public scanner
+ {
+ public:
+ group_scanner (scanner&);
+
+ virtual bool
+ more ();
+
+ virtual const char*
+ peek ();
+
+ virtual const char*
+ next ();
+
+ virtual void
+ skip ();
+
+ virtual std::size_t
+ position ();
+
+ // The group is only available after the call to next()
+ // (and skip() -- in case one needs to make sure the group
+ // was empty, or some such) and is only valid (and must be
+ // handled) until the next call to any of the scanner
+ // functions (including more()).
+ //
+ // Note also that argument positions within each group start
+ // from 0.
+ //
+ scanner&
+ group ();
+
+ // Escape an argument that is a group separator. Return the
+ // passed string if no escaping is required.
+ //
+ static const char*
+ escape (const char*);
+
+ private:
+ enum state
+ {
+ peeked, // Argument peeked at with peek().
+ scanned, // Argument scanned with next().
+ skipped, // Argument skipped with skip()/initial.
+ };
+
+ enum separator
+ {
+ none,
+ open, // {
+ close, // }
+ open_plus, // +{
+ close_plus // }+
+ };
+
+ static separator
+ sense (const char*);
+
+ // Scan the leading groups, the next argument/argument pack,
+ // and the trailing groups.
+ //
+ void
+ scan_group ();
+
+ scanner& scan_;
+ state state_;
+
+ // Circular buffer of two arguments.
+ //
+ std::vector<std::string> arg_[2];
+ std::size_t i_, j_, pos_;
+
+ std::vector<std::string> group_;
+ vector_scanner group_scan_;
+ };
+
+ template <typename X>
+ struct parser;
+ }
+}
+
+#include <set>
+
+#include <bpkg/types.hxx>
+
+#include <bpkg/options-types.hxx>
+
+namespace bpkg
+{
+ class common_options
+ {
+ public:
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const common_options&);
+
+ // Option accessors and modifiers.
+ //
+ const bool&
+ v () const;
+
+ bool&
+ v ();
+
+ void
+ v (const bool&);
+
+ const bool&
+ V () const;
+
+ bool&
+ V ();
+
+ void
+ V (const bool&);
+
+ const bool&
+ quiet () const;
+
+ bool&
+ quiet ();
+
+ void
+ quiet (const bool&);
+
+ const uint16_t&
+ verbose () const;
+
+ uint16_t&
+ verbose ();
+
+ void
+ verbose (const uint16_t&);
+
+ bool
+ verbose_specified () const;
+
+ void
+ verbose_specified (bool);
+
+ const bpkg::stdout_format&
+ stdout_format () const;
+
+ bpkg::stdout_format&
+ stdout_format ();
+
+ void
+ stdout_format (const bpkg::stdout_format&);
+
+ bool
+ stdout_format_specified () const;
+
+ void
+ stdout_format_specified (bool);
+
+ const size_t&
+ jobs () const;
+
+ size_t&
+ jobs ();
+
+ void
+ jobs (const size_t&);
+
+ bool
+ jobs_specified () const;
+
+ void
+ jobs_specified (bool);
+
+ const bool&
+ no_result () const;
+
+ bool&
+ no_result ();
+
+ void
+ no_result (const bool&);
+
+ const string&
+ structured_result () const;
+
+ string&
+ structured_result ();
+
+ void
+ structured_result (const string&);
+
+ bool
+ structured_result_specified () const;
+
+ void
+ structured_result_specified (bool);
+
+ const bool&
+ progress () const;
+
+ bool&
+ progress ();
+
+ void
+ progress (const bool&);
+
+ const bool&
+ no_progress () const;
+
+ bool&
+ no_progress ();
+
+ void
+ no_progress (const bool&);
+
+ const bool&
+ diag_color () const;
+
+ bool&
+ diag_color ();
+
+ void
+ diag_color (const bool&);
+
+ const bool&
+ no_diag_color () const;
+
+ bool&
+ no_diag_color ();
+
+ void
+ no_diag_color (const bool&);
+
+ const path&
+ build () const;
+
+ path&
+ build ();
+
+ void
+ build (const path&);
+
+ bool
+ build_specified () const;
+
+ void
+ build_specified (bool);
+
+ const strings&
+ build_option () const;
+
+ strings&
+ build_option ();
+
+ void
+ build_option (const strings&);
+
+ bool
+ build_option_specified () const;
+
+ void
+ build_option_specified (bool);
+
+ const path&
+ fetch () const;
+
+ path&
+ fetch ();
+
+ void
+ fetch (const path&);
+
+ bool
+ fetch_specified () const;
+
+ void
+ fetch_specified (bool);
+
+ const strings&
+ fetch_option () const;
+
+ strings&
+ fetch_option ();
+
+ void
+ fetch_option (const strings&);
+
+ bool
+ fetch_option_specified () const;
+
+ void
+ fetch_option_specified (bool);
+
+ const path&
+ curl () const;
+
+ path&
+ curl ();
+
+ void
+ curl (const path&);
+
+ bool
+ curl_specified () const;
+
+ void
+ curl_specified (bool);
+
+ const strings&
+ curl_option () const;
+
+ strings&
+ curl_option ();
+
+ void
+ curl_option (const strings&);
+
+ bool
+ curl_option_specified () const;
+
+ void
+ curl_option_specified (bool);
+
+ const size_t&
+ fetch_timeout () const;
+
+ size_t&
+ fetch_timeout ();
+
+ void
+ fetch_timeout (const size_t&);
+
+ bool
+ fetch_timeout_specified () const;
+
+ void
+ fetch_timeout_specified (bool);
+
+ const butl::url&
+ pkg_proxy () const;
+
+ butl::url&
+ pkg_proxy ();
+
+ void
+ pkg_proxy (const butl::url&);
+
+ bool
+ pkg_proxy_specified () const;
+
+ void
+ pkg_proxy_specified (bool);
+
+ const path&
+ git () const;
+
+ path&
+ git ();
+
+ void
+ git (const path&);
+
+ bool
+ git_specified () const;
+
+ void
+ git_specified (bool);
+
+ const strings&
+ git_option () const;
+
+ strings&
+ git_option ();
+
+ void
+ git_option (const strings&);
+
+ bool
+ git_option_specified () const;
+
+ void
+ git_option_specified (bool);
+
+ const path&
+ sha256 () const;
+
+ path&
+ sha256 ();
+
+ void
+ sha256 (const path&);
+
+ bool
+ sha256_specified () const;
+
+ void
+ sha256_specified (bool);
+
+ const strings&
+ sha256_option () const;
+
+ strings&
+ sha256_option ();
+
+ void
+ sha256_option (const strings&);
+
+ bool
+ sha256_option_specified () const;
+
+ void
+ sha256_option_specified (bool);
+
+ const path&
+ tar () const;
+
+ path&
+ tar ();
+
+ void
+ tar (const path&);
+
+ bool
+ tar_specified () const;
+
+ void
+ tar_specified (bool);
+
+ const strings&
+ tar_option () const;
+
+ strings&
+ tar_option ();
+
+ void
+ tar_option (const strings&);
+
+ bool
+ tar_option_specified () const;
+
+ void
+ tar_option_specified (bool);
+
+ const qualified_option<openssl_commands, path>&
+ openssl () const;
+
+ qualified_option<openssl_commands, path>&
+ openssl ();
+
+ void
+ openssl (const qualified_option<openssl_commands, path>&);
+
+ bool
+ openssl_specified () const;
+
+ void
+ openssl_specified (bool);
+
+ const qualified_option<openssl_commands, strings>&
+ openssl_option () const;
+
+ qualified_option<openssl_commands, strings>&
+ openssl_option ();
+
+ void
+ openssl_option (const qualified_option<openssl_commands, strings>&);
+
+ bool
+ openssl_option_specified () const;
+
+ void
+ openssl_option_specified (bool);
+
+ const bpkg::auth&
+ auth () const;
+
+ bpkg::auth&
+ auth ();
+
+ void
+ auth (const bpkg::auth&);
+
+ bool
+ auth_specified () const;
+
+ void
+ auth_specified (bool);
+
+ const std::set<string, icase_compare_string>&
+ trust () const;
+
+ std::set<string, icase_compare_string>&
+ trust ();
+
+ void
+ trust (const std::set<string, icase_compare_string>&);
+
+ bool
+ trust_specified () const;
+
+ void
+ trust_specified (bool);
+
+ const bool&
+ trust_yes () const;
+
+ bool&
+ trust_yes ();
+
+ void
+ trust_yes (const bool&);
+
+ const bool&
+ trust_no () const;
+
+ bool&
+ trust_no ();
+
+ void
+ trust_no (const bool&);
+
+ const git_capabilities_map&
+ git_capabilities () const;
+
+ git_capabilities_map&
+ git_capabilities ();
+
+ void
+ git_capabilities (const git_capabilities_map&);
+
+ bool
+ git_capabilities_specified () const;
+
+ void
+ git_capabilities_specified (bool);
+
+ const string&
+ pager () const;
+
+ string&
+ pager ();
+
+ void
+ pager (const string&);
+
+ bool
+ pager_specified () const;
+
+ void
+ pager_specified (bool);
+
+ const strings&
+ pager_option () const;
+
+ strings&
+ pager_option ();
+
+ void
+ pager_option (const strings&);
+
+ bool
+ pager_option_specified () const;
+
+ void
+ pager_option_specified (bool);
+
+ const string&
+ options_file () const;
+
+ string&
+ options_file ();
+
+ void
+ options_file (const string&);
+
+ bool
+ options_file_specified () const;
+
+ void
+ options_file_specified (bool);
+
+ const dir_path&
+ default_options () const;
+
+ dir_path&
+ default_options ();
+
+ void
+ default_options (const dir_path&);
+
+ bool
+ default_options_specified () const;
+
+ void
+ default_options_specified (bool);
+
+ const bool&
+ no_default_options () const;
+
+ bool&
+ no_default_options ();
+
+ void
+ no_default_options (const bool&);
+
+ const bool&
+ keep_tmp () const;
+
+ bool&
+ keep_tmp ();
+
+ void
+ keep_tmp (const bool&);
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ static ::bpkg::cli::usage_para
+ print_long_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ common_options ();
+
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ public:
+ bool v_;
+ bool V_;
+ bool quiet_;
+ uint16_t verbose_;
+ bool verbose_specified_;
+ bpkg::stdout_format stdout_format_;
+ bool stdout_format_specified_;
+ size_t jobs_;
+ bool jobs_specified_;
+ bool no_result_;
+ string structured_result_;
+ bool structured_result_specified_;
+ bool progress_;
+ bool no_progress_;
+ bool diag_color_;
+ bool no_diag_color_;
+ path build_;
+ bool build_specified_;
+ strings build_option_;
+ bool build_option_specified_;
+ path fetch_;
+ bool fetch_specified_;
+ strings fetch_option_;
+ bool fetch_option_specified_;
+ path curl_;
+ bool curl_specified_;
+ strings curl_option_;
+ bool curl_option_specified_;
+ size_t fetch_timeout_;
+ bool fetch_timeout_specified_;
+ butl::url pkg_proxy_;
+ bool pkg_proxy_specified_;
+ path git_;
+ bool git_specified_;
+ strings git_option_;
+ bool git_option_specified_;
+ path sha256_;
+ bool sha256_specified_;
+ strings sha256_option_;
+ bool sha256_option_specified_;
+ path tar_;
+ bool tar_specified_;
+ strings tar_option_;
+ bool tar_option_specified_;
+ qualified_option<openssl_commands, path> openssl_;
+ bool openssl_specified_;
+ qualified_option<openssl_commands, strings> openssl_option_;
+ bool openssl_option_specified_;
+ bpkg::auth auth_;
+ bool auth_specified_;
+ std::set<string, icase_compare_string> trust_;
+ bool trust_specified_;
+ bool trust_yes_;
+ bool trust_no_;
+ git_capabilities_map git_capabilities_;
+ bool git_capabilities_specified_;
+ string pager_;
+ bool pager_specified_;
+ strings pager_option_;
+ bool pager_option_specified_;
+ string options_file_;
+ bool options_file_specified_;
+ dir_path default_options_;
+ bool default_options_specified_;
+ bool no_default_options_;
+ bool keep_tmp_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_common_options_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ ::bpkg::cli::usage_para
+ print_bpkg_common_options_long_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/common-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_COMMON_OPTIONS_HXX
diff --git a/bpkg/common-options.ixx b/bpkg/common-options.ixx
new file mode 100644
index 0000000..ed27ac3
--- /dev/null
+++ b/bpkg/common-options.ixx
@@ -0,0 +1,1436 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <cassert>
+
+namespace bpkg
+{
+ 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_;
+ }
+
+ // unexpected_group
+ //
+ inline unexpected_group::
+ unexpected_group (const std::string& argument,
+ const std::string& group)
+ : argument_ (argument), group_ (group)
+ {
+ }
+
+ inline const std::string& unexpected_group::
+ argument () const
+ {
+ return argument_;
+ }
+
+ inline const std::string& unexpected_group::
+ group () const
+ {
+ return group_;
+ }
+
+ // group_separator
+ //
+ inline group_separator::
+ group_separator (const std::string& encountered,
+ const std::string& expected)
+ : encountered_ (encountered), expected_ (expected)
+ {
+ }
+
+ inline const std::string& group_separator::
+ encountered () const
+ {
+ return encountered_;
+ }
+
+ inline const std::string& group_separator::
+ expected () const
+ {
+ return expected_;
+ }
+
+ // 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);
+ }
+
+ // group_scanner
+ //
+ inline group_scanner::
+ group_scanner (scanner& s)
+ : scan_ (s), state_ (skipped), i_ (1), j_ (0), group_scan_ (group_)
+ {
+ }
+
+ inline scanner& group_scanner::
+ group ()
+ {
+ assert (state_ == scanned || state_ == skipped);
+ return group_scan_;
+ }
+
+ inline const char* group_scanner::
+ escape (const char* a)
+ {
+ switch (sense (a))
+ {
+ case separator::none: break;
+ case separator::open: return "\\{";
+ case separator::close: return "\\}";
+ case separator::open_plus: return "\\+{";
+ case separator::close_plus: return "\\}+";
+ }
+
+ return a;
+ }
+
+ inline group_scanner::separator group_scanner::
+ sense (const char* s)
+ {
+ switch (s[0])
+ {
+ case '{': return s[1] == '\0' ? open : none;
+ case '}':
+ {
+ switch (s[1])
+ {
+ case '+': return s[2] == '\0' ? close_plus : none;
+ default: return s[1] == '\0' ? close : none;
+ }
+ }
+ case '+':
+ {
+ switch (s[1])
+ {
+ case '{': return s[2] == '\0' ? open_plus : none;
+ default: return none;
+ }
+ }
+ }
+
+ return none;
+ }
+ }
+}
+
+namespace bpkg
+{
+ // common_options
+ //
+
+ inline const bool& common_options::
+ v () const
+ {
+ return this->v_;
+ }
+
+ inline bool& common_options::
+ v ()
+ {
+ return this->v_;
+ }
+
+ inline void common_options::
+ v (const bool& x)
+ {
+ this->v_ = x;
+ }
+
+ inline const bool& common_options::
+ V () const
+ {
+ return this->V_;
+ }
+
+ inline bool& common_options::
+ V ()
+ {
+ return this->V_;
+ }
+
+ inline void common_options::
+ V (const bool& x)
+ {
+ this->V_ = x;
+ }
+
+ inline const bool& common_options::
+ quiet () const
+ {
+ return this->quiet_;
+ }
+
+ inline bool& common_options::
+ quiet ()
+ {
+ return this->quiet_;
+ }
+
+ inline void common_options::
+ quiet (const bool& x)
+ {
+ this->quiet_ = x;
+ }
+
+ inline const uint16_t& common_options::
+ verbose () const
+ {
+ return this->verbose_;
+ }
+
+ inline uint16_t& common_options::
+ verbose ()
+ {
+ return this->verbose_;
+ }
+
+ inline void common_options::
+ verbose (const uint16_t& x)
+ {
+ this->verbose_ = x;
+ }
+
+ inline bool common_options::
+ verbose_specified () const
+ {
+ return this->verbose_specified_;
+ }
+
+ inline void common_options::
+ verbose_specified (bool x)
+ {
+ this->verbose_specified_ = x;
+ }
+
+ inline const bpkg::stdout_format& common_options::
+ stdout_format () const
+ {
+ return this->stdout_format_;
+ }
+
+ inline bpkg::stdout_format& common_options::
+ stdout_format ()
+ {
+ return this->stdout_format_;
+ }
+
+ inline void common_options::
+ stdout_format (const bpkg::stdout_format& x)
+ {
+ this->stdout_format_ = x;
+ }
+
+ inline bool common_options::
+ stdout_format_specified () const
+ {
+ return this->stdout_format_specified_;
+ }
+
+ inline void common_options::
+ stdout_format_specified (bool x)
+ {
+ this->stdout_format_specified_ = x;
+ }
+
+ inline const size_t& common_options::
+ jobs () const
+ {
+ return this->jobs_;
+ }
+
+ inline size_t& common_options::
+ jobs ()
+ {
+ return this->jobs_;
+ }
+
+ inline void common_options::
+ jobs (const size_t& x)
+ {
+ this->jobs_ = x;
+ }
+
+ inline bool common_options::
+ jobs_specified () const
+ {
+ return this->jobs_specified_;
+ }
+
+ inline void common_options::
+ jobs_specified (bool x)
+ {
+ this->jobs_specified_ = x;
+ }
+
+ inline const bool& common_options::
+ no_result () const
+ {
+ return this->no_result_;
+ }
+
+ inline bool& common_options::
+ no_result ()
+ {
+ return this->no_result_;
+ }
+
+ inline void common_options::
+ no_result (const bool& x)
+ {
+ this->no_result_ = x;
+ }
+
+ inline const string& common_options::
+ structured_result () const
+ {
+ return this->structured_result_;
+ }
+
+ inline string& common_options::
+ structured_result ()
+ {
+ return this->structured_result_;
+ }
+
+ inline void common_options::
+ structured_result (const string& x)
+ {
+ this->structured_result_ = x;
+ }
+
+ inline bool common_options::
+ structured_result_specified () const
+ {
+ return this->structured_result_specified_;
+ }
+
+ inline void common_options::
+ structured_result_specified (bool x)
+ {
+ this->structured_result_specified_ = x;
+ }
+
+ inline const bool& common_options::
+ progress () const
+ {
+ return this->progress_;
+ }
+
+ inline bool& common_options::
+ progress ()
+ {
+ return this->progress_;
+ }
+
+ inline void common_options::
+ progress (const bool& x)
+ {
+ this->progress_ = x;
+ }
+
+ inline const bool& common_options::
+ no_progress () const
+ {
+ return this->no_progress_;
+ }
+
+ inline bool& common_options::
+ no_progress ()
+ {
+ return this->no_progress_;
+ }
+
+ inline void common_options::
+ no_progress (const bool& x)
+ {
+ this->no_progress_ = x;
+ }
+
+ inline const bool& common_options::
+ diag_color () const
+ {
+ return this->diag_color_;
+ }
+
+ inline bool& common_options::
+ diag_color ()
+ {
+ return this->diag_color_;
+ }
+
+ inline void common_options::
+ diag_color (const bool& x)
+ {
+ this->diag_color_ = x;
+ }
+
+ inline const bool& common_options::
+ no_diag_color () const
+ {
+ return this->no_diag_color_;
+ }
+
+ inline bool& common_options::
+ no_diag_color ()
+ {
+ return this->no_diag_color_;
+ }
+
+ inline void common_options::
+ no_diag_color (const bool& x)
+ {
+ this->no_diag_color_ = x;
+ }
+
+ inline const path& common_options::
+ build () const
+ {
+ return this->build_;
+ }
+
+ inline path& common_options::
+ build ()
+ {
+ return this->build_;
+ }
+
+ inline void common_options::
+ build (const path& x)
+ {
+ this->build_ = x;
+ }
+
+ inline bool common_options::
+ build_specified () const
+ {
+ return this->build_specified_;
+ }
+
+ inline void common_options::
+ build_specified (bool x)
+ {
+ this->build_specified_ = x;
+ }
+
+ inline const strings& common_options::
+ build_option () const
+ {
+ return this->build_option_;
+ }
+
+ inline strings& common_options::
+ build_option ()
+ {
+ return this->build_option_;
+ }
+
+ inline void common_options::
+ build_option (const strings& x)
+ {
+ this->build_option_ = x;
+ }
+
+ inline bool common_options::
+ build_option_specified () const
+ {
+ return this->build_option_specified_;
+ }
+
+ inline void common_options::
+ build_option_specified (bool x)
+ {
+ this->build_option_specified_ = x;
+ }
+
+ inline const path& common_options::
+ fetch () const
+ {
+ return this->fetch_;
+ }
+
+ inline path& common_options::
+ fetch ()
+ {
+ return this->fetch_;
+ }
+
+ inline void common_options::
+ fetch (const path& x)
+ {
+ this->fetch_ = x;
+ }
+
+ inline bool common_options::
+ fetch_specified () const
+ {
+ return this->fetch_specified_;
+ }
+
+ inline void common_options::
+ fetch_specified (bool x)
+ {
+ this->fetch_specified_ = x;
+ }
+
+ inline const strings& common_options::
+ fetch_option () const
+ {
+ return this->fetch_option_;
+ }
+
+ inline strings& common_options::
+ fetch_option ()
+ {
+ return this->fetch_option_;
+ }
+
+ inline void common_options::
+ fetch_option (const strings& x)
+ {
+ this->fetch_option_ = x;
+ }
+
+ inline bool common_options::
+ fetch_option_specified () const
+ {
+ return this->fetch_option_specified_;
+ }
+
+ inline void common_options::
+ fetch_option_specified (bool x)
+ {
+ this->fetch_option_specified_ = x;
+ }
+
+ inline const path& common_options::
+ curl () const
+ {
+ return this->curl_;
+ }
+
+ inline path& common_options::
+ curl ()
+ {
+ return this->curl_;
+ }
+
+ inline void common_options::
+ curl (const path& x)
+ {
+ this->curl_ = x;
+ }
+
+ inline bool common_options::
+ curl_specified () const
+ {
+ return this->curl_specified_;
+ }
+
+ inline void common_options::
+ curl_specified (bool x)
+ {
+ this->curl_specified_ = x;
+ }
+
+ inline const strings& common_options::
+ curl_option () const
+ {
+ return this->curl_option_;
+ }
+
+ inline strings& common_options::
+ curl_option ()
+ {
+ return this->curl_option_;
+ }
+
+ inline void common_options::
+ curl_option (const strings& x)
+ {
+ this->curl_option_ = x;
+ }
+
+ inline bool common_options::
+ curl_option_specified () const
+ {
+ return this->curl_option_specified_;
+ }
+
+ inline void common_options::
+ curl_option_specified (bool x)
+ {
+ this->curl_option_specified_ = x;
+ }
+
+ inline const size_t& common_options::
+ fetch_timeout () const
+ {
+ return this->fetch_timeout_;
+ }
+
+ inline size_t& common_options::
+ fetch_timeout ()
+ {
+ return this->fetch_timeout_;
+ }
+
+ inline void common_options::
+ fetch_timeout (const size_t& x)
+ {
+ this->fetch_timeout_ = x;
+ }
+
+ inline bool common_options::
+ fetch_timeout_specified () const
+ {
+ return this->fetch_timeout_specified_;
+ }
+
+ inline void common_options::
+ fetch_timeout_specified (bool x)
+ {
+ this->fetch_timeout_specified_ = x;
+ }
+
+ inline const butl::url& common_options::
+ pkg_proxy () const
+ {
+ return this->pkg_proxy_;
+ }
+
+ inline butl::url& common_options::
+ pkg_proxy ()
+ {
+ return this->pkg_proxy_;
+ }
+
+ inline void common_options::
+ pkg_proxy (const butl::url& x)
+ {
+ this->pkg_proxy_ = x;
+ }
+
+ inline bool common_options::
+ pkg_proxy_specified () const
+ {
+ return this->pkg_proxy_specified_;
+ }
+
+ inline void common_options::
+ pkg_proxy_specified (bool x)
+ {
+ this->pkg_proxy_specified_ = x;
+ }
+
+ inline const path& common_options::
+ git () const
+ {
+ return this->git_;
+ }
+
+ inline path& common_options::
+ git ()
+ {
+ return this->git_;
+ }
+
+ inline void common_options::
+ git (const path& x)
+ {
+ this->git_ = x;
+ }
+
+ inline bool common_options::
+ git_specified () const
+ {
+ return this->git_specified_;
+ }
+
+ inline void common_options::
+ git_specified (bool x)
+ {
+ this->git_specified_ = x;
+ }
+
+ inline const strings& common_options::
+ git_option () const
+ {
+ return this->git_option_;
+ }
+
+ inline strings& common_options::
+ git_option ()
+ {
+ return this->git_option_;
+ }
+
+ inline void common_options::
+ git_option (const strings& x)
+ {
+ this->git_option_ = x;
+ }
+
+ inline bool common_options::
+ git_option_specified () const
+ {
+ return this->git_option_specified_;
+ }
+
+ inline void common_options::
+ git_option_specified (bool x)
+ {
+ this->git_option_specified_ = x;
+ }
+
+ inline const path& common_options::
+ sha256 () const
+ {
+ return this->sha256_;
+ }
+
+ inline path& common_options::
+ sha256 ()
+ {
+ return this->sha256_;
+ }
+
+ inline void common_options::
+ sha256 (const path& x)
+ {
+ this->sha256_ = x;
+ }
+
+ inline bool common_options::
+ sha256_specified () const
+ {
+ return this->sha256_specified_;
+ }
+
+ inline void common_options::
+ sha256_specified (bool x)
+ {
+ this->sha256_specified_ = x;
+ }
+
+ inline const strings& common_options::
+ sha256_option () const
+ {
+ return this->sha256_option_;
+ }
+
+ inline strings& common_options::
+ sha256_option ()
+ {
+ return this->sha256_option_;
+ }
+
+ inline void common_options::
+ sha256_option (const strings& x)
+ {
+ this->sha256_option_ = x;
+ }
+
+ inline bool common_options::
+ sha256_option_specified () const
+ {
+ return this->sha256_option_specified_;
+ }
+
+ inline void common_options::
+ sha256_option_specified (bool x)
+ {
+ this->sha256_option_specified_ = x;
+ }
+
+ inline const path& common_options::
+ tar () const
+ {
+ return this->tar_;
+ }
+
+ inline path& common_options::
+ tar ()
+ {
+ return this->tar_;
+ }
+
+ inline void common_options::
+ tar (const path& x)
+ {
+ this->tar_ = x;
+ }
+
+ inline bool common_options::
+ tar_specified () const
+ {
+ return this->tar_specified_;
+ }
+
+ inline void common_options::
+ tar_specified (bool x)
+ {
+ this->tar_specified_ = x;
+ }
+
+ inline const strings& common_options::
+ tar_option () const
+ {
+ return this->tar_option_;
+ }
+
+ inline strings& common_options::
+ tar_option ()
+ {
+ return this->tar_option_;
+ }
+
+ inline void common_options::
+ tar_option (const strings& x)
+ {
+ this->tar_option_ = x;
+ }
+
+ inline bool common_options::
+ tar_option_specified () const
+ {
+ return this->tar_option_specified_;
+ }
+
+ inline void common_options::
+ tar_option_specified (bool x)
+ {
+ this->tar_option_specified_ = x;
+ }
+
+ inline const qualified_option<openssl_commands, path>& common_options::
+ openssl () const
+ {
+ return this->openssl_;
+ }
+
+ inline qualified_option<openssl_commands, path>& common_options::
+ openssl ()
+ {
+ return this->openssl_;
+ }
+
+ inline void common_options::
+ openssl (const qualified_option<openssl_commands, path>& x)
+ {
+ this->openssl_ = x;
+ }
+
+ inline bool common_options::
+ openssl_specified () const
+ {
+ return this->openssl_specified_;
+ }
+
+ inline void common_options::
+ openssl_specified (bool x)
+ {
+ this->openssl_specified_ = x;
+ }
+
+ inline const qualified_option<openssl_commands, strings>& common_options::
+ openssl_option () const
+ {
+ return this->openssl_option_;
+ }
+
+ inline qualified_option<openssl_commands, strings>& common_options::
+ openssl_option ()
+ {
+ return this->openssl_option_;
+ }
+
+ inline void common_options::
+ openssl_option (const qualified_option<openssl_commands, strings>& x)
+ {
+ this->openssl_option_ = x;
+ }
+
+ inline bool common_options::
+ openssl_option_specified () const
+ {
+ return this->openssl_option_specified_;
+ }
+
+ inline void common_options::
+ openssl_option_specified (bool x)
+ {
+ this->openssl_option_specified_ = x;
+ }
+
+ inline const bpkg::auth& common_options::
+ auth () const
+ {
+ return this->auth_;
+ }
+
+ inline bpkg::auth& common_options::
+ auth ()
+ {
+ return this->auth_;
+ }
+
+ inline void common_options::
+ auth (const bpkg::auth& x)
+ {
+ this->auth_ = x;
+ }
+
+ inline bool common_options::
+ auth_specified () const
+ {
+ return this->auth_specified_;
+ }
+
+ inline void common_options::
+ auth_specified (bool x)
+ {
+ this->auth_specified_ = x;
+ }
+
+ inline const std::set<string, icase_compare_string>& common_options::
+ trust () const
+ {
+ return this->trust_;
+ }
+
+ inline std::set<string, icase_compare_string>& common_options::
+ trust ()
+ {
+ return this->trust_;
+ }
+
+ inline void common_options::
+ trust (const std::set<string, icase_compare_string>& x)
+ {
+ this->trust_ = x;
+ }
+
+ inline bool common_options::
+ trust_specified () const
+ {
+ return this->trust_specified_;
+ }
+
+ inline void common_options::
+ trust_specified (bool x)
+ {
+ this->trust_specified_ = x;
+ }
+
+ inline const bool& common_options::
+ trust_yes () const
+ {
+ return this->trust_yes_;
+ }
+
+ inline bool& common_options::
+ trust_yes ()
+ {
+ return this->trust_yes_;
+ }
+
+ inline void common_options::
+ trust_yes (const bool& x)
+ {
+ this->trust_yes_ = x;
+ }
+
+ inline const bool& common_options::
+ trust_no () const
+ {
+ return this->trust_no_;
+ }
+
+ inline bool& common_options::
+ trust_no ()
+ {
+ return this->trust_no_;
+ }
+
+ inline void common_options::
+ trust_no (const bool& x)
+ {
+ this->trust_no_ = x;
+ }
+
+ inline const git_capabilities_map& common_options::
+ git_capabilities () const
+ {
+ return this->git_capabilities_;
+ }
+
+ inline git_capabilities_map& common_options::
+ git_capabilities ()
+ {
+ return this->git_capabilities_;
+ }
+
+ inline void common_options::
+ git_capabilities (const git_capabilities_map& x)
+ {
+ this->git_capabilities_ = x;
+ }
+
+ inline bool common_options::
+ git_capabilities_specified () const
+ {
+ return this->git_capabilities_specified_;
+ }
+
+ inline void common_options::
+ git_capabilities_specified (bool x)
+ {
+ this->git_capabilities_specified_ = x;
+ }
+
+ inline const string& common_options::
+ pager () const
+ {
+ return this->pager_;
+ }
+
+ inline string& common_options::
+ pager ()
+ {
+ return this->pager_;
+ }
+
+ inline void common_options::
+ pager (const string& x)
+ {
+ this->pager_ = x;
+ }
+
+ inline bool common_options::
+ pager_specified () const
+ {
+ return this->pager_specified_;
+ }
+
+ inline void common_options::
+ pager_specified (bool x)
+ {
+ this->pager_specified_ = x;
+ }
+
+ inline const strings& common_options::
+ pager_option () const
+ {
+ return this->pager_option_;
+ }
+
+ inline strings& common_options::
+ pager_option ()
+ {
+ return this->pager_option_;
+ }
+
+ inline void common_options::
+ pager_option (const strings& x)
+ {
+ this->pager_option_ = x;
+ }
+
+ inline bool common_options::
+ pager_option_specified () const
+ {
+ return this->pager_option_specified_;
+ }
+
+ inline void common_options::
+ pager_option_specified (bool x)
+ {
+ this->pager_option_specified_ = x;
+ }
+
+ inline const string& common_options::
+ options_file () const
+ {
+ return this->options_file_;
+ }
+
+ inline string& common_options::
+ options_file ()
+ {
+ return this->options_file_;
+ }
+
+ inline void common_options::
+ options_file (const string& x)
+ {
+ this->options_file_ = x;
+ }
+
+ inline bool common_options::
+ options_file_specified () const
+ {
+ return this->options_file_specified_;
+ }
+
+ inline void common_options::
+ options_file_specified (bool x)
+ {
+ this->options_file_specified_ = x;
+ }
+
+ inline const dir_path& common_options::
+ default_options () const
+ {
+ return this->default_options_;
+ }
+
+ inline dir_path& common_options::
+ default_options ()
+ {
+ return this->default_options_;
+ }
+
+ inline void common_options::
+ default_options (const dir_path& x)
+ {
+ this->default_options_ = x;
+ }
+
+ inline bool common_options::
+ default_options_specified () const
+ {
+ return this->default_options_specified_;
+ }
+
+ inline void common_options::
+ default_options_specified (bool x)
+ {
+ this->default_options_specified_ = x;
+ }
+
+ inline const bool& common_options::
+ no_default_options () const
+ {
+ return this->no_default_options_;
+ }
+
+ inline bool& common_options::
+ no_default_options ()
+ {
+ return this->no_default_options_;
+ }
+
+ inline void common_options::
+ no_default_options (const bool& x)
+ {
+ this->no_default_options_ = x;
+ }
+
+ inline const bool& common_options::
+ keep_tmp () const
+ {
+ return this->keep_tmp_;
+ }
+
+ inline bool& common_options::
+ keep_tmp ()
+ {
+ return this->keep_tmp_;
+ }
+
+ inline void common_options::
+ keep_tmp (const bool& x)
+ {
+ this->keep_tmp_ = x;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/configuration-options.cxx b/bpkg/configuration-options.cxx
new file mode 100644
index 0000000..9790132
--- /dev/null
+++ b/bpkg/configuration-options.cxx
@@ -0,0 +1,653 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // configuration_options
+ //
+
+ configuration_options::
+ configuration_options ()
+ : directory_ ("."),
+ directory_specified_ (false)
+ {
+ }
+
+ bool configuration_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool configuration_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool configuration_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool configuration_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool configuration_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void configuration_options::
+ merge (const configuration_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+
+ if (a.directory_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->directory_, a.directory_);
+ this->directory_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para configuration_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1m--directory\033[0m|\033[1m-d\033[0m \033[4mdir\033[0m Assume configuration is in \033[4mdir\033[0m rather than in the" << ::std::endl
+ << " current working directory." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (configuration_options&, ::bpkg::cli::scanner&)>
+ _cli_configuration_options_map;
+
+ static _cli_configuration_options_map _cli_configuration_options_map_;
+
+ struct _cli_configuration_options_map_init
+ {
+ _cli_configuration_options_map_init ()
+ {
+ _cli_configuration_options_map_["--directory"] =
+ &::bpkg::cli::thunk< configuration_options, dir_path, &configuration_options::directory_,
+ &configuration_options::directory_specified_ >;
+ _cli_configuration_options_map_["-d"] =
+ &::bpkg::cli::thunk< configuration_options, dir_path, &configuration_options::directory_,
+ &configuration_options::directory_specified_ >;
+ }
+ };
+
+ static _cli_configuration_options_map_init _cli_configuration_options_map_init_;
+
+ bool configuration_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_configuration_options_map::const_iterator i (_cli_configuration_options_map_.find (o));
+
+ if (i != _cli_configuration_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool configuration_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_configuration_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/configuration-options.hxx b/bpkg/configuration-options.hxx
new file mode 100644
index 0000000..d7a61db
--- /dev/null
+++ b/bpkg/configuration-options.hxx
@@ -0,0 +1,117 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_CONFIGURATION_OPTIONS_HXX
+#define BPKG_CONFIGURATION_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class configuration_options: public ::bpkg::common_options
+ {
+ public:
+ configuration_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const configuration_options&);
+
+ // Option accessors.
+ //
+ const dir_path&
+ directory () const;
+
+ bool
+ directory_specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ dir_path directory_;
+ bool directory_specified_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_configuration_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/configuration-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_CONFIGURATION_OPTIONS_HXX
diff --git a/bpkg/configuration-options.ixx b/bpkg/configuration-options.ixx
new file mode 100644
index 0000000..294a431
--- /dev/null
+++ b/bpkg/configuration-options.ixx
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // configuration_options
+ //
+
+ inline const dir_path& configuration_options::
+ directory () const
+ {
+ return this->directory_;
+ }
+
+ inline bool configuration_options::
+ directory_specified () const
+ {
+ return this->directory_specified_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/default-options-files.cxx b/bpkg/default-options-files.cxx
new file mode 100644
index 0000000..72c5745
--- /dev/null
+++ b/bpkg/default-options-files.cxx
@@ -0,0 +1,91 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/default-options-files.hxx>
+
+#include <map>
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_default_options_files_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg\033[0m \033[4mcommand\033[0m [\033[4mmode-options\033[0m] ...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "Instead of having a separate config file format for tool configuration, the" << ::std::endl
+ << "\033[1mbuild2\033[0m toolchain uses \033[4mdefault options files\033[0m which contain the same options as" << ::std::endl
+ << "what can be specified on the command line. The default options files are like" << ::std::endl
+ << "options files that one can specify with \033[1m--options-file\033[0m (\033[1mbpkg-common-options(1)\033[0m)" << ::std::endl
+ << "except that they are loaded by default." << ::std::endl
+ << ::std::endl
+ << "The default options files are searched for in the \033[1m.build2/\033[0m and \033[1m.build2/local/\033[0m" << ::std::endl
+ << "subdirectories of each outer directory beginning from the \033[4mstart directory\033[0m and" << ::std::endl
+ << "until reaching either the home directory or the filesystem root directory (both" << ::std::endl
+ << "excluding). Then in the \033[1m.build2/\033[0m subdirectory of the home directory and finally" << ::std::endl
+ << "in the system directory (for example, \033[1m/etc/build2/\033[0m) if configured." << ::std::endl
+ << ::std::endl
+ << "Once the search is complete, the files are loaded in the reverse order, that" << ::std::endl
+ << "is, beginning from the system directory (if any), followed by the home" << ::std::endl
+ << "directory, ending with the start directory, and finishing off with the options" << ::std::endl
+ << "specified on the command line. In other words, the files are loaded from the" << ::std::endl
+ << "more generic to the more specific with the command line options having the" << ::std::endl
+ << "ability to override any values specified in the default options files." << ::std::endl
+ << ::std::endl
+ << "The start directory, the names of the default options files, and in which order" << ::std::endl
+ << "they are loaded within each directory are determined by the \033[4mcommand\033[0m and" << ::std::endl
+ << "potentially its \033[4mmode-options\033[0m. See each command's DEFAULT OPTIONS FILES section" << ::std::endl
+ << "for details." << ::std::endl
+ << ::std::endl
+ << "If a default options file contains \033[1m--no-default-options\033[0m, then the search is" << ::std::endl
+ << "stopped at the directory containing this file and no outer files are loaded. If" << ::std::endl
+ << "this option is specified on the command line, then none of the default options" << ::std::endl
+ << "files are searched for or loaded." << ::std::endl
+ << ::std::endl
+ << "An additional directory containing default options files can be specified with" << ::std::endl
+ << "\033[1m--default-options\033[0m. If such a directory is a subdirectory of the start directory" << ::std::endl
+ << "or is between the start directory and the end of the outer search, then its" << ::std::endl
+ << "configuration files are loaded at the corresponding point in the directory" << ::std::endl
+ << "hierarchy. Otherwise, they are loaded after the home directory." << ::std::endl
+ << ::std::endl
+ << "The presence of the \033[1m.git\033[0m filesystem entry causes the default options files in" << ::std::endl
+ << "this directory and any of its subdirectories to be considered remote. Depending" << ::std::endl
+ << "on the command, some security-sensitive options may be disallowed or trigger a" << ::std::endl
+ << "prompt when specified in remote options files (in the current implementation" << ::std::endl
+ << "this is the case even for files from the \033[1m.build2/local/\033[0m subdirectory since the" << ::std::endl
+ << "mere location is not a sufficient ground to definitively conclude that the file" << ::std::endl
+ << "is not remote; to be sure we would need to query the version control system)." << ::std::endl
+ << "Note that additional default options files specified with \033[1m--default-options\033[0m are" << ::std::endl
+ << "never considered remote." << ::std::endl
+ << ::std::endl
+ << "The order in which default options files are loaded is traced at the verbosity" << ::std::endl
+ << "level 3 (\033[1m-V\033[0m option) or higher." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/default-options-files.hxx b/bpkg/default-options-files.hxx
new file mode 100644
index 0000000..a26c600
--- /dev/null
+++ b/bpkg/default-options-files.hxx
@@ -0,0 +1,31 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_DEFAULT_OPTIONS_FILES_HXX
+#define BPKG_DEFAULT_OPTIONS_FILES_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_default_options_files_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_DEFAULT_OPTIONS_FILES_HXX
diff --git a/bpkg/fetch-git.cxx b/bpkg/fetch-git.cxx
index 5d2e5fe..c283626 100644
--- a/bpkg/fetch-git.cxx
+++ b/bpkg/fetch-git.cxx
@@ -119,7 +119,8 @@ namespace bpkg
template <typename O, typename E, typename... A>
static process
- start_git (const common_options& co,
+ start_git (uint16_t verbosity,
+ const common_options& co,
O&& out,
E&& err,
A&&... args)
@@ -162,7 +163,8 @@ namespace bpkg
// We assume that non-sanitized git environment can't harm this call.
//
- process pr (start_git (co,
+ process pr (start_git (2 /* verbosity */,
+ co,
pipe, 2 /* stderr */,
co.git_option (),
"rev-parse",
@@ -231,9 +233,10 @@ namespace bpkg
ep = "--exec-path=" + pp.effect.directory ().string ();
#endif
- return process_start_callback ([] (const char* const args[], size_t n)
+ return process_start_callback ([verbosity] (const char* const args[],
+ size_t n)
{
- if (verb >= 2)
+ if (verb >= verbosity)
print_process (args, n);
},
0 /* stdin */, out, err,
@@ -247,6 +250,16 @@ namespace bpkg
}
}
+ template <typename O, typename E, typename... A>
+ inline static process
+ start_git (const common_options& co,
+ O&& out,
+ E&& err,
+ A&&... args)
+ {
+ return start_git (2 /* verbosity */, co, out, err, forward<A> (args)...);
+ }
+
// Run git process, optionally suppressing progress.
//
template <typename... A>
@@ -2569,7 +2582,8 @@ namespace bpkg
path tp;
fdpipe pipe (open_pipe ());
- process pr (start_git (co,
+ process pr (start_git (3 /* verbosity */,
+ co,
pipe, 2 /* stderr */,
co.git_option (),
"-C", dir,
diff --git a/bpkg/help-options.cxx b/bpkg/help-options.cxx
new file mode 100644
index 0000000..4a7244e
--- /dev/null
+++ b/bpkg/help-options.cxx
@@ -0,0 +1,657 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/help-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // help_options
+ //
+
+ help_options::
+ help_options ()
+ {
+ }
+
+ bool help_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool help_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool help_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool help_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool help_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void help_options::
+ merge (const help_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+ }
+
+ ::bpkg::cli::usage_para help_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (help_options&, ::bpkg::cli::scanner&)>
+ _cli_help_options_map;
+
+ static _cli_help_options_map _cli_help_options_map_;
+
+ struct _cli_help_options_map_init
+ {
+ _cli_help_options_map_init ()
+ {
+ }
+ };
+
+ static _cli_help_options_map_init _cli_help_options_map_init_;
+
+ bool help_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_help_options_map::const_iterator i (_cli_help_options_map_.find (o));
+
+ if (i != _cli_help_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool help_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_help_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg help\033[0m [\033[4mcommand\033[0m | \033[4mtopic\033[0m]\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "Show the detailed help for \033[4mcommand\033[0m or help \033[4mtopic\033[0m or a summary of available" << ::std::endl
+ << "commands and topics if none was specified." << ::std::endl;
+
+ p = ::bpkg::help_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mhelp\033[0m command the following options files are searched for only in the" << ::std::endl
+ << "predefined directories (home, system, etc) and, if found, loaded in the order" << ::std::endl
+ << "listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-help.options" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/help-options.hxx b/bpkg/help-options.hxx
new file mode 100644
index 0000000..9c67dee
--- /dev/null
+++ b/bpkg/help-options.hxx
@@ -0,0 +1,109 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_HELP_OPTIONS_HXX
+#define BPKG_HELP_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class help_options: public ::bpkg::common_options
+ {
+ public:
+ help_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const help_options&);
+
+ // Option accessors.
+ //
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_help_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/help-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_HELP_OPTIONS_HXX
diff --git a/bpkg/help-options.ixx b/bpkg/help-options.ixx
new file mode 100644
index 0000000..91f5bfd
--- /dev/null
+++ b/bpkg/help-options.ixx
@@ -0,0 +1,21 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // help_options
+ //
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/package-odb.cxx b/bpkg/package-odb.cxx
new file mode 100644
index 0000000..aa7e156
--- /dev/null
+++ b/bpkg/package-odb.cxx
@@ -0,0 +1,19100 @@
+// -*- C++ -*-
+//
+// This file was generated by ODB, object-relational mapping (ORM)
+// compiler for C++.
+//
+
+#include <odb/pre.hxx>
+
+#include <bpkg/package-odb.hxx>
+
+#include <cassert>
+#include <cstring> // std::memcpy
+
+#include <odb/schema-catalog-impl.hxx>
+
+#include <odb/sqlite/traits.hxx>
+#include <odb/sqlite/database.hxx>
+#include <odb/sqlite/transaction.hxx>
+#include <odb/sqlite/connection.hxx>
+#include <odb/sqlite/statement.hxx>
+#include <odb/sqlite/statement-cache.hxx>
+#include <odb/sqlite/simple-object-statements.hxx>
+#include <odb/sqlite/view-statements.hxx>
+#include <odb/sqlite/section-statements.hxx>
+#include <odb/sqlite/container-statements.hxx>
+#include <odb/sqlite/exceptions.hxx>
+#include <odb/sqlite/prepared-query.hxx>
+#include <odb/sqlite/simple-object-result.hxx>
+#include <odb/sqlite/view-result.hxx>
+
+namespace odb
+{
+ // _version
+ //
+
+ bool access::composite_value_traits< ::bpkg::_version, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // epoch
+ //
+ t[0UL] = false;
+
+ // canonical_upstream
+ //
+ if (t[1UL])
+ {
+ i.canonical_upstream_value.capacity (i.canonical_upstream_size);
+ grew = true;
+ }
+
+ // canonical_release
+ //
+ if (t[2UL])
+ {
+ i.canonical_release_value.capacity (i.canonical_release_size);
+ grew = true;
+ }
+
+ // revision
+ //
+ t[3UL] = false;
+
+ // iteration
+ //
+ t[4UL] = false;
+
+ // upstream
+ //
+ if (t[5UL])
+ {
+ i.upstream_value.capacity (i.upstream_size);
+ grew = true;
+ }
+
+ // release
+ //
+ if (t[6UL])
+ {
+ i.release_value.capacity (i.release_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::_version, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // epoch
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.epoch_value;
+ b[n].is_null = &i.epoch_null;
+ n++;
+
+ // canonical_upstream
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.canonical_upstream_value.data ();
+ b[n].size = &i.canonical_upstream_size;
+ b[n].capacity = i.canonical_upstream_value.capacity ();
+ b[n].is_null = &i.canonical_upstream_null;
+ n++;
+
+ // canonical_release
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.canonical_release_value.data ();
+ b[n].size = &i.canonical_release_size;
+ b[n].capacity = i.canonical_release_value.capacity ();
+ b[n].is_null = &i.canonical_release_null;
+ n++;
+
+ // revision
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.revision_value;
+ b[n].is_null = &i.revision_null;
+ n++;
+
+ // iteration
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.iteration_value;
+ b[n].is_null = &i.iteration_null;
+ n++;
+
+ // upstream
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.upstream_value.data ();
+ b[n].size = &i.upstream_size;
+ b[n].capacity = i.upstream_value.capacity ();
+ b[n].is_null = &i.upstream_null;
+ n++;
+
+ // release
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.release_value.data ();
+ b[n].size = &i.release_size;
+ b[n].capacity = i.release_value.capacity ();
+ b[n].is_null = &i.release_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::_version, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // epoch
+ //
+ {
+ ::uint16_t const& v =
+ o.epoch;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::uint16_t,
+ sqlite::id_integer >::set_image (
+ i.epoch_value,
+ is_null,
+ v);
+ i.epoch_null = is_null;
+ }
+
+ // canonical_upstream
+ //
+ {
+ ::std::string const& v =
+ o.canonical_upstream;
+
+ bool is_null (false);
+ std::size_t cap (i.canonical_upstream_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.canonical_upstream_value,
+ i.canonical_upstream_size,
+ is_null,
+ v);
+ i.canonical_upstream_null = is_null;
+ grew = grew || (cap != i.canonical_upstream_value.capacity ());
+ }
+
+ // canonical_release
+ //
+ {
+ ::std::string const& v =
+ o.canonical_release;
+
+ bool is_null (false);
+ std::size_t cap (i.canonical_release_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.canonical_release_value,
+ i.canonical_release_size,
+ is_null,
+ v);
+ i.canonical_release_null = is_null;
+ grew = grew || (cap != i.canonical_release_value.capacity ());
+ }
+
+ // revision
+ //
+ {
+ ::butl::optional< short unsigned int > const& v =
+ o.revision;
+
+ bool is_null (true);
+ sqlite::value_traits<
+ ::butl::optional< short unsigned int >,
+ sqlite::id_integer >::set_image (
+ i.revision_value,
+ is_null,
+ v);
+ i.revision_null = is_null;
+ }
+
+ // iteration
+ //
+ {
+ ::uint32_t const& v =
+ o.iteration;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::uint32_t,
+ sqlite::id_integer >::set_image (
+ i.iteration_value,
+ is_null,
+ v);
+ i.iteration_null = is_null;
+ }
+
+ // upstream
+ //
+ {
+ ::std::string const& v =
+ o.upstream;
+
+ bool is_null (false);
+ std::size_t cap (i.upstream_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.upstream_value,
+ i.upstream_size,
+ is_null,
+ v);
+ i.upstream_null = is_null;
+ grew = grew || (cap != i.upstream_value.capacity ());
+ }
+
+ // release
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.release;
+
+ bool is_null (true);
+ std::size_t cap (i.release_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.release_value,
+ i.release_size,
+ is_null,
+ v);
+ i.release_null = is_null;
+ grew = grew || (cap != i.release_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::_version, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // epoch
+ //
+ {
+ ::uint16_t& v =
+ o.epoch;
+
+ sqlite::value_traits<
+ ::uint16_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.epoch_value,
+ i.epoch_null);
+ }
+
+ // canonical_upstream
+ //
+ {
+ ::std::string& v =
+ o.canonical_upstream;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.canonical_upstream_value,
+ i.canonical_upstream_size,
+ i.canonical_upstream_null);
+ }
+
+ // canonical_release
+ //
+ {
+ ::std::string& v =
+ o.canonical_release;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.canonical_release_value,
+ i.canonical_release_size,
+ i.canonical_release_null);
+ }
+
+ // revision
+ //
+ {
+ ::butl::optional< short unsigned int >& v =
+ o.revision;
+
+ sqlite::value_traits<
+ ::butl::optional< short unsigned int >,
+ sqlite::id_integer >::set_value (
+ v,
+ i.revision_value,
+ i.revision_null);
+ }
+
+ // iteration
+ //
+ {
+ ::uint32_t& v =
+ o.iteration;
+
+ sqlite::value_traits<
+ ::uint32_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.iteration_value,
+ i.iteration_null);
+ }
+
+ // upstream
+ //
+ {
+ ::std::string& v =
+ o.upstream;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.upstream_value,
+ i.upstream_size,
+ i.upstream_null);
+ }
+
+ // release
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.release;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.release_value,
+ i.release_size,
+ i.release_null);
+ }
+ }
+
+ // language
+ //
+
+ bool access::composite_value_traits< ::bpkg::language, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // name
+ //
+ if (t[0UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // impl
+ //
+ t[1UL] = false;
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::language, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // name
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.name_value.data ();
+ b[n].size = &i.name_size;
+ b[n].capacity = i.name_value.capacity ();
+ b[n].is_null = &i.name_null;
+ n++;
+
+ // impl
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.impl_value;
+ b[n].is_null = &i.impl_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::language, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // name
+ //
+ {
+ ::std::string const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.name_value,
+ i.name_size,
+ is_null,
+ v);
+ i.name_null = is_null;
+ grew = grew || (cap != i.name_value.capacity ());
+ }
+
+ // impl
+ //
+ {
+ bool const& v =
+ o.impl;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.impl_value,
+ is_null,
+ v);
+ i.impl_null = is_null;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::language, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // name
+ //
+ {
+ ::std::string& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // impl
+ //
+ {
+ bool& v =
+ o.impl;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.impl_value,
+ i.impl_null);
+ }
+ }
+
+ // version_constraint
+ //
+
+ bool access::composite_value_traits< ::bpkg::version_constraint, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // min_version
+ //
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::grow (
+ i.min_version_value, t + 0UL))
+ grew = true;
+
+ // max_version
+ //
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::grow (
+ i.max_version_value, t + 7UL))
+ grew = true;
+
+ // min_open
+ //
+ t[14UL] = false;
+
+ // max_open
+ //
+ t[15UL] = false;
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::version_constraint, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // min_version
+ //
+ composite_value_traits< ::bpkg::_version, id_sqlite >::bind (
+ b + n, i.min_version_value, sk);
+ n += 7UL;
+
+ // max_version
+ //
+ composite_value_traits< ::bpkg::_version, id_sqlite >::bind (
+ b + n, i.max_version_value, sk);
+ n += 7UL;
+
+ // min_open
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.min_open_value;
+ b[n].is_null = &i.min_open_null;
+ n++;
+
+ // max_open
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.max_open_value;
+ b[n].is_null = &i.max_open_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::version_constraint, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // min_version
+ //
+ {
+ ::butl::optional< ::bpkg::version > const& v =
+ o.min_version;
+
+ // From package.hxx:325:14
+ ::bpkg::_optional_version const& vt =
+ (v) ? bpkg::_version
+ {
+ (v)->epoch, (v)->canonical_upstream, (v)->canonical_release, (v)->revision, (v)->iteration, (v)->upstream, (v)->release
+ } : bpkg::_optional_version ();
+
+ if (wrapper_traits< ::bpkg::_optional_version >::get_null (vt))
+ composite_value_traits< ::bpkg::_version, id_sqlite >::set_null (
+ i.min_version_value, sk);
+ else
+ {
+ const::bpkg::_version& vw =
+ wrapper_traits< ::bpkg::_optional_version >::get_ref (vt);
+
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ i.min_version_value,
+ vw,
+ sk))
+ grew = true;
+ }
+ }
+
+ // max_version
+ //
+ {
+ ::butl::optional< ::bpkg::version > const& v =
+ o.max_version;
+
+ // From package.hxx:325:14
+ ::bpkg::_optional_version const& vt =
+ (v) ? bpkg::_version
+ {
+ (v)->epoch, (v)->canonical_upstream, (v)->canonical_release, (v)->revision, (v)->iteration, (v)->upstream, (v)->release
+ } : bpkg::_optional_version ();
+
+ if (wrapper_traits< ::bpkg::_optional_version >::get_null (vt))
+ composite_value_traits< ::bpkg::_version, id_sqlite >::set_null (
+ i.max_version_value, sk);
+ else
+ {
+ const::bpkg::_version& vw =
+ wrapper_traits< ::bpkg::_optional_version >::get_ref (vt);
+
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ i.max_version_value,
+ vw,
+ sk))
+ grew = true;
+ }
+ }
+
+ // min_open
+ //
+ {
+ bool const& v =
+ o.min_open;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.min_open_value,
+ is_null,
+ v);
+ i.min_open_null = is_null;
+ }
+
+ // max_open
+ //
+ {
+ bool const& v =
+ o.max_open;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.max_open_value,
+ is_null,
+ v);
+ i.max_open_null = is_null;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::version_constraint, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // min_version
+ //
+ {
+ ::butl::optional< ::bpkg::version >& v =
+ o.min_version;
+
+ ::bpkg::_optional_version vt;
+
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::get_null (
+ i.min_version_value))
+ wrapper_traits< ::bpkg::_optional_version >::set_null (vt);
+ else
+ {
+ ::bpkg::_version& vw =
+ wrapper_traits< ::bpkg::_optional_version >::set_ref (vt);
+
+ composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ vw,
+ i.min_version_value,
+ db);
+ }
+
+ // From package.hxx:325:14
+ v = (vt) ? bpkg::version ((vt)->epoch, std::move ((vt)->upstream), std::move ((vt)->release), (vt)->revision, (vt)->iteration) : bpkg::optional_version ();
+ }
+
+ // max_version
+ //
+ {
+ ::butl::optional< ::bpkg::version >& v =
+ o.max_version;
+
+ ::bpkg::_optional_version vt;
+
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::get_null (
+ i.max_version_value))
+ wrapper_traits< ::bpkg::_optional_version >::set_null (vt);
+ else
+ {
+ ::bpkg::_version& vw =
+ wrapper_traits< ::bpkg::_optional_version >::set_ref (vt);
+
+ composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ vw,
+ i.max_version_value,
+ db);
+ }
+
+ // From package.hxx:325:14
+ v = (vt) ? bpkg::version ((vt)->epoch, std::move ((vt)->upstream), std::move ((vt)->release), (vt)->revision, (vt)->iteration) : bpkg::optional_version ();
+ }
+
+ // min_open
+ //
+ {
+ bool& v =
+ o.min_open;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.min_open_value,
+ i.min_open_null);
+ }
+
+ // max_open
+ //
+ {
+ bool& v =
+ o.max_open;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.max_open_value,
+ i.max_open_null);
+ }
+ }
+
+ // dependency
+ //
+
+ bool access::composite_value_traits< ::bpkg::dependency, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // name
+ //
+ if (t[0UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // constraint
+ //
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::grow (
+ i.constraint_value, t + 1UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // name
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::package_name,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.name_value.data ();
+ b[n].size = &i.name_size;
+ b[n].capacity = i.name_value.capacity ();
+ b[n].is_null = &i.name_null;
+ n++;
+
+ // constraint
+ //
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::bind (
+ b + n, i.constraint_value, sk);
+ n += 16UL;
+ }
+
+ bool access::composite_value_traits< ::bpkg::dependency, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // name
+ //
+ {
+ ::bpkg::package_name const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_image (
+ i.name_value,
+ i.name_size,
+ is_null,
+ v);
+ i.name_null = is_null;
+ grew = grew || (cap != i.name_value.capacity ());
+ }
+
+ // constraint
+ //
+ {
+ ::butl::optional< ::bpkg::version_constraint > const& v =
+ o.constraint;
+
+ if (wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::get_null (v))
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::set_null (
+ i.constraint_value, sk);
+ else
+ {
+ const::bpkg::version_constraint& vw =
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::get_ref (v);
+
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::init (
+ i.constraint_value,
+ vw,
+ sk))
+ grew = true;
+ }
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // name
+ //
+ {
+ ::bpkg::package_name& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // constraint
+ //
+ {
+ ::butl::optional< ::bpkg::version_constraint >& v =
+ o.constraint;
+
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::get_null (
+ i.constraint_value))
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::set_null (v);
+ else
+ {
+ ::bpkg::version_constraint& vw =
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::set_ref (v);
+
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::init (
+ vw,
+ i.constraint_value,
+ db);
+ }
+ }
+ }
+
+ // dependency_alternative
+ //
+
+ bool access::composite_value_traits< ::bpkg::dependency_alternative, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // enable
+ //
+ if (t[0UL])
+ {
+ i.enable_value.capacity (i.enable_size);
+ grew = true;
+ }
+
+ // reflect
+ //
+ if (t[1UL])
+ {
+ i.reflect_value.capacity (i.reflect_size);
+ grew = true;
+ }
+
+ // prefer
+ //
+ if (t[2UL])
+ {
+ i.prefer_value.capacity (i.prefer_size);
+ grew = true;
+ }
+
+ // accept
+ //
+ if (t[3UL])
+ {
+ i.accept_value.capacity (i.accept_size);
+ grew = true;
+ }
+
+ // require
+ //
+ if (t[4UL])
+ {
+ i.require_value.capacity (i.require_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency_alternative, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // enable
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.enable_value.data ();
+ b[n].size = &i.enable_size;
+ b[n].capacity = i.enable_value.capacity ();
+ b[n].is_null = &i.enable_null;
+ n++;
+
+ // reflect
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.reflect_value.data ();
+ b[n].size = &i.reflect_size;
+ b[n].capacity = i.reflect_value.capacity ();
+ b[n].is_null = &i.reflect_null;
+ n++;
+
+ // prefer
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.prefer_value.data ();
+ b[n].size = &i.prefer_size;
+ b[n].capacity = i.prefer_value.capacity ();
+ b[n].is_null = &i.prefer_null;
+ n++;
+
+ // accept
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.accept_value.data ();
+ b[n].size = &i.accept_size;
+ b[n].capacity = i.accept_value.capacity ();
+ b[n].is_null = &i.accept_null;
+ n++;
+
+ // require
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.require_value.data ();
+ b[n].size = &i.require_size;
+ b[n].capacity = i.require_value.capacity ();
+ b[n].is_null = &i.require_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::dependency_alternative, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // enable
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.enable;
+
+ bool is_null (true);
+ std::size_t cap (i.enable_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.enable_value,
+ i.enable_size,
+ is_null,
+ v);
+ i.enable_null = is_null;
+ grew = grew || (cap != i.enable_value.capacity ());
+ }
+
+ // reflect
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.reflect;
+
+ bool is_null (true);
+ std::size_t cap (i.reflect_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.reflect_value,
+ i.reflect_size,
+ is_null,
+ v);
+ i.reflect_null = is_null;
+ grew = grew || (cap != i.reflect_value.capacity ());
+ }
+
+ // prefer
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.prefer;
+
+ bool is_null (true);
+ std::size_t cap (i.prefer_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.prefer_value,
+ i.prefer_size,
+ is_null,
+ v);
+ i.prefer_null = is_null;
+ grew = grew || (cap != i.prefer_value.capacity ());
+ }
+
+ // accept
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.accept;
+
+ bool is_null (true);
+ std::size_t cap (i.accept_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.accept_value,
+ i.accept_size,
+ is_null,
+ v);
+ i.accept_null = is_null;
+ grew = grew || (cap != i.accept_value.capacity ());
+ }
+
+ // require
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.require;
+
+ bool is_null (true);
+ std::size_t cap (i.require_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.require_value,
+ i.require_size,
+ is_null,
+ v);
+ i.require_null = is_null;
+ grew = grew || (cap != i.require_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency_alternative, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // enable
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.enable;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.enable_value,
+ i.enable_size,
+ i.enable_null);
+ }
+
+ // reflect
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.reflect;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.reflect_value,
+ i.reflect_size,
+ i.reflect_null);
+ }
+
+ // prefer
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.prefer;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.prefer_value,
+ i.prefer_size,
+ i.prefer_null);
+ }
+
+ // accept
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.accept;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.accept_value,
+ i.accept_size,
+ i.accept_null);
+ }
+
+ // require
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.require;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.require_value,
+ i.require_size,
+ i.require_null);
+ }
+ }
+
+ // dependency_alternatives
+ //
+
+ bool access::composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // buildtime
+ //
+ t[0UL] = false;
+
+ // comment
+ //
+ if (t[1UL])
+ {
+ i.comment_value.capacity (i.comment_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // buildtime
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.buildtime_value;
+ b[n].is_null = &i.buildtime_null;
+ n++;
+
+ // comment
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.comment_value.data ();
+ b[n].size = &i.comment_size;
+ b[n].capacity = i.comment_value.capacity ();
+ b[n].is_null = &i.comment_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // buildtime
+ //
+ {
+ bool const& v =
+ o.buildtime;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.buildtime_value,
+ is_null,
+ v);
+ i.buildtime_null = is_null;
+ }
+
+ // comment
+ //
+ {
+ ::std::string const& v =
+ o.comment;
+
+ bool is_null (false);
+ std::size_t cap (i.comment_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.comment_value,
+ i.comment_size,
+ is_null,
+ v);
+ i.comment_null = is_null;
+ grew = grew || (cap != i.comment_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // buildtime
+ //
+ {
+ bool& v =
+ o.buildtime;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.buildtime_value,
+ i.buildtime_null);
+ }
+
+ // comment
+ //
+ {
+ ::std::string& v =
+ o.comment;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.comment_value,
+ i.comment_size,
+ i.comment_null);
+ }
+ }
+
+ // test_dependency
+ //
+
+ bool access::composite_value_traits< ::bpkg::test_dependency, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // dependency base
+ //
+ if (composite_value_traits< ::bpkg::dependency, id_sqlite >::grow (
+ i, t + 0UL))
+ grew = true;
+
+ // type
+ //
+ if (t[17UL])
+ {
+ i.type_value.capacity (i.type_size);
+ grew = true;
+ }
+
+ // buildtime
+ //
+ t[18UL] = false;
+
+ // enable
+ //
+ if (t[19UL])
+ {
+ i.enable_value.capacity (i.enable_size);
+ grew = true;
+ }
+
+ // reflect
+ //
+ if (t[20UL])
+ {
+ i.reflect_value.capacity (i.reflect_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::test_dependency, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // dependency base
+ //
+ composite_value_traits< ::bpkg::dependency, id_sqlite >::bind (b + n, i, sk);
+ n += 17UL;
+
+ // type
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.type_value.data ();
+ b[n].size = &i.type_size;
+ b[n].capacity = i.type_value.capacity ();
+ b[n].is_null = &i.type_null;
+ n++;
+
+ // buildtime
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.buildtime_value;
+ b[n].is_null = &i.buildtime_null;
+ n++;
+
+ // enable
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.enable_value.data ();
+ b[n].size = &i.enable_size;
+ b[n].capacity = i.enable_value.capacity ();
+ b[n].is_null = &i.enable_null;
+ n++;
+
+ // reflect
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.reflect_value.data ();
+ b[n].size = &i.reflect_size;
+ b[n].capacity = i.reflect_value.capacity ();
+ b[n].is_null = &i.reflect_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::test_dependency, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // dependency base
+ //
+ if (composite_value_traits< ::bpkg::dependency, id_sqlite >::init (i, o, sk))
+ grew = true;
+
+ // type
+ //
+ {
+ ::bpkg::test_dependency_type const& v =
+ o.type;
+
+ // From package.hxx:629:14
+ ::std::string const& vt =
+ to_string (v);
+
+ bool is_null (false);
+ std::size_t cap (i.type_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.type_value,
+ i.type_size,
+ is_null,
+ vt);
+ i.type_null = is_null;
+ grew = grew || (cap != i.type_value.capacity ());
+ }
+
+ // buildtime
+ //
+ {
+ bool const& v =
+ o.buildtime;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.buildtime_value,
+ is_null,
+ v);
+ i.buildtime_null = is_null;
+ }
+
+ // enable
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.enable;
+
+ bool is_null (true);
+ std::size_t cap (i.enable_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.enable_value,
+ i.enable_size,
+ is_null,
+ v);
+ i.enable_null = is_null;
+ grew = grew || (cap != i.enable_value.capacity ());
+ }
+
+ // reflect
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.reflect;
+
+ bool is_null (true);
+ std::size_t cap (i.reflect_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.reflect_value,
+ i.reflect_size,
+ is_null,
+ v);
+ i.reflect_null = is_null;
+ grew = grew || (cap != i.reflect_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::test_dependency, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // dependency base
+ //
+ composite_value_traits< ::bpkg::dependency, id_sqlite >::init (o, i, db);
+
+ // type
+ //
+ {
+ ::bpkg::test_dependency_type& v =
+ o.type;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.type_value,
+ i.type_size,
+ i.type_null);
+
+ // From package.hxx:629:14
+ v = bpkg::to_test_dependency_type (vt);
+ }
+
+ // buildtime
+ //
+ {
+ bool& v =
+ o.buildtime;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.buildtime_value,
+ i.buildtime_null);
+ }
+
+ // enable
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.enable;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.enable_value,
+ i.enable_size,
+ i.enable_null);
+ }
+
+ // reflect
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.reflect;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.reflect_value,
+ i.reflect_size,
+ i.reflect_null);
+ }
+ }
+
+ // buildfile
+ //
+
+ bool access::composite_value_traits< ::bpkg::buildfile, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // path
+ //
+ if (t[0UL])
+ {
+ i.path_value.capacity (i.path_size);
+ grew = true;
+ }
+
+ // content
+ //
+ if (t[1UL])
+ {
+ i.content_value.capacity (i.content_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::buildfile, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // path
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.path_value.data ();
+ b[n].size = &i.path_size;
+ b[n].capacity = i.path_value.capacity ();
+ b[n].is_null = &i.path_null;
+ n++;
+
+ // content
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.content_value.data ();
+ b[n].size = &i.content_size;
+ b[n].capacity = i.content_value.capacity ();
+ b[n].is_null = &i.content_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::buildfile, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // path
+ //
+ {
+ ::butl::path const& v =
+ o.path;
+
+ // From package.hxx:50:14
+ ::std::string const& vt =
+ (v).representation ();
+
+ bool is_null (false);
+ std::size_t cap (i.path_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.path_value,
+ i.path_size,
+ is_null,
+ vt);
+ i.path_null = is_null;
+ grew = grew || (cap != i.path_value.capacity ());
+ }
+
+ // content
+ //
+ {
+ ::std::string const& v =
+ o.content;
+
+ bool is_null (false);
+ std::size_t cap (i.content_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.content_value,
+ i.content_size,
+ is_null,
+ v);
+ i.content_null = is_null;
+ grew = grew || (cap != i.content_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::buildfile, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // path
+ //
+ {
+ ::butl::path& v =
+ o.path;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.path_value,
+ i.path_size,
+ i.path_null);
+
+ // From package.hxx:50:14
+ v = bpkg::path (vt);
+ }
+
+ // content
+ //
+ {
+ ::std::string& v =
+ o.content;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.content_value,
+ i.content_size,
+ i.content_null);
+ }
+ }
+
+ // distribution_name_value
+ //
+
+ bool access::composite_value_traits< ::bpkg::distribution_name_value, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // name
+ //
+ if (t[0UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // value
+ //
+ if (t[1UL])
+ {
+ i.value_value.capacity (i.value_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::distribution_name_value, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // name
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.name_value.data ();
+ b[n].size = &i.name_size;
+ b[n].capacity = i.name_value.capacity ();
+ b[n].is_null = &i.name_null;
+ n++;
+
+ // value
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.value_value.data ();
+ b[n].size = &i.value_size;
+ b[n].capacity = i.value_value.capacity ();
+ b[n].is_null = &i.value_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::distribution_name_value, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // name
+ //
+ {
+ ::std::string const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.name_value,
+ i.name_size,
+ is_null,
+ v);
+ i.name_null = is_null;
+ grew = grew || (cap != i.name_value.capacity ());
+ }
+
+ // value
+ //
+ {
+ ::std::string const& v =
+ o.value;
+
+ bool is_null (false);
+ std::size_t cap (i.value_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.value_value,
+ i.value_size,
+ is_null,
+ v);
+ i.value_null = is_null;
+ grew = grew || (cap != i.value_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::distribution_name_value, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // name
+ //
+ {
+ ::std::string& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // value
+ //
+ {
+ ::std::string& v =
+ o.value;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.value_value,
+ i.value_size,
+ i.value_null);
+ }
+ }
+
+ // configuration
+ //
+
+ struct access::object_traits_impl< ::bpkg::configuration, id_sqlite >::extra_statement_cache_type
+ {
+ extra_statement_cache_type (
+ sqlite::connection&,
+ image_type&,
+ id_image_type&,
+ sqlite::binding&,
+ sqlite::binding&)
+ {
+ }
+ };
+
+ access::object_traits_impl< ::bpkg::configuration, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ id (const id_image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ sqlite::value_traits<
+ ::bpkg::optional_uint64_t,
+ sqlite::id_integer >::set_value (
+ id,
+ i.id_value,
+ i.id_null);
+ }
+
+ return id;
+ }
+
+ access::object_traits_impl< ::bpkg::configuration, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ id (const image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ sqlite::value_traits<
+ ::bpkg::optional_uint64_t,
+ sqlite::id_integer >::set_value (
+ id,
+ i.id_value,
+ i.id_null);
+ }
+
+ return id;
+ }
+
+ bool access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // id
+ //
+ t[0UL] = false;
+
+ // uuid
+ //
+ if (t[1UL])
+ {
+ i.uuid_value.capacity (i.uuid_size);
+ grew = true;
+ }
+
+ // name
+ //
+ if (t[2UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // type
+ //
+ if (t[3UL])
+ {
+ i.type_value.capacity (i.type_size);
+ grew = true;
+ }
+
+ // path
+ //
+ if (t[4UL])
+ {
+ i.path_value.capacity (i.path_size);
+ grew = true;
+ }
+
+ // expl
+ //
+ t[5UL] = false;
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+
+ // id
+ //
+ if (sk != statement_update)
+ {
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.id_value;
+ b[n].is_null = &i.id_null;
+ n++;
+ }
+
+ // uuid
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.uuid_value.data ();
+ b[n].size = &i.uuid_size;
+ b[n].capacity = i.uuid_value.capacity ();
+ b[n].is_null = &i.uuid_null;
+ n++;
+
+ // name
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.name_value.data ();
+ b[n].size = &i.name_size;
+ b[n].capacity = i.name_value.capacity ();
+ b[n].is_null = &i.name_null;
+ n++;
+
+ // type
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.type_value.data ();
+ b[n].size = &i.type_size;
+ b[n].capacity = i.type_value.capacity ();
+ b[n].is_null = &i.type_null;
+ n++;
+
+ // path
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.path_value.data ();
+ b[n].size = &i.path_size;
+ b[n].capacity = i.path_value.capacity ();
+ b[n].is_null = &i.path_null;
+ n++;
+
+ // expl
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.expl_value;
+ b[n].is_null = &i.expl_null;
+ n++;
+ }
+
+ void access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ bind (sqlite::bind* b, id_image_type& i)
+ {
+ std::size_t n (0);
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.id_value;
+ b[n].is_null = &i.id_null;
+ }
+
+ bool access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ init (image_type& i,
+ const object_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // id
+ //
+ if (sk == statement_insert)
+ {
+ ::bpkg::optional_uint64_t const& v =
+ o.id;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::bpkg::optional_uint64_t,
+ sqlite::id_integer >::set_image (
+ i.id_value,
+ is_null,
+ v);
+ i.id_null = is_null;
+ }
+
+ // uuid
+ //
+ {
+ ::bpkg::configuration::uuid_type const& v =
+ o.uuid;
+
+ // From package.hxx:66:14
+ ::std::string const& vt =
+ (v).string ();
+
+ bool is_null (false);
+ std::size_t cap (i.uuid_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.uuid_value,
+ i.uuid_size,
+ is_null,
+ vt);
+ i.uuid_null = is_null;
+ grew = grew || (cap != i.uuid_value.capacity ());
+ }
+
+ // name
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.name;
+
+ bool is_null (true);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.name_value,
+ i.name_size,
+ is_null,
+ v);
+ i.name_null = is_null;
+ grew = grew || (cap != i.name_value.capacity ());
+ }
+
+ // type
+ //
+ {
+ ::std::string const& v =
+ o.type;
+
+ bool is_null (false);
+ std::size_t cap (i.type_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.type_value,
+ i.type_size,
+ is_null,
+ v);
+ i.type_null = is_null;
+ grew = grew || (cap != i.type_value.capacity ());
+ }
+
+ // path
+ //
+ {
+ ::butl::dir_path const& v =
+ o.path;
+
+ // From package.hxx:57:14
+ ::std::string const& vt =
+ (v).string ();
+
+ bool is_null (false);
+ std::size_t cap (i.path_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.path_value,
+ i.path_size,
+ is_null,
+ vt);
+ i.path_null = is_null;
+ grew = grew || (cap != i.path_value.capacity ());
+ }
+
+ // expl
+ //
+ {
+ bool const& v =
+ o.expl;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.expl_value,
+ is_null,
+ v);
+ i.expl_null = is_null;
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ init (object_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // id
+ //
+ {
+ ::bpkg::optional_uint64_t& v =
+ o.id;
+
+ sqlite::value_traits<
+ ::bpkg::optional_uint64_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.id_value,
+ i.id_null);
+ }
+
+ // uuid
+ //
+ {
+ ::bpkg::configuration::uuid_type& v =
+ o.uuid;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.uuid_value,
+ i.uuid_size,
+ i.uuid_null);
+
+ // From package.hxx:66:14
+ v = bpkg::uuid (vt);
+ }
+
+ // name
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // type
+ //
+ {
+ ::std::string& v =
+ o.type;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.type_value,
+ i.type_size,
+ i.type_null);
+ }
+
+ // path
+ //
+ {
+ ::butl::dir_path& v =
+ o.path;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.path_value,
+ i.path_size,
+ i.path_null);
+
+ // From package.hxx:57:14
+ v = bpkg::dir_path (vt);
+ }
+
+ // expl
+ //
+ {
+ bool& v =
+ o.expl;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.expl_value,
+ i.expl_null);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ init (id_image_type& i, const id_type& id)
+ {
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ ::bpkg::optional_uint64_t,
+ sqlite::id_integer >::set_image (
+ i.id_value,
+ is_null,
+ id);
+ i.id_null = is_null;
+ }
+ }
+
+ const char access::object_traits_impl< ::bpkg::configuration, id_sqlite >::persist_statement[] =
+ "INSERT INTO \"main\".\"configuration\" "
+ "(\"id\", "
+ "\"uuid\", "
+ "\"name\", "
+ "\"type\", "
+ "\"path\", "
+ "\"explicit\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::configuration, id_sqlite >::find_statement[] =
+ "SELECT "
+ "\"main\".\"configuration\".\"id\", "
+ "\"main\".\"configuration\".\"uuid\", "
+ "\"main\".\"configuration\".\"name\", "
+ "\"main\".\"configuration\".\"type\", "
+ "\"main\".\"configuration\".\"path\", "
+ "\"main\".\"configuration\".\"explicit\" "
+ "FROM \"main\".\"configuration\" "
+ "WHERE \"main\".\"configuration\".\"id\"=?";
+
+ const char access::object_traits_impl< ::bpkg::configuration, id_sqlite >::update_statement[] =
+ "UPDATE \"main\".\"configuration\" "
+ "SET "
+ "\"uuid\"=?, "
+ "\"name\"=?, "
+ "\"type\"=?, "
+ "\"path\"=?, "
+ "\"explicit\"=? "
+ "WHERE \"id\"=?";
+
+ const char access::object_traits_impl< ::bpkg::configuration, id_sqlite >::erase_statement[] =
+ "DELETE FROM \"main\".\"configuration\" "
+ "WHERE \"id\"=?";
+
+ const char access::object_traits_impl< ::bpkg::configuration, id_sqlite >::query_statement[] =
+ "SELECT "
+ "\"main\".\"configuration\".\"id\", "
+ "\"main\".\"configuration\".\"uuid\", "
+ "\"main\".\"configuration\".\"name\", "
+ "\"main\".\"configuration\".\"type\", "
+ "\"main\".\"configuration\".\"path\", "
+ "\"main\".\"configuration\".\"explicit\" "
+ "FROM \"main\".\"configuration\"";
+
+ const char access::object_traits_impl< ::bpkg::configuration, id_sqlite >::erase_query_statement[] =
+ "DELETE FROM \"main\".\"configuration\"";
+
+ const char access::object_traits_impl< ::bpkg::configuration, id_sqlite >::table_name[] =
+ "\"main\".\"configuration\"";
+
+ void access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ persist (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ callback (db,
+ static_cast<const object_type&> (obj),
+ callback_event::pre_persist);
+
+ image_type& im (sts.image ());
+ binding& imb (sts.insert_image_binding ());
+
+ if (init (im, obj, statement_insert))
+ im.version++;
+
+ if (im.version != sts.insert_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_insert);
+ sts.insert_image_version (im.version);
+ imb.version++;
+ }
+
+ {
+ id_image_type& i (sts.id_image ());
+ binding& b (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || b.version == 0)
+ {
+ bind (b.bind, i);
+ sts.id_image_version (i.version);
+ b.version++;
+ }
+ }
+
+ insert_statement& st (sts.persist_statement ());
+ if (!st.execute ())
+ throw object_already_persistent ();
+
+ obj.id = id (sts.id_image ());
+
+ callback (db,
+ static_cast<const object_type&> (obj),
+ callback_event::post_persist);
+ }
+
+ void access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ update (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+ using sqlite::update_statement;
+
+ callback (db, obj, callback_event::pre_update);
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ sqlite::connection& conn (tr.connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& idi (sts.id_image ());
+ init (idi, id (obj));
+
+ image_type& im (sts.image ());
+ if (init (im, obj, statement_update))
+ im.version++;
+
+ bool u (false);
+ binding& imb (sts.update_image_binding ());
+ if (im.version != sts.update_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_update);
+ sts.update_image_version (im.version);
+ imb.version++;
+ u = true;
+ }
+
+ binding& idb (sts.id_image_binding ());
+ if (idi.version != sts.update_id_image_version () ||
+ idb.version == 0)
+ {
+ if (idi.version != sts.id_image_version () ||
+ idb.version == 0)
+ {
+ bind (idb.bind, idi);
+ sts.id_image_version (idi.version);
+ idb.version++;
+ }
+
+ sts.update_id_image_version (idi.version);
+
+ if (!u)
+ imb.version++;
+ }
+
+ update_statement& st (sts.update_statement ());
+ if (st.execute () == 0)
+ throw object_not_persistent ();
+
+ callback (db, obj, callback_event::post_update);
+ pointer_cache_traits::update (db, obj);
+ }
+
+ void access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ erase (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ if (sts.erase_statement ().execute () != 1)
+ throw object_not_persistent ();
+
+ pointer_cache_traits::erase (db, id);
+ }
+
+ access::object_traits_impl< ::bpkg::configuration, id_sqlite >::pointer_type
+ access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ find (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ {
+ pointer_type p (pointer_cache_traits::find (db, id));
+
+ if (!pointer_traits::null_ptr (p))
+ return p;
+ }
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+
+ if (l.locked ())
+ {
+ if (!find_ (sts, &id))
+ return pointer_type ();
+ }
+
+ pointer_type p (
+ access::object_factory<object_type, pointer_type>::create ());
+ pointer_traits::guard pg (p);
+
+ pointer_cache_traits::insert_guard ig (
+ pointer_cache_traits::insert (db, id, p));
+
+ object_type& obj (pointer_traits::get_ref (p));
+
+ if (l.locked ())
+ {
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ pointer_cache_traits::load (ig.position ());
+ }
+ else
+ sts.delay_load (id, obj, ig.position ());
+
+ ig.release ();
+ pg.release ();
+ return p;
+ }
+
+ bool access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ find (database& db, const id_type& id, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ reference_cache_traits::position_type pos (
+ reference_cache_traits::insert (db, id, obj));
+ reference_cache_traits::insert_guard ig (pos);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ reference_cache_traits::load (pos);
+ ig.release ();
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ reload (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ const id_type& id (object_traits_impl::id (obj));
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, true);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ find_ (statements_type& sts,
+ const id_type* id)
+ {
+ using namespace sqlite;
+
+ id_image_type& i (sts.id_image ());
+ init (i, *id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ select_statement& st (sts.find_statement ());
+
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ if (grow (im, sts.select_image_truncated ()))
+ im.version++;
+
+ if (im.version != sts.select_image_version ())
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ result< access::object_traits_impl< ::bpkg::configuration, id_sqlite >::object_type >
+ access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ q.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::object_result_impl<object_type> > r (
+ new (shared) sqlite::object_result_impl<object_type> (
+ q, st, sts, 0));
+
+ return result<object_type> (r);
+ }
+
+ unsigned long long access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ erase_query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ std::string text (erase_query_statement);
+ if (!q.empty ())
+ {
+ text += ' ';
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ delete_statement st (
+ conn,
+ text,
+ q.parameters_binding ());
+
+ return st.execute ();
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = q;
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::object_result_impl<object_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // canonical_version
+ //
+
+ bool access::composite_value_traits< ::bpkg::canonical_version, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // epoch
+ //
+ t[0UL] = false;
+
+ // canonical_upstream
+ //
+ if (t[1UL])
+ {
+ i.canonical_upstream_value.capacity (i.canonical_upstream_size);
+ grew = true;
+ }
+
+ // canonical_release
+ //
+ if (t[2UL])
+ {
+ i.canonical_release_value.capacity (i.canonical_release_size);
+ grew = true;
+ }
+
+ // revision
+ //
+ t[3UL] = false;
+
+ // iteration
+ //
+ t[4UL] = false;
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::canonical_version, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // epoch
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.epoch_value;
+ b[n].is_null = &i.epoch_null;
+ n++;
+
+ // canonical_upstream
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.canonical_upstream_value.data ();
+ b[n].size = &i.canonical_upstream_size;
+ b[n].capacity = i.canonical_upstream_value.capacity ();
+ b[n].is_null = &i.canonical_upstream_null;
+ n++;
+
+ // canonical_release
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.canonical_release_value.data ();
+ b[n].size = &i.canonical_release_size;
+ b[n].capacity = i.canonical_release_value.capacity ();
+ b[n].is_null = &i.canonical_release_null;
+ n++;
+
+ // revision
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.revision_value;
+ b[n].is_null = &i.revision_null;
+ n++;
+
+ // iteration
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.iteration_value;
+ b[n].is_null = &i.iteration_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::canonical_version, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // epoch
+ //
+ {
+ ::uint16_t const& v =
+ o.epoch;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::uint16_t,
+ sqlite::id_integer >::set_image (
+ i.epoch_value,
+ is_null,
+ v);
+ i.epoch_null = is_null;
+ }
+
+ // canonical_upstream
+ //
+ {
+ ::std::string const& v =
+ o.canonical_upstream;
+
+ bool is_null (false);
+ std::size_t cap (i.canonical_upstream_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.canonical_upstream_value,
+ i.canonical_upstream_size,
+ is_null,
+ v);
+ i.canonical_upstream_null = is_null;
+ grew = grew || (cap != i.canonical_upstream_value.capacity ());
+ }
+
+ // canonical_release
+ //
+ {
+ ::std::string const& v =
+ o.canonical_release;
+
+ bool is_null (false);
+ std::size_t cap (i.canonical_release_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.canonical_release_value,
+ i.canonical_release_size,
+ is_null,
+ v);
+ i.canonical_release_null = is_null;
+ grew = grew || (cap != i.canonical_release_value.capacity ());
+ }
+
+ // revision
+ //
+ {
+ ::uint16_t const& v =
+ o.revision;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::uint16_t,
+ sqlite::id_integer >::set_image (
+ i.revision_value,
+ is_null,
+ v);
+ i.revision_null = is_null;
+ }
+
+ // iteration
+ //
+ {
+ ::uint32_t const& v =
+ o.iteration;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::uint32_t,
+ sqlite::id_integer >::set_image (
+ i.iteration_value,
+ is_null,
+ v);
+ i.iteration_null = is_null;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::canonical_version, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // epoch
+ //
+ {
+ ::uint16_t& v =
+ o.epoch;
+
+ sqlite::value_traits<
+ ::uint16_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.epoch_value,
+ i.epoch_null);
+ }
+
+ // canonical_upstream
+ //
+ {
+ ::std::string& v =
+ o.canonical_upstream;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.canonical_upstream_value,
+ i.canonical_upstream_size,
+ i.canonical_upstream_null);
+ }
+
+ // canonical_release
+ //
+ {
+ ::std::string& v =
+ o.canonical_release;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.canonical_release_value,
+ i.canonical_release_size,
+ i.canonical_release_null);
+ }
+
+ // revision
+ //
+ {
+ ::uint16_t& v =
+ o.revision;
+
+ sqlite::value_traits<
+ ::uint16_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.revision_value,
+ i.revision_null);
+ }
+
+ // iteration
+ //
+ {
+ ::uint32_t& v =
+ o.iteration;
+
+ sqlite::value_traits<
+ ::uint32_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.iteration_value,
+ i.iteration_null);
+ }
+ }
+
+ // upstream_version
+ //
+
+ bool access::composite_value_traits< ::bpkg::upstream_version, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // upstream_
+ //
+ if (t[0UL])
+ {
+ i.upstream_value.capacity (i.upstream_size);
+ grew = true;
+ }
+
+ // release_
+ //
+ if (t[1UL])
+ {
+ i.release_value.capacity (i.release_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::upstream_version, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // upstream_
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.upstream_value.data ();
+ b[n].size = &i.upstream_size;
+ b[n].capacity = i.upstream_value.capacity ();
+ b[n].is_null = &i.upstream_null;
+ n++;
+
+ // release_
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.release_value.data ();
+ b[n].size = &i.release_size;
+ b[n].capacity = i.release_value.capacity ();
+ b[n].is_null = &i.release_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::upstream_version, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // upstream_
+ //
+ {
+ // From package.hxx:276:7
+ ::std::string const& v =
+ o.upstream;
+
+ bool is_null (false);
+ std::size_t cap (i.upstream_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.upstream_value,
+ i.upstream_size,
+ is_null,
+ v);
+ i.upstream_null = is_null;
+ grew = grew || (cap != i.upstream_value.capacity ());
+ }
+
+ // release_
+ //
+ {
+ // From package.hxx:281:7
+ ::bpkg::optional_string const& v =
+ o.release;
+
+ bool is_null (true);
+ std::size_t cap (i.release_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_image (
+ i.release_value,
+ i.release_size,
+ is_null,
+ v);
+ i.release_null = is_null;
+ grew = grew || (cap != i.release_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::upstream_version, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // upstream_
+ //
+ {
+ // From package.hxx:277:7
+ ::std::string v;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.upstream_value,
+ i.upstream_size,
+ i.upstream_null);
+
+ // From package.hxx:277:7
+ o = bpkg::version (0, std::move (v), std::string (), bpkg::nullopt, 0);
+ }
+
+ // release_
+ //
+ {
+ // From package.hxx:282:7
+ ::bpkg::optional_string v;
+
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_value (
+ v,
+ i.release_value,
+ i.release_size,
+ i.release_null);
+
+ // From package.hxx:282:7
+ o = bpkg::version (0, std::move (o.upstream), std::move (v), bpkg::nullopt, 0);
+ }
+ }
+
+ // _repository_location
+ //
+
+ bool access::composite_value_traits< ::bpkg::_repository_location, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // url
+ //
+ if (t[0UL])
+ {
+ i.url_value.capacity (i.url_size);
+ grew = true;
+ }
+
+ // type
+ //
+ if (t[1UL])
+ {
+ i.type_value.capacity (i.type_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::_repository_location, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // url
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.url_value.data ();
+ b[n].size = &i.url_size;
+ b[n].capacity = i.url_value.capacity ();
+ b[n].is_null = &i.url_null;
+ n++;
+
+ // type
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.type_value.data ();
+ b[n].size = &i.type_size;
+ b[n].capacity = i.type_value.capacity ();
+ b[n].is_null = &i.type_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::_repository_location, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // url
+ //
+ {
+ ::bpkg::repository_url const& v =
+ o.url;
+
+ // From package.hxx:358:14
+ ::std::string const& vt =
+ (v).string ();
+
+ bool is_null (false);
+ std::size_t cap (i.url_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.url_value,
+ i.url_size,
+ is_null,
+ vt);
+ i.url_null = is_null;
+ grew = grew || (cap != i.url_value.capacity ());
+ }
+
+ // type
+ //
+ {
+ ::bpkg::repository_type const& v =
+ o.type;
+
+ // From package.hxx:362:14
+ ::std::string const& vt =
+ to_string (v);
+
+ bool is_null (false);
+ std::size_t cap (i.type_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.type_value,
+ i.type_size,
+ is_null,
+ vt);
+ i.type_null = is_null;
+ grew = grew || (cap != i.type_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::_repository_location, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // url
+ //
+ {
+ ::bpkg::repository_url& v =
+ o.url;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.url_value,
+ i.url_size,
+ i.url_null);
+
+ // From package.hxx:358:14
+ v = (vt).empty () ? bpkg::repository_url () : bpkg::repository_url (vt);
+ }
+
+ // type
+ //
+ {
+ ::bpkg::repository_type& v =
+ o.type;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.type_value,
+ i.type_size,
+ i.type_null);
+
+ // From package.hxx:362:14
+ v = bpkg::to_repository_type (vt);
+ }
+ }
+
+ // repository_fragment
+ //
+
+ struct access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::extra_statement_cache_type
+ {
+ sqlite::container_statements_impl< complements_traits > complements;
+ sqlite::container_statements_impl< prerequisites_traits > prerequisites;
+
+ extra_statement_cache_type (
+ sqlite::connection& c,
+ image_type&,
+ id_image_type&,
+ sqlite::binding& id,
+ sqlite::binding&)
+ : complements (c, id),
+ prerequisites (c, id)
+ {
+ }
+ };
+
+ // complements
+ //
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"repository_fragment_complements\".\"complement\" "
+ "FROM \"main\".\"repository_fragment_complements\" "
+ "WHERE \"main\".\"repository_fragment_complements\".\"repository_fragment\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"repository_fragment_complements\" "
+ "(\"repository_fragment\", "
+ "\"complement\") "
+ "VALUES "
+ "(?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"repository_fragment_complements\" "
+ "WHERE \"repository_fragment\"=?";
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // value
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = d.value_value.data ();
+ b[n].size = &d.value_size;
+ b[n].capacity = d.value_value.capacity ();
+ b[n].is_null = &d.value_null;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // value
+ //
+ if (t[0UL])
+ {
+ i.value_value.capacity (i.value_size);
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ init (data_image_type& i,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // value
+ //
+ {
+ typedef object_traits< ::bpkg::repository > obj_traits;
+ typedef odb::pointer_traits< value_type > wptr_traits;
+ typedef odb::pointer_traits< wptr_traits::strong_pointer_type > ptr_traits;
+
+ wptr_traits::strong_pointer_type sp (wptr_traits::lock (v));
+ bool is_null (ptr_traits::null_ptr (sp));
+ if (!is_null)
+ {
+ const obj_traits::id_type& ptr_id (
+ ptr_traits::object_id< ptr_traits::element_type > (sp));
+
+ std::size_t cap (i.value_value.capacity ());
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_image (
+ i.value_value,
+ i.value_size,
+ is_null,
+ ptr_id);
+ i.value_null = is_null;
+ grew = grew || (cap != i.value_value.capacity ());
+ }
+ else
+ throw null_pointer ();
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ init (value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // value
+ //
+ {
+ typedef object_traits< ::bpkg::repository > obj_traits;
+ typedef odb::pointer_traits< value_type > ptr_traits;
+
+ if (i.value_null)
+ v = ptr_traits::pointer_type ();
+ else
+ {
+ obj_traits::id_type ptr_id;
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_value (
+ ptr_id,
+ i.value_value,
+ i.value_size,
+ i.value_null);
+
+ v = ptr_traits::pointer_type (
+ *static_cast<sqlite::database*> (db), ptr_id);
+ }
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ insert (const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ select (value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::erase (fs);
+ }
+
+ // prerequisites
+ //
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"repository_fragment_prerequisites\".\"prerequisite\" "
+ "FROM \"main\".\"repository_fragment_prerequisites\" "
+ "WHERE \"main\".\"repository_fragment_prerequisites\".\"repository_fragment\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"repository_fragment_prerequisites\" "
+ "(\"repository_fragment\", "
+ "\"prerequisite\") "
+ "VALUES "
+ "(?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"repository_fragment_prerequisites\" "
+ "WHERE \"repository_fragment\"=?";
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // value
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = d.value_value.data ();
+ b[n].size = &d.value_size;
+ b[n].capacity = d.value_value.capacity ();
+ b[n].is_null = &d.value_null;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // value
+ //
+ if (t[0UL])
+ {
+ i.value_value.capacity (i.value_size);
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ init (data_image_type& i,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // value
+ //
+ {
+ typedef object_traits< ::bpkg::repository > obj_traits;
+ typedef odb::pointer_traits< value_type > wptr_traits;
+ typedef odb::pointer_traits< wptr_traits::strong_pointer_type > ptr_traits;
+
+ wptr_traits::strong_pointer_type sp (wptr_traits::lock (v));
+ bool is_null (ptr_traits::null_ptr (sp));
+ if (!is_null)
+ {
+ const obj_traits::id_type& ptr_id (
+ ptr_traits::object_id< ptr_traits::element_type > (sp));
+
+ std::size_t cap (i.value_value.capacity ());
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_image (
+ i.value_value,
+ i.value_size,
+ is_null,
+ ptr_id);
+ i.value_null = is_null;
+ grew = grew || (cap != i.value_value.capacity ());
+ }
+ else
+ throw null_pointer ();
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ init (value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // value
+ //
+ {
+ typedef object_traits< ::bpkg::repository > obj_traits;
+ typedef odb::pointer_traits< value_type > ptr_traits;
+
+ if (i.value_null)
+ v = ptr_traits::pointer_type ();
+ else
+ {
+ obj_traits::id_type ptr_id;
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_value (
+ ptr_id,
+ i.value_value,
+ i.value_size,
+ i.value_null);
+
+ v = ptr_traits::pointer_type (
+ *static_cast<sqlite::database*> (db), ptr_id);
+ }
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ insert (const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ select (value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::erase (fs);
+ }
+
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ id (const image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ id,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ return id;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // name
+ //
+ if (t[0UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // location
+ //
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::grow (
+ i.location_value, t + 1UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+
+ // name
+ //
+ if (sk != statement_update)
+ {
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.name_value.data ();
+ b[n].size = &i.name_size;
+ b[n].capacity = i.name_value.capacity ();
+ b[n].is_null = &i.name_null;
+ n++;
+ }
+
+ // location
+ //
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::bind (
+ b + n, i.location_value, sk);
+ n += 2UL;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ bind (sqlite::bind* b, id_image_type& i)
+ {
+ std::size_t n (0);
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.id_value.data ();
+ b[n].size = &i.id_size;
+ b[n].capacity = i.id_value.capacity ();
+ b[n].is_null = &i.id_null;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ init (image_type& i,
+ const object_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // name
+ //
+ if (sk == statement_insert)
+ {
+ ::std::string const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.name_value,
+ i.name_size,
+ is_null,
+ v);
+ i.name_null = is_null;
+ grew = grew || (cap != i.name_value.capacity ());
+ }
+
+ // location
+ //
+ {
+ ::bpkg::repository_location const& v =
+ o.location;
+
+ // From package.hxx:368:14
+ ::bpkg::_repository_location const& vt =
+ bpkg::_repository_location
+ {
+ (v).url (), (v).empty () ? bpkg::repository_type::pkg : (v).type ()
+ };
+
+
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ i.location_value,
+ vt,
+ sk))
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ init (object_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // name
+ //
+ {
+ ::std::string& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // location
+ //
+ {
+ // From package.hxx:437:7
+ ::bpkg::repository_location v;
+
+ ::bpkg::_repository_location vt;
+
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ vt,
+ i.location_value,
+ db);
+
+ // From package.hxx:368:14
+ v = bpkg::repository_location (std::move ((vt).url), (vt).type);
+ // From package.hxx:437:7
+ o.location = std::move (v);
+ assert (o.name == o.location.canonical_name ());
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ init (id_image_type& i, const id_type& id)
+ {
+ bool grew (false);
+ {
+ bool is_null (false);
+ std::size_t cap (i.id_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.id_value,
+ i.id_size,
+ is_null,
+ id);
+ i.id_null = is_null;
+ grew = grew || (cap != i.id_value.capacity ());
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::persist_statement[] =
+ "INSERT INTO \"main\".\"repository_fragment\" "
+ "(\"name\", "
+ "\"url\", "
+ "\"type\") "
+ "VALUES "
+ "(?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::find_statement[] =
+ "SELECT "
+ "\"main\".\"repository_fragment\".\"name\", "
+ "\"main\".\"repository_fragment\".\"url\", "
+ "\"main\".\"repository_fragment\".\"type\" "
+ "FROM \"main\".\"repository_fragment\" "
+ "WHERE \"main\".\"repository_fragment\".\"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::update_statement[] =
+ "UPDATE \"main\".\"repository_fragment\" "
+ "SET "
+ "\"url\"=?, "
+ "\"type\"=? "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::erase_statement[] =
+ "DELETE FROM \"main\".\"repository_fragment\" "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::query_statement[] =
+ "SELECT "
+ "\"main\".\"repository_fragment\".\"name\", "
+ "\"main\".\"repository_fragment\".\"url\", "
+ "\"main\".\"repository_fragment\".\"type\" "
+ "FROM \"main\".\"repository_fragment\"";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::erase_query_statement[] =
+ "DELETE FROM \"main\".\"repository_fragment\"";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::table_name[] =
+ "\"main\".\"repository_fragment\"";
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ persist (database& db, const object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ callback (db,
+ obj,
+ callback_event::pre_persist);
+
+ image_type& im (sts.image ());
+ binding& imb (sts.insert_image_binding ());
+
+ if (init (im, obj, statement_insert))
+ im.version++;
+
+ if (im.version != sts.insert_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_insert);
+ sts.insert_image_version (im.version);
+ imb.version++;
+ }
+
+ insert_statement& st (sts.persist_statement ());
+ if (!st.execute ())
+ throw object_already_persistent ();
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // complements
+ //
+ {
+ ::bpkg::repository_fragment::dependencies const& v =
+ obj.complements;
+
+ complements_traits::persist (
+ v,
+ esc.complements);
+ }
+
+ // prerequisites
+ //
+ {
+ ::bpkg::repository_fragment::dependencies const& v =
+ obj.prerequisites;
+
+ prerequisites_traits::persist (
+ v,
+ esc.prerequisites);
+ }
+
+ callback (db,
+ obj,
+ callback_event::post_persist);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ update (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+ using sqlite::update_statement;
+
+ callback (db, obj, callback_event::pre_update);
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ sqlite::connection& conn (tr.connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& idi (sts.id_image ());
+ init (idi, id (obj));
+
+ image_type& im (sts.image ());
+ if (init (im, obj, statement_update))
+ im.version++;
+
+ bool u (false);
+ binding& imb (sts.update_image_binding ());
+ if (im.version != sts.update_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_update);
+ sts.update_image_version (im.version);
+ imb.version++;
+ u = true;
+ }
+
+ binding& idb (sts.id_image_binding ());
+ if (idi.version != sts.update_id_image_version () ||
+ idb.version == 0)
+ {
+ if (idi.version != sts.id_image_version () ||
+ idb.version == 0)
+ {
+ bind (idb.bind, idi);
+ sts.id_image_version (idi.version);
+ idb.version++;
+ }
+
+ sts.update_id_image_version (idi.version);
+
+ if (!u)
+ imb.version++;
+ }
+
+ update_statement& st (sts.update_statement ());
+ if (st.execute () == 0)
+ throw object_not_persistent ();
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // complements
+ //
+ {
+ ::bpkg::repository_fragment::dependencies const& v =
+ obj.complements;
+
+ complements_traits::update (
+ v,
+ esc.complements);
+ }
+
+ // prerequisites
+ //
+ {
+ ::bpkg::repository_fragment::dependencies const& v =
+ obj.prerequisites;
+
+ prerequisites_traits::update (
+ v,
+ esc.prerequisites);
+ }
+
+ callback (db, obj, callback_event::post_update);
+ pointer_cache_traits::update (db, obj);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ erase (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // complements
+ //
+ {
+ complements_traits::erase (
+ esc.complements);
+ }
+
+ // prerequisites
+ //
+ {
+ prerequisites_traits::erase (
+ esc.prerequisites);
+ }
+
+ if (sts.erase_statement ().execute () != 1)
+ throw object_not_persistent ();
+
+ pointer_cache_traits::erase (db, id);
+ }
+
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::pointer_type
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ find (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ {
+ pointer_type p (pointer_cache_traits::find (db, id));
+
+ if (!pointer_traits::null_ptr (p))
+ return p;
+ }
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+
+ if (l.locked ())
+ {
+ if (!find_ (sts, &id))
+ return pointer_type ();
+ }
+
+ pointer_type p (
+ access::object_factory<object_type, pointer_type>::create ());
+ pointer_traits::guard pg (p);
+
+ pointer_cache_traits::insert_guard ig (
+ pointer_cache_traits::insert (db, id, p));
+
+ object_type& obj (pointer_traits::get_ref (p));
+
+ if (l.locked ())
+ {
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ pointer_cache_traits::load (ig.position ());
+ }
+ else
+ sts.delay_load (id, obj, ig.position ());
+
+ ig.release ();
+ pg.release ();
+ return p;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ find (database& db, const id_type& id, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ reference_cache_traits::position_type pos (
+ reference_cache_traits::insert (db, id, obj));
+ reference_cache_traits::insert_guard ig (pos);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ reference_cache_traits::load (pos);
+ ig.release ();
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ reload (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ const id_type& id (object_traits_impl::id (obj));
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, true);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ find_ (statements_type& sts,
+ const id_type* id)
+ {
+ using namespace sqlite;
+
+ id_image_type& i (sts.id_image ());
+ init (i, *id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ select_statement& st (sts.find_statement ());
+
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ if (grow (im, sts.select_image_truncated ()))
+ im.version++;
+
+ if (im.version != sts.select_image_version ())
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ load_ (statements_type& sts,
+ object_type& obj,
+ bool reload)
+ {
+ ODB_POTENTIALLY_UNUSED (reload);
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // complements
+ //
+ {
+ ::bpkg::repository_fragment::dependencies& v =
+ obj.complements;
+
+ complements_traits::load (
+ v,
+ esc.complements);
+ }
+
+ // prerequisites
+ //
+ {
+ ::bpkg::repository_fragment::dependencies& v =
+ obj.prerequisites;
+
+ prerequisites_traits::load (
+ v,
+ esc.prerequisites);
+ }
+ }
+
+ result< access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::object_type >
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ q.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::object_result_impl<object_type> > r (
+ new (shared) sqlite::object_result_impl<object_type> (
+ q, st, sts, 0));
+
+ return result<object_type> (r);
+ }
+
+ unsigned long long access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ erase_query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ std::string text (erase_query_statement);
+ if (!q.empty ())
+ {
+ text += ' ';
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ delete_statement st (
+ conn,
+ text,
+ q.parameters_binding ());
+
+ return st.execute ();
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = q;
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::object_result_impl<object_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // repository_fragment_count
+ //
+
+ bool access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // result
+ //
+ t[0UL] = false;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // result
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.result_value;
+ b[n].is_null = &i.result_null;
+ n++;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // result
+ //
+ {
+ ::std::size_t& v =
+ o.result;
+
+ sqlite::value_traits<
+ ::std::size_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.result_value,
+ i.result_null);
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "count(*) ");
+
+ r += "FROM \"main\".\"repository_fragment\"";
+
+ query_base_type c (
+ // From package.hxx:452:5
+ query_columns::name != "" && (q.empty () ? query_base_type::true_expr : q));
+
+ c.optimize ();
+
+ if (!c.empty ())
+ {
+ r += " ";
+ r += c.clause_prefix ();
+ r += c;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // fragment_type
+ //
+
+ bool access::composite_value_traits< ::bpkg::repository::fragment_type, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // friendly_name
+ //
+ if (t[0UL])
+ {
+ i.friendly_name_value.capacity (i.friendly_name_size);
+ grew = true;
+ }
+
+ // fragment
+ //
+ if (t[1UL])
+ {
+ i.fragment_value.capacity (i.fragment_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::repository::fragment_type, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // friendly_name
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.friendly_name_value.data ();
+ b[n].size = &i.friendly_name_size;
+ b[n].capacity = i.friendly_name_value.capacity ();
+ b[n].is_null = &i.friendly_name_null;
+ n++;
+
+ // fragment
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.fragment_value.data ();
+ b[n].size = &i.fragment_size;
+ b[n].capacity = i.fragment_value.capacity ();
+ b[n].is_null = &i.fragment_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::repository::fragment_type, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // friendly_name
+ //
+ {
+ ::std::string const& v =
+ o.friendly_name;
+
+ bool is_null (false);
+ std::size_t cap (i.friendly_name_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.friendly_name_value,
+ i.friendly_name_size,
+ is_null,
+ v);
+ i.friendly_name_null = is_null;
+ grew = grew || (cap != i.friendly_name_value.capacity ());
+ }
+
+ // fragment
+ //
+ {
+ ::bpkg::lazy_shared_ptr< ::bpkg::repository_fragment > const& v =
+ o.fragment;
+
+ typedef object_traits< ::bpkg::repository_fragment > obj_traits;
+ typedef odb::pointer_traits< ::bpkg::lazy_shared_ptr< ::bpkg::repository_fragment > > ptr_traits;
+
+ bool is_null (ptr_traits::null_ptr (v));
+ if (!is_null)
+ {
+ const obj_traits::id_type& ptr_id (
+ ptr_traits::object_id< ptr_traits::element_type > (v));
+
+ std::size_t cap (i.fragment_value.capacity ());
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_image (
+ i.fragment_value,
+ i.fragment_size,
+ is_null,
+ ptr_id);
+ i.fragment_null = is_null;
+ grew = grew || (cap != i.fragment_value.capacity ());
+ }
+ else
+ i.fragment_null = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::repository::fragment_type, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // friendly_name
+ //
+ {
+ ::std::string& v =
+ o.friendly_name;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.friendly_name_value,
+ i.friendly_name_size,
+ i.friendly_name_null);
+ }
+
+ // fragment
+ //
+ {
+ ::bpkg::lazy_shared_ptr< ::bpkg::repository_fragment >& v =
+ o.fragment;
+
+ typedef object_traits< ::bpkg::repository_fragment > obj_traits;
+ typedef odb::pointer_traits< ::bpkg::lazy_shared_ptr< ::bpkg::repository_fragment > > ptr_traits;
+
+ if (i.fragment_null)
+ v = ptr_traits::pointer_type ();
+ else
+ {
+ obj_traits::id_type ptr_id;
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_value (
+ ptr_id,
+ i.fragment_value,
+ i.fragment_size,
+ i.fragment_null);
+
+ v = ptr_traits::pointer_type (
+ *static_cast<sqlite::database*> (db), ptr_id);
+ }
+ }
+ }
+
+ // repository
+ //
+
+ struct access::object_traits_impl< ::bpkg::repository, id_sqlite >::extra_statement_cache_type
+ {
+ sqlite::container_statements_impl< fragments_traits > fragments;
+
+ extra_statement_cache_type (
+ sqlite::connection& c,
+ image_type&,
+ id_image_type&,
+ sqlite::binding& id,
+ sqlite::binding&)
+ : fragments (c, id)
+ {
+ }
+ };
+
+ // fragments
+ //
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"repository_fragments\".\"index\", "
+ "\"main\".\"repository_fragments\".\"friendly_name\", "
+ "\"main\".\"repository_fragments\".\"fragment\" "
+ "FROM \"main\".\"repository_fragments\" "
+ "WHERE \"main\".\"repository_fragments\".\"repository\"=? ORDER BY \"main\".\"repository_fragments\".\"index\"";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"repository_fragments\" "
+ "(\"repository\", "
+ "\"index\", "
+ "\"friendly_name\", "
+ "\"fragment\") "
+ "VALUES "
+ "(?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"repository_fragments\" "
+ "WHERE \"repository\"=?";
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // index
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.index_value;
+ b[n].is_null = &d.index_null;
+ n++;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // index
+ //
+ t[0UL] = false;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 1UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ init (data_image_type& i,
+ index_type* j,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // index
+ //
+ if (j != 0)
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_image (
+ i.index_value,
+ is_null,
+ *j);
+ i.index_null = is_null;
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ init (index_type& j,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // index
+ //
+ {
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_value (
+ j,
+ i.index_value,
+ i.index_null);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ insert (index_type i, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &i, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ select (index_type& i, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (i, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::erase (fs);
+ }
+
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ id (const image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ id,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ return id;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // name
+ //
+ if (t[0UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // location
+ //
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::grow (
+ i.location_value, t + 1UL))
+ grew = true;
+
+ // certificate
+ //
+ if (t[3UL])
+ {
+ i.certificate_value.capacity (i.certificate_size);
+ grew = true;
+ }
+
+ // local
+ //
+ t[4UL] = false;
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+
+ // name
+ //
+ if (sk != statement_update)
+ {
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.name_value.data ();
+ b[n].size = &i.name_size;
+ b[n].capacity = i.name_value.capacity ();
+ b[n].is_null = &i.name_null;
+ n++;
+ }
+
+ // location
+ //
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::bind (
+ b + n, i.location_value, sk);
+ n += 2UL;
+
+ // certificate
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.certificate_value.data ();
+ b[n].size = &i.certificate_size;
+ b[n].capacity = i.certificate_value.capacity ();
+ b[n].is_null = &i.certificate_null;
+ n++;
+
+ // local
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.local_value;
+ b[n].is_null = &i.local_null;
+ n++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ bind (sqlite::bind* b, id_image_type& i)
+ {
+ std::size_t n (0);
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.id_value.data ();
+ b[n].size = &i.id_size;
+ b[n].capacity = i.id_value.capacity ();
+ b[n].is_null = &i.id_null;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ init (image_type& i,
+ const object_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // name
+ //
+ if (sk == statement_insert)
+ {
+ ::std::string const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.name_value,
+ i.name_size,
+ is_null,
+ v);
+ i.name_null = is_null;
+ grew = grew || (cap != i.name_value.capacity ());
+ }
+
+ // location
+ //
+ {
+ ::bpkg::repository_location const& v =
+ o.location;
+
+ // From package.hxx:368:14
+ ::bpkg::_repository_location const& vt =
+ bpkg::_repository_location
+ {
+ (v).url (), (v).empty () ? bpkg::repository_type::pkg : (v).type ()
+ };
+
+
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ i.location_value,
+ vt,
+ sk))
+ grew = true;
+ }
+
+ // certificate
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.certificate;
+
+ bool is_null (true);
+ std::size_t cap (i.certificate_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.certificate_value,
+ i.certificate_size,
+ is_null,
+ v);
+ i.certificate_null = is_null;
+ grew = grew || (cap != i.certificate_value.capacity ());
+ }
+
+ // local
+ //
+ {
+ ::butl::optional< bool > const& v =
+ o.local;
+
+ bool is_null (true);
+ sqlite::value_traits<
+ ::butl::optional< bool >,
+ sqlite::id_integer >::set_image (
+ i.local_value,
+ is_null,
+ v);
+ i.local_null = is_null;
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ init (object_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // name
+ //
+ {
+ ::std::string& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // location
+ //
+ {
+ // From package.hxx:501:7
+ ::bpkg::repository_location v;
+
+ ::bpkg::_repository_location vt;
+
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ vt,
+ i.location_value,
+ db);
+
+ // From package.hxx:368:14
+ v = bpkg::repository_location (std::move ((vt).url), (vt).type);
+ // From package.hxx:501:7
+ o.location = std::move (v);
+ assert (o.name == o.location.canonical_name ());
+ }
+
+ // certificate
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.certificate;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.certificate_value,
+ i.certificate_size,
+ i.certificate_null);
+ }
+
+ // local
+ //
+ {
+ ::butl::optional< bool >& v =
+ o.local;
+
+ sqlite::value_traits<
+ ::butl::optional< bool >,
+ sqlite::id_integer >::set_value (
+ v,
+ i.local_value,
+ i.local_null);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ init (id_image_type& i, const id_type& id)
+ {
+ bool grew (false);
+ {
+ bool is_null (false);
+ std::size_t cap (i.id_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.id_value,
+ i.id_size,
+ is_null,
+ id);
+ i.id_null = is_null;
+ grew = grew || (cap != i.id_value.capacity ());
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::persist_statement[] =
+ "INSERT INTO \"main\".\"repository\" "
+ "(\"name\", "
+ "\"url\", "
+ "\"type\", "
+ "\"certificate\", "
+ "\"local\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::find_statement[] =
+ "SELECT "
+ "\"main\".\"repository\".\"name\", "
+ "\"main\".\"repository\".\"url\", "
+ "\"main\".\"repository\".\"type\", "
+ "\"main\".\"repository\".\"certificate\", "
+ "\"main\".\"repository\".\"local\" "
+ "FROM \"main\".\"repository\" "
+ "WHERE \"main\".\"repository\".\"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::update_statement[] =
+ "UPDATE \"main\".\"repository\" "
+ "SET "
+ "\"url\"=?, "
+ "\"type\"=?, "
+ "\"certificate\"=?, "
+ "\"local\"=? "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::erase_statement[] =
+ "DELETE FROM \"main\".\"repository\" "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::query_statement[] =
+ "SELECT "
+ "\"main\".\"repository\".\"name\", "
+ "\"main\".\"repository\".\"url\", "
+ "\"main\".\"repository\".\"type\", "
+ "\"main\".\"repository\".\"certificate\", "
+ "\"main\".\"repository\".\"local\" "
+ "FROM \"main\".\"repository\"";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::erase_query_statement[] =
+ "DELETE FROM \"main\".\"repository\"";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::table_name[] =
+ "\"main\".\"repository\"";
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ persist (database& db, const object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ callback (db,
+ obj,
+ callback_event::pre_persist);
+
+ image_type& im (sts.image ());
+ binding& imb (sts.insert_image_binding ());
+
+ if (init (im, obj, statement_insert))
+ im.version++;
+
+ if (im.version != sts.insert_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_insert);
+ sts.insert_image_version (im.version);
+ imb.version++;
+ }
+
+ insert_statement& st (sts.persist_statement ());
+ if (!st.execute ())
+ throw object_already_persistent ();
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // fragments
+ //
+ {
+ ::bpkg::repository::fragments_type const& v =
+ obj.fragments;
+
+ fragments_traits::persist (
+ v,
+ esc.fragments);
+ }
+
+ callback (db,
+ obj,
+ callback_event::post_persist);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ update (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+ using sqlite::update_statement;
+
+ callback (db, obj, callback_event::pre_update);
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ sqlite::connection& conn (tr.connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& idi (sts.id_image ());
+ init (idi, id (obj));
+
+ image_type& im (sts.image ());
+ if (init (im, obj, statement_update))
+ im.version++;
+
+ bool u (false);
+ binding& imb (sts.update_image_binding ());
+ if (im.version != sts.update_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_update);
+ sts.update_image_version (im.version);
+ imb.version++;
+ u = true;
+ }
+
+ binding& idb (sts.id_image_binding ());
+ if (idi.version != sts.update_id_image_version () ||
+ idb.version == 0)
+ {
+ if (idi.version != sts.id_image_version () ||
+ idb.version == 0)
+ {
+ bind (idb.bind, idi);
+ sts.id_image_version (idi.version);
+ idb.version++;
+ }
+
+ sts.update_id_image_version (idi.version);
+
+ if (!u)
+ imb.version++;
+ }
+
+ update_statement& st (sts.update_statement ());
+ if (st.execute () == 0)
+ throw object_not_persistent ();
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // fragments
+ //
+ {
+ ::bpkg::repository::fragments_type const& v =
+ obj.fragments;
+
+ fragments_traits::update (
+ v,
+ esc.fragments);
+ }
+
+ callback (db, obj, callback_event::post_update);
+ pointer_cache_traits::update (db, obj);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ erase (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // fragments
+ //
+ {
+ fragments_traits::erase (
+ esc.fragments);
+ }
+
+ if (sts.erase_statement ().execute () != 1)
+ throw object_not_persistent ();
+
+ pointer_cache_traits::erase (db, id);
+ }
+
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::pointer_type
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ find (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ {
+ pointer_type p (pointer_cache_traits::find (db, id));
+
+ if (!pointer_traits::null_ptr (p))
+ return p;
+ }
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+
+ if (l.locked ())
+ {
+ if (!find_ (sts, &id))
+ return pointer_type ();
+ }
+
+ pointer_type p (
+ access::object_factory<object_type, pointer_type>::create ());
+ pointer_traits::guard pg (p);
+
+ pointer_cache_traits::insert_guard ig (
+ pointer_cache_traits::insert (db, id, p));
+
+ object_type& obj (pointer_traits::get_ref (p));
+
+ if (l.locked ())
+ {
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ pointer_cache_traits::load (ig.position ());
+ }
+ else
+ sts.delay_load (id, obj, ig.position ());
+
+ ig.release ();
+ pg.release ();
+ return p;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ find (database& db, const id_type& id, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ reference_cache_traits::position_type pos (
+ reference_cache_traits::insert (db, id, obj));
+ reference_cache_traits::insert_guard ig (pos);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ reference_cache_traits::load (pos);
+ ig.release ();
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ reload (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ const id_type& id (object_traits_impl::id (obj));
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, true);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ find_ (statements_type& sts,
+ const id_type* id)
+ {
+ using namespace sqlite;
+
+ id_image_type& i (sts.id_image ());
+ init (i, *id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ select_statement& st (sts.find_statement ());
+
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ if (grow (im, sts.select_image_truncated ()))
+ im.version++;
+
+ if (im.version != sts.select_image_version ())
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ load_ (statements_type& sts,
+ object_type& obj,
+ bool reload)
+ {
+ ODB_POTENTIALLY_UNUSED (reload);
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // fragments
+ //
+ {
+ ::bpkg::repository::fragments_type& v =
+ obj.fragments;
+
+ fragments_traits::load (
+ v,
+ esc.fragments);
+ }
+ }
+
+ result< access::object_traits_impl< ::bpkg::repository, id_sqlite >::object_type >
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ q.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::object_result_impl<object_type> > r (
+ new (shared) sqlite::object_result_impl<object_type> (
+ q, st, sts, 0));
+
+ return result<object_type> (r);
+ }
+
+ unsigned long long access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ erase_query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ std::string text (erase_query_statement);
+ if (!q.empty ())
+ {
+ text += ' ';
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ delete_statement st (
+ conn,
+ text,
+ q.parameters_binding ());
+
+ return st.execute ();
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = q;
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::object_result_impl<object_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // repository_count
+ //
+
+ bool access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // result
+ //
+ t[0UL] = false;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // result
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.result_value;
+ b[n].is_null = &i.result_null;
+ n++;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // result
+ //
+ {
+ ::std::size_t& v =
+ o.result;
+
+ sqlite::value_traits<
+ ::std::size_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.result_value,
+ i.result_null);
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "count(*) ");
+
+ r += "FROM \"main\".\"repository\"";
+
+ query_base_type c (
+ // From package.hxx:512:38
+ query_columns::name != "" && (q.empty () ? query_base_type::true_expr : q));
+
+ c.optimize ();
+
+ if (!c.empty ())
+ {
+ r += " ";
+ r += c.clause_prefix ();
+ r += c;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // package_location
+ //
+
+ bool access::composite_value_traits< ::bpkg::package_location, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // repository_fragment
+ //
+ if (t[0UL])
+ {
+ i.repository_fragment_value.capacity (i.repository_fragment_size);
+ grew = true;
+ }
+
+ // location
+ //
+ if (t[1UL])
+ {
+ i.location_value.capacity (i.location_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::package_location, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // repository_fragment
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.repository_fragment_value.data ();
+ b[n].size = &i.repository_fragment_size;
+ b[n].capacity = i.repository_fragment_value.capacity ();
+ b[n].is_null = &i.repository_fragment_null;
+ n++;
+
+ // location
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.location_value.data ();
+ b[n].size = &i.location_size;
+ b[n].capacity = i.location_value.capacity ();
+ b[n].is_null = &i.location_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::package_location, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // repository_fragment
+ //
+ {
+ ::bpkg::lazy_shared_ptr< ::bpkg::repository_fragment > const& v =
+ o.repository_fragment;
+
+ typedef object_traits< ::bpkg::repository_fragment > obj_traits;
+ typedef odb::pointer_traits< ::bpkg::lazy_shared_ptr< ::bpkg::repository_fragment > > ptr_traits;
+
+ bool is_null (ptr_traits::null_ptr (v));
+ if (!is_null)
+ {
+ const obj_traits::id_type& ptr_id (
+ ptr_traits::object_id< ptr_traits::element_type > (v));
+
+ std::size_t cap (i.repository_fragment_value.capacity ());
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_image (
+ i.repository_fragment_value,
+ i.repository_fragment_size,
+ is_null,
+ ptr_id);
+ i.repository_fragment_null = is_null;
+ grew = grew || (cap != i.repository_fragment_value.capacity ());
+ }
+ else
+ i.repository_fragment_null = true;
+ }
+
+ // location
+ //
+ {
+ ::butl::path const& v =
+ o.location;
+
+ // From package.hxx:50:14
+ ::std::string const& vt =
+ (v).representation ();
+
+ bool is_null (false);
+ std::size_t cap (i.location_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.location_value,
+ i.location_size,
+ is_null,
+ vt);
+ i.location_null = is_null;
+ grew = grew || (cap != i.location_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::package_location, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // repository_fragment
+ //
+ {
+ ::bpkg::lazy_shared_ptr< ::bpkg::repository_fragment >& v =
+ o.repository_fragment;
+
+ typedef object_traits< ::bpkg::repository_fragment > obj_traits;
+ typedef odb::pointer_traits< ::bpkg::lazy_shared_ptr< ::bpkg::repository_fragment > > ptr_traits;
+
+ if (i.repository_fragment_null)
+ v = ptr_traits::pointer_type ();
+ else
+ {
+ obj_traits::id_type ptr_id;
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_value (
+ ptr_id,
+ i.repository_fragment_value,
+ i.repository_fragment_size,
+ i.repository_fragment_null);
+
+ v = ptr_traits::pointer_type (
+ *static_cast<sqlite::database*> (db), ptr_id);
+ }
+ }
+
+ // location
+ //
+ {
+ ::butl::path& v =
+ o.location;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.location_value,
+ i.location_size,
+ i.location_null);
+
+ // From package.hxx:50:14
+ v = bpkg::path (vt);
+ }
+ }
+
+ // dependency_alternatives_ex
+ //
+
+ bool access::composite_value_traits< ::bpkg::dependency_alternatives_ex, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // dependency_alternatives base
+ //
+ if (composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::grow (
+ i, t + 0UL))
+ grew = true;
+
+ // type
+ //
+ if (t[2UL])
+ {
+ i.type_value.capacity (i.type_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency_alternatives_ex, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // dependency_alternatives base
+ //
+ composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::bind (b + n, i, sk);
+ n += 2UL;
+
+ // type
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.type_value.data ();
+ b[n].size = &i.type_size;
+ b[n].capacity = i.type_value.capacity ();
+ b[n].is_null = &i.type_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::dependency_alternatives_ex, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // dependency_alternatives base
+ //
+ if (composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::init (i, o, sk))
+ grew = true;
+
+ // type
+ //
+ {
+ ::butl::optional< ::bpkg::test_dependency_type > const& v =
+ o.type;
+
+ // From package.hxx:633:14
+ ::bpkg::optional_string const& vt =
+ (v) ? to_string ( * (v)) : bpkg::optional_string ();
+
+ bool is_null (true);
+ std::size_t cap (i.type_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_image (
+ i.type_value,
+ i.type_size,
+ is_null,
+ vt);
+ i.type_null = is_null;
+ grew = grew || (cap != i.type_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency_alternatives_ex, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // dependency_alternatives base
+ //
+ composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::init (o, i, db);
+
+ // type
+ //
+ {
+ ::butl::optional< ::bpkg::test_dependency_type >& v =
+ o.type;
+
+ ::bpkg::optional_string vt;
+
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.type_value,
+ i.type_size,
+ i.type_null);
+
+ // From package.hxx:633:14
+ v = (vt) ? bpkg::to_test_dependency_type ( * (vt)) : bpkg::optional_test_dependency_type ();
+ }
+ }
+
+ // available_package_id
+ //
+
+ bool access::composite_value_traits< ::bpkg::available_package_id, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // name
+ //
+ if (t[0UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // version
+ //
+ if (composite_value_traits< ::bpkg::canonical_version, id_sqlite >::grow (
+ i.version_value, t + 1UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::available_package_id, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // name
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::package_name,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.name_value.data ();
+ b[n].size = &i.name_size;
+ b[n].capacity = i.name_value.capacity ();
+ b[n].is_null = &i.name_null;
+ n++;
+
+ // version
+ //
+ composite_value_traits< ::bpkg::canonical_version, id_sqlite >::bind (
+ b + n, i.version_value, sk);
+ n += 5UL;
+ }
+
+ bool access::composite_value_traits< ::bpkg::available_package_id, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // name
+ //
+ {
+ ::bpkg::package_name const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_image (
+ i.name_value,
+ i.name_size,
+ is_null,
+ v);
+ i.name_null = is_null;
+ grew = grew || (cap != i.name_value.capacity ());
+ }
+
+ // version
+ //
+ {
+ ::bpkg::canonical_version const& v =
+ o.version;
+
+ if (composite_value_traits< ::bpkg::canonical_version, id_sqlite >::init (
+ i.version_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::available_package_id, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // name
+ //
+ {
+ ::bpkg::package_name& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // version
+ //
+ {
+ ::bpkg::canonical_version& v =
+ o.version;
+
+ composite_value_traits< ::bpkg::canonical_version, id_sqlite >::init (
+ v,
+ i.version_value,
+ db);
+ }
+ }
+
+ // _dependency_alternative_key
+ //
+
+ bool access::composite_value_traits< ::bpkg::available_package::_dependency_alternative_key, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // outer
+ //
+ t[0UL] = false;
+
+ // inner
+ //
+ t[1UL] = false;
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::available_package::_dependency_alternative_key, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // outer
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.outer_value;
+ b[n].is_null = &i.outer_null;
+ n++;
+
+ // inner
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.inner_value;
+ b[n].is_null = &i.inner_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::available_package::_dependency_alternative_key, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // outer
+ //
+ {
+ ::bpkg::available_package::_dependency_alternative_key::outer_type const& v =
+ o.outer;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternative_key::outer_type,
+ sqlite::id_integer >::set_image (
+ i.outer_value,
+ is_null,
+ v);
+ i.outer_null = is_null;
+ }
+
+ // inner
+ //
+ {
+ ::bpkg::available_package::_dependency_alternative_key::inner_type const& v =
+ o.inner;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternative_key::inner_type,
+ sqlite::id_integer >::set_image (
+ i.inner_value,
+ is_null,
+ v);
+ i.inner_null = is_null;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::available_package::_dependency_alternative_key, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // outer
+ //
+ {
+ ::bpkg::available_package::_dependency_alternative_key::outer_type& v =
+ o.outer;
+
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternative_key::outer_type,
+ sqlite::id_integer >::set_value (
+ v,
+ i.outer_value,
+ i.outer_null);
+ }
+
+ // inner
+ //
+ {
+ ::bpkg::available_package::_dependency_alternative_key::inner_type& v =
+ o.inner;
+
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternative_key::inner_type,
+ sqlite::id_integer >::set_value (
+ v,
+ i.inner_value,
+ i.inner_null);
+ }
+ }
+
+ // _dependency_key
+ //
+
+ bool access::composite_value_traits< ::bpkg::available_package::_dependency_key, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // outer
+ //
+ t[0UL] = false;
+
+ // middle
+ //
+ t[1UL] = false;
+
+ // inner
+ //
+ t[2UL] = false;
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::available_package::_dependency_key, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // outer
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.outer_value;
+ b[n].is_null = &i.outer_null;
+ n++;
+
+ // middle
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.middle_value;
+ b[n].is_null = &i.middle_null;
+ n++;
+
+ // inner
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.inner_value;
+ b[n].is_null = &i.inner_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::available_package::_dependency_key, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // outer
+ //
+ {
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::outer_type const& v =
+ o.outer;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::outer_type,
+ sqlite::id_integer >::set_image (
+ i.outer_value,
+ is_null,
+ v);
+ i.outer_null = is_null;
+ }
+
+ // middle
+ //
+ {
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::middle_type const& v =
+ o.middle;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::middle_type,
+ sqlite::id_integer >::set_image (
+ i.middle_value,
+ is_null,
+ v);
+ i.middle_null = is_null;
+ }
+
+ // inner
+ //
+ {
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::inner_type const& v =
+ o.inner;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::inner_type,
+ sqlite::id_integer >::set_image (
+ i.inner_value,
+ is_null,
+ v);
+ i.inner_null = is_null;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::available_package::_dependency_key, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // outer
+ //
+ {
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::outer_type& v =
+ o.outer;
+
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::outer_type,
+ sqlite::id_integer >::set_value (
+ v,
+ i.outer_value,
+ i.outer_null);
+ }
+
+ // middle
+ //
+ {
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::middle_type& v =
+ o.middle;
+
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::middle_type,
+ sqlite::id_integer >::set_value (
+ v,
+ i.middle_value,
+ i.middle_null);
+ }
+
+ // inner
+ //
+ {
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::inner_type& v =
+ o.inner;
+
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternative_dependencies_type::key_type::inner_type,
+ sqlite::id_integer >::set_value (
+ v,
+ i.inner_value,
+ i.inner_null);
+ }
+ }
+
+ // available_package
+ //
+
+ struct access::object_traits_impl< ::bpkg::available_package, id_sqlite >::extra_statement_cache_type
+ {
+ sqlite::container_statements_impl< languages_traits > languages;
+ sqlite::container_statements_impl< locations_traits > locations;
+ sqlite::container_statements_impl< dependencies_traits > dependencies;
+ sqlite::container_statements_impl< dependency_alternatives_traits > dependency_alternatives;
+ sqlite::container_statements_impl< dependency_alternative_dependencies_traits > dependency_alternative_dependencies;
+ sqlite::container_statements_impl< tests_traits > tests;
+ sqlite::container_statements_impl< buildfiles_traits > buildfiles;
+ sqlite::container_statements_impl< distribution_values_traits > distribution_values;
+
+ sqlite::section_statements< ::bpkg::available_package, languages_section_traits > languages_section;
+
+ extra_statement_cache_type (
+ sqlite::connection& c,
+ image_type& im,
+ id_image_type& idim,
+ sqlite::binding& id,
+ sqlite::binding& idv)
+ : languages (c, id),
+ locations (c, id),
+ dependencies (c, id),
+ dependency_alternatives (c, id),
+ dependency_alternative_dependencies (c, id),
+ tests (c, id),
+ buildfiles (c, id),
+ distribution_values (c, id),
+ languages_section (c, im, idim, id, idv)
+ {
+ }
+ };
+
+ // languages
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"available_package_languages\".\"index\", "
+ "\"main\".\"available_package_languages\".\"language_name\", "
+ "\"main\".\"available_package_languages\".\"language_impl\" "
+ "FROM \"main\".\"available_package_languages\" "
+ "WHERE \"main\".\"available_package_languages\".\"name\"=? AND \"main\".\"available_package_languages\".\"version_epoch\"=? AND \"main\".\"available_package_languages\".\"version_canonical_upstream\"=? AND \"main\".\"available_package_languages\".\"version_canonical_release\"=? AND \"main\".\"available_package_languages\".\"version_revision\"=? AND \"main\".\"available_package_languages\".\"version_iteration\"=? ORDER BY \"main\".\"available_package_languages\".\"index\"";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"available_package_languages\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"index\", "
+ "\"language_name\", "
+ "\"language_impl\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"available_package_languages\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // index
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.index_value;
+ b[n].is_null = &d.index_null;
+ n++;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // index
+ //
+ t[0UL] = false;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 1UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ init (data_image_type& i,
+ index_type* j,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // index
+ //
+ if (j != 0)
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_image (
+ i.index_value,
+ is_null,
+ *j);
+ i.index_null = is_null;
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ init (index_type& j,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // index
+ //
+ {
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_value (
+ j,
+ i.index_value,
+ i.index_null);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ insert (index_type i, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &i, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ select (index_type& i, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (i, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::erase (fs);
+ }
+
+ // locations
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"available_package_locations\".\"repository_fragment\", "
+ "\"main\".\"available_package_locations\".\"location\" "
+ "FROM \"main\".\"available_package_locations\" "
+ "WHERE \"main\".\"available_package_locations\".\"name\"=? AND \"main\".\"available_package_locations\".\"version_epoch\"=? AND \"main\".\"available_package_locations\".\"version_canonical_upstream\"=? AND \"main\".\"available_package_locations\".\"version_canonical_release\"=? AND \"main\".\"available_package_locations\".\"version_revision\"=? AND \"main\".\"available_package_locations\".\"version_iteration\"=?";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"available_package_locations\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"repository_fragment\", "
+ "\"location\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"available_package_locations\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 0UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ init (data_image_type& i,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ init (value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ insert (index_type, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ select (index_type&, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = false;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = false;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = false;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = false;
+ container_traits_type::erase (fs);
+ }
+
+ // dependencies
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"available_package_dependencies\".\"index\", "
+ "\"main\".\"available_package_dependencies\".\"buildtime\", "
+ "\"main\".\"available_package_dependencies\".\"comment\", "
+ "\"main\".\"available_package_dependencies\".\"type\" "
+ "FROM \"main\".\"available_package_dependencies\" "
+ "WHERE \"main\".\"available_package_dependencies\".\"name\"=? AND \"main\".\"available_package_dependencies\".\"version_epoch\"=? AND \"main\".\"available_package_dependencies\".\"version_canonical_upstream\"=? AND \"main\".\"available_package_dependencies\".\"version_canonical_release\"=? AND \"main\".\"available_package_dependencies\".\"version_revision\"=? AND \"main\".\"available_package_dependencies\".\"version_iteration\"=? ORDER BY \"main\".\"available_package_dependencies\".\"index\"";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"available_package_dependencies\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"index\", "
+ "\"buildtime\", "
+ "\"comment\", "
+ "\"type\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"available_package_dependencies\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // index
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.index_value;
+ b[n].is_null = &d.index_null;
+ n++;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // index
+ //
+ t[0UL] = false;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 1UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ init (data_image_type& i,
+ index_type* j,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // index
+ //
+ if (j != 0)
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_image (
+ i.index_value,
+ is_null,
+ *j);
+ i.index_null = is_null;
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ init (index_type& j,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // index
+ //
+ {
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_value (
+ j,
+ i.index_value,
+ i.index_null);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ insert (index_type i, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &i, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ select (index_type& i, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (i, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::erase (fs);
+ }
+
+ // dependency_alternatives
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"available_package_dependency_alternatives\".\"dependency_index\", "
+ "\"main\".\"available_package_dependency_alternatives\".\"index\", "
+ "\"main\".\"available_package_dependency_alternatives\".\"enable\", "
+ "\"main\".\"available_package_dependency_alternatives\".\"reflect\", "
+ "\"main\".\"available_package_dependency_alternatives\".\"prefer\", "
+ "\"main\".\"available_package_dependency_alternatives\".\"accept\", "
+ "\"main\".\"available_package_dependency_alternatives\".\"require\" "
+ "FROM \"main\".\"available_package_dependency_alternatives\" "
+ "WHERE \"main\".\"available_package_dependency_alternatives\".\"name\"=? AND \"main\".\"available_package_dependency_alternatives\".\"version_epoch\"=? AND \"main\".\"available_package_dependency_alternatives\".\"version_canonical_upstream\"=? AND \"main\".\"available_package_dependency_alternatives\".\"version_canonical_release\"=? AND \"main\".\"available_package_dependency_alternatives\".\"version_revision\"=? AND \"main\".\"available_package_dependency_alternatives\".\"version_iteration\"=?";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"available_package_dependency_alternatives\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"dependency_index\", "
+ "\"index\", "
+ "\"enable\", "
+ "\"reflect\", "
+ "\"prefer\", "
+ "\"accept\", "
+ "\"require\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"available_package_dependency_alternatives\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // key
+ //
+ composite_value_traits< key_type, id_sqlite >::bind (
+ b + n, d.key_value, sk);
+ n += 2UL;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // key
+ //
+ if (composite_value_traits< key_type, id_sqlite >::grow (
+ i.key_value, t + 0UL))
+ grew = true;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 2UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ init (data_image_type& i,
+ const key_type* k,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // key
+ //
+ if (k != 0)
+ {
+ composite_value_traits< key_type, id_sqlite >::init (
+ i.key_value,
+ *k,
+ sk);
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ init (key_type& k,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // key
+ //
+ {
+ composite_value_traits< key_type, id_sqlite >::init (
+ k,
+ i.key_value,
+ db);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ insert (const key_type& k, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &k, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ select (key_type& k, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (k, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::erase (fs);
+ }
+
+ // dependency_alternative_dependencies
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dependency_index\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"alternative_index\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"index\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_name\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_min_version_epoch\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_min_version_canonical_upstream\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_min_version_canonical_release\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_min_version_revision\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_min_version_iteration\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_min_version_upstream\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_min_version_release\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_max_version_epoch\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_max_version_canonical_upstream\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_max_version_canonical_release\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_max_version_revision\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_max_version_iteration\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_max_version_upstream\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_max_version_release\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_min_open\", "
+ "\"main\".\"available_package_dependency_alternative_dependencies\".\"dep_max_open\" "
+ "FROM \"main\".\"available_package_dependency_alternative_dependencies\" "
+ "WHERE \"main\".\"available_package_dependency_alternative_dependencies\".\"name\"=? AND \"main\".\"available_package_dependency_alternative_dependencies\".\"version_epoch\"=? AND \"main\".\"available_package_dependency_alternative_dependencies\".\"version_canonical_upstream\"=? AND \"main\".\"available_package_dependency_alternative_dependencies\".\"version_canonical_release\"=? AND \"main\".\"available_package_dependency_alternative_dependencies\".\"version_revision\"=? AND \"main\".\"available_package_dependency_alternative_dependencies\".\"version_iteration\"=?";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"available_package_dependency_alternative_dependencies\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"dependency_index\", "
+ "\"alternative_index\", "
+ "\"index\", "
+ "\"dep_name\", "
+ "\"dep_min_version_epoch\", "
+ "\"dep_min_version_canonical_upstream\", "
+ "\"dep_min_version_canonical_release\", "
+ "\"dep_min_version_revision\", "
+ "\"dep_min_version_iteration\", "
+ "\"dep_min_version_upstream\", "
+ "\"dep_min_version_release\", "
+ "\"dep_max_version_epoch\", "
+ "\"dep_max_version_canonical_upstream\", "
+ "\"dep_max_version_canonical_release\", "
+ "\"dep_max_version_revision\", "
+ "\"dep_max_version_iteration\", "
+ "\"dep_max_version_upstream\", "
+ "\"dep_max_version_release\", "
+ "\"dep_min_open\", "
+ "\"dep_max_open\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"available_package_dependency_alternative_dependencies\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // key
+ //
+ composite_value_traits< key_type, id_sqlite >::bind (
+ b + n, d.key_value, sk);
+ n += 3UL;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // key
+ //
+ if (composite_value_traits< key_type, id_sqlite >::grow (
+ i.key_value, t + 0UL))
+ grew = true;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 3UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ init (data_image_type& i,
+ const key_type* k,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // key
+ //
+ if (k != 0)
+ {
+ composite_value_traits< key_type, id_sqlite >::init (
+ i.key_value,
+ *k,
+ sk);
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ init (key_type& k,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // key
+ //
+ {
+ composite_value_traits< key_type, id_sqlite >::init (
+ k,
+ i.key_value,
+ db);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ insert (const key_type& k, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &k, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ select (key_type& k, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (k, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternative_dependencies_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::erase (fs);
+ }
+
+ // tests
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"available_package_tests\".\"index\", "
+ "\"main\".\"available_package_tests\".\"test_name\", "
+ "\"main\".\"available_package_tests\".\"test_min_version_epoch\", "
+ "\"main\".\"available_package_tests\".\"test_min_version_canonical_upstream\", "
+ "\"main\".\"available_package_tests\".\"test_min_version_canonical_release\", "
+ "\"main\".\"available_package_tests\".\"test_min_version_revision\", "
+ "\"main\".\"available_package_tests\".\"test_min_version_iteration\", "
+ "\"main\".\"available_package_tests\".\"test_min_version_upstream\", "
+ "\"main\".\"available_package_tests\".\"test_min_version_release\", "
+ "\"main\".\"available_package_tests\".\"test_max_version_epoch\", "
+ "\"main\".\"available_package_tests\".\"test_max_version_canonical_upstream\", "
+ "\"main\".\"available_package_tests\".\"test_max_version_canonical_release\", "
+ "\"main\".\"available_package_tests\".\"test_max_version_revision\", "
+ "\"main\".\"available_package_tests\".\"test_max_version_iteration\", "
+ "\"main\".\"available_package_tests\".\"test_max_version_upstream\", "
+ "\"main\".\"available_package_tests\".\"test_max_version_release\", "
+ "\"main\".\"available_package_tests\".\"test_min_open\", "
+ "\"main\".\"available_package_tests\".\"test_max_open\", "
+ "\"main\".\"available_package_tests\".\"test_type\", "
+ "\"main\".\"available_package_tests\".\"test_buildtime\", "
+ "\"main\".\"available_package_tests\".\"test_enable\", "
+ "\"main\".\"available_package_tests\".\"test_reflect\" "
+ "FROM \"main\".\"available_package_tests\" "
+ "WHERE \"main\".\"available_package_tests\".\"name\"=? AND \"main\".\"available_package_tests\".\"version_epoch\"=? AND \"main\".\"available_package_tests\".\"version_canonical_upstream\"=? AND \"main\".\"available_package_tests\".\"version_canonical_release\"=? AND \"main\".\"available_package_tests\".\"version_revision\"=? AND \"main\".\"available_package_tests\".\"version_iteration\"=? ORDER BY \"main\".\"available_package_tests\".\"index\"";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"available_package_tests\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"index\", "
+ "\"test_name\", "
+ "\"test_min_version_epoch\", "
+ "\"test_min_version_canonical_upstream\", "
+ "\"test_min_version_canonical_release\", "
+ "\"test_min_version_revision\", "
+ "\"test_min_version_iteration\", "
+ "\"test_min_version_upstream\", "
+ "\"test_min_version_release\", "
+ "\"test_max_version_epoch\", "
+ "\"test_max_version_canonical_upstream\", "
+ "\"test_max_version_canonical_release\", "
+ "\"test_max_version_revision\", "
+ "\"test_max_version_iteration\", "
+ "\"test_max_version_upstream\", "
+ "\"test_max_version_release\", "
+ "\"test_min_open\", "
+ "\"test_max_open\", "
+ "\"test_type\", "
+ "\"test_buildtime\", "
+ "\"test_enable\", "
+ "\"test_reflect\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"available_package_tests\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // index
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.index_value;
+ b[n].is_null = &d.index_null;
+ n++;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // index
+ //
+ t[0UL] = false;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 1UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ init (data_image_type& i,
+ index_type* j,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // index
+ //
+ if (j != 0)
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_image (
+ i.index_value,
+ is_null,
+ *j);
+ i.index_null = is_null;
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ init (index_type& j,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // index
+ //
+ {
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_value (
+ j,
+ i.index_value,
+ i.index_null);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ insert (index_type i, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &i, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ select (index_type& i, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (i, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::erase (fs);
+ }
+
+ // buildfiles
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"available_package_buildfiles\".\"index\", "
+ "\"main\".\"available_package_buildfiles\".\"path\", "
+ "\"main\".\"available_package_buildfiles\".\"content\" "
+ "FROM \"main\".\"available_package_buildfiles\" "
+ "WHERE \"main\".\"available_package_buildfiles\".\"name\"=? AND \"main\".\"available_package_buildfiles\".\"version_epoch\"=? AND \"main\".\"available_package_buildfiles\".\"version_canonical_upstream\"=? AND \"main\".\"available_package_buildfiles\".\"version_canonical_release\"=? AND \"main\".\"available_package_buildfiles\".\"version_revision\"=? AND \"main\".\"available_package_buildfiles\".\"version_iteration\"=? ORDER BY \"main\".\"available_package_buildfiles\".\"index\"";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"available_package_buildfiles\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"index\", "
+ "\"path\", "
+ "\"content\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"available_package_buildfiles\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // index
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.index_value;
+ b[n].is_null = &d.index_null;
+ n++;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // index
+ //
+ t[0UL] = false;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 1UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ init (data_image_type& i,
+ index_type* j,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // index
+ //
+ if (j != 0)
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_image (
+ i.index_value,
+ is_null,
+ *j);
+ i.index_null = is_null;
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ init (index_type& j,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // index
+ //
+ {
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_value (
+ j,
+ i.index_value,
+ i.index_null);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ insert (index_type i, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &i, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ select (index_type& i, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (i, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::buildfiles_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::erase (fs);
+ }
+
+ // distribution_values
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"available_package_distribution_values\".\"index\", "
+ "\"main\".\"available_package_distribution_values\".\"dist_name\", "
+ "\"main\".\"available_package_distribution_values\".\"dist_value\" "
+ "FROM \"main\".\"available_package_distribution_values\" "
+ "WHERE \"main\".\"available_package_distribution_values\".\"name\"=? AND \"main\".\"available_package_distribution_values\".\"version_epoch\"=? AND \"main\".\"available_package_distribution_values\".\"version_canonical_upstream\"=? AND \"main\".\"available_package_distribution_values\".\"version_canonical_release\"=? AND \"main\".\"available_package_distribution_values\".\"version_revision\"=? AND \"main\".\"available_package_distribution_values\".\"version_iteration\"=? ORDER BY \"main\".\"available_package_distribution_values\".\"index\"";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"available_package_distribution_values\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"index\", "
+ "\"dist_name\", "
+ "\"dist_value\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"available_package_distribution_values\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // index
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.index_value;
+ b[n].is_null = &d.index_null;
+ n++;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // index
+ //
+ t[0UL] = false;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 1UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ init (data_image_type& i,
+ index_type* j,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // index
+ //
+ if (j != 0)
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_image (
+ i.index_value,
+ is_null,
+ *j);
+ i.index_null = is_null;
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ init (index_type& j,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // index
+ //
+ {
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_value (
+ j,
+ i.index_value,
+ i.index_null);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ insert (index_type i, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &i, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ select (index_type& i, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (i, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::distribution_values_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::erase (fs);
+ }
+
+ // languages_section
+ //
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_section_traits::
+ load (extra_statement_cache_type& esc, object_type& obj)
+ {
+ // languages
+ //
+ {
+ ::butl::small_vector< ::bpkg::language, 1 >& v =
+ obj.languages;
+
+ languages_traits::load (
+ v,
+ esc.languages);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::languages_section_traits::
+ update (extra_statement_cache_type& esc, const object_type& obj)
+ {
+ // languages
+ //
+ {
+ ::butl::small_vector< ::bpkg::language, 1 > const& v =
+ obj.languages;
+
+ languages_traits::update (
+ v,
+ esc.languages);
+ }
+ }
+
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ id (const image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::init (
+ id,
+ i.id_value,
+ db);
+ }
+
+ return id;
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // id
+ //
+ if (composite_value_traits< ::bpkg::available_package_id, id_sqlite >::grow (
+ i.id_value, t + 0UL))
+ grew = true;
+
+ // version
+ //
+ if (composite_value_traits< ::bpkg::available_package::upstream_version_type, id_sqlite >::grow (
+ i.version_value, t + 6UL))
+ grew = true;
+
+ // upstream_version
+ //
+ if (t[8UL])
+ {
+ i.upstream_version_value.capacity (i.upstream_version_size);
+ grew = true;
+ }
+
+ // type
+ //
+ if (t[9UL])
+ {
+ i.type_value.capacity (i.type_size);
+ grew = true;
+ }
+
+ // project
+ //
+ if (t[10UL])
+ {
+ i.project_value.capacity (i.project_size);
+ grew = true;
+ }
+
+ // alt_naming
+ //
+ t[11UL] = false;
+
+ // bootstrap_build
+ //
+ if (t[12UL])
+ {
+ i.bootstrap_build_value.capacity (i.bootstrap_build_size);
+ grew = true;
+ }
+
+ // root_build
+ //
+ if (t[13UL])
+ {
+ i.root_build_value.capacity (i.root_build_size);
+ grew = true;
+ }
+
+ // sha256sum
+ //
+ if (t[14UL])
+ {
+ i.sha256sum_value.capacity (i.sha256sum_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+
+ // id
+ //
+ if (sk != statement_update)
+ {
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::bind (
+ b + n, i.id_value, sk);
+ n += 6UL;
+ }
+
+ // version
+ //
+ composite_value_traits< ::bpkg::available_package::upstream_version_type, id_sqlite >::bind (
+ b + n, i.version_value, sk);
+ n += 2UL;
+
+ // upstream_version
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.upstream_version_value.data ();
+ b[n].size = &i.upstream_version_size;
+ b[n].capacity = i.upstream_version_value.capacity ();
+ b[n].is_null = &i.upstream_version_null;
+ n++;
+
+ // type
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.type_value.data ();
+ b[n].size = &i.type_size;
+ b[n].capacity = i.type_value.capacity ();
+ b[n].is_null = &i.type_null;
+ n++;
+
+ // project
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::butl::project_name >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.project_value.data ();
+ b[n].size = &i.project_size;
+ b[n].capacity = i.project_value.capacity ();
+ b[n].is_null = &i.project_null;
+ n++;
+
+ // alt_naming
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.alt_naming_value;
+ b[n].is_null = &i.alt_naming_null;
+ n++;
+
+ // bootstrap_build
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.bootstrap_build_value.data ();
+ b[n].size = &i.bootstrap_build_size;
+ b[n].capacity = i.bootstrap_build_value.capacity ();
+ b[n].is_null = &i.bootstrap_build_null;
+ n++;
+
+ // root_build
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.root_build_value.data ();
+ b[n].size = &i.root_build_size;
+ b[n].capacity = i.root_build_value.capacity ();
+ b[n].is_null = &i.root_build_null;
+ n++;
+
+ // sha256sum
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.sha256sum_value.data ();
+ b[n].size = &i.sha256sum_size;
+ b[n].capacity = i.sha256sum_value.capacity ();
+ b[n].is_null = &i.sha256sum_null;
+ n++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ bind (sqlite::bind* b, id_image_type& i)
+ {
+ std::size_t n (0);
+ sqlite::statement_kind sk (sqlite::statement_select);
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::bind (
+ b + n, i.id_value, sk);
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ init (image_type& i,
+ const object_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // id
+ //
+ if (sk == statement_insert)
+ {
+ ::bpkg::available_package_id const& v =
+ o.id;
+
+ if (composite_value_traits< ::bpkg::available_package_id, id_sqlite >::init (
+ i.id_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ // version
+ //
+ {
+ ::bpkg::available_package::upstream_version_type const& v =
+ o.version;
+
+ if (composite_value_traits< ::bpkg::available_package::upstream_version_type, id_sqlite >::init (
+ i.version_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ // upstream_version
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.upstream_version;
+
+ bool is_null (true);
+ std::size_t cap (i.upstream_version_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.upstream_version_value,
+ i.upstream_version_size,
+ is_null,
+ v);
+ i.upstream_version_null = is_null;
+ grew = grew || (cap != i.upstream_version_value.capacity ());
+ }
+
+ // type
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.type;
+
+ bool is_null (true);
+ std::size_t cap (i.type_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.type_value,
+ i.type_size,
+ is_null,
+ v);
+ i.type_null = is_null;
+ grew = grew || (cap != i.type_value.capacity ());
+ }
+
+ // project
+ //
+ {
+ ::butl::optional< ::butl::project_name > const& v =
+ o.project;
+
+ bool is_null (true);
+ std::size_t cap (i.project_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::butl::project_name >,
+ sqlite::id_text >::set_image (
+ i.project_value,
+ i.project_size,
+ is_null,
+ v);
+ i.project_null = is_null;
+ grew = grew || (cap != i.project_value.capacity ());
+ }
+
+ // alt_naming
+ //
+ {
+ ::butl::optional< bool > const& v =
+ o.alt_naming;
+
+ bool is_null (true);
+ sqlite::value_traits<
+ ::butl::optional< bool >,
+ sqlite::id_integer >::set_image (
+ i.alt_naming_value,
+ is_null,
+ v);
+ i.alt_naming_null = is_null;
+ }
+
+ // bootstrap_build
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.bootstrap_build;
+
+ bool is_null (true);
+ std::size_t cap (i.bootstrap_build_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.bootstrap_build_value,
+ i.bootstrap_build_size,
+ is_null,
+ v);
+ i.bootstrap_build_null = is_null;
+ grew = grew || (cap != i.bootstrap_build_value.capacity ());
+ }
+
+ // root_build
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.root_build;
+
+ bool is_null (true);
+ std::size_t cap (i.root_build_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.root_build_value,
+ i.root_build_size,
+ is_null,
+ v);
+ i.root_build_null = is_null;
+ grew = grew || (cap != i.root_build_value.capacity ());
+ }
+
+ // sha256sum
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.sha256sum;
+
+ bool is_null (true);
+ std::size_t cap (i.sha256sum_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.sha256sum_value,
+ i.sha256sum_size,
+ is_null,
+ v);
+ i.sha256sum_null = is_null;
+ grew = grew || (cap != i.sha256sum_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ init (object_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // id
+ //
+ {
+ ::bpkg::available_package_id& v =
+ o.id;
+
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::init (
+ v,
+ i.id_value,
+ db);
+ }
+
+ // version
+ //
+ {
+ // From package.hxx:830:32
+ ::bpkg::available_package::upstream_version_type v;
+
+ composite_value_traits< ::bpkg::available_package::upstream_version_type, id_sqlite >::init (
+ v,
+ i.version_value,
+ db);
+
+ // From package.hxx:830:32
+ o.version.init (o.id.version, (v));
+ }
+
+ // upstream_version
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.upstream_version;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.upstream_version_value,
+ i.upstream_version_size,
+ i.upstream_version_null);
+ }
+
+ // type
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.type;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.type_value,
+ i.type_size,
+ i.type_null);
+ }
+
+ // project
+ //
+ {
+ ::butl::optional< ::butl::project_name >& v =
+ o.project;
+
+ sqlite::value_traits<
+ ::butl::optional< ::butl::project_name >,
+ sqlite::id_text >::set_value (
+ v,
+ i.project_value,
+ i.project_size,
+ i.project_null);
+ }
+
+ // alt_naming
+ //
+ {
+ ::butl::optional< bool >& v =
+ o.alt_naming;
+
+ sqlite::value_traits<
+ ::butl::optional< bool >,
+ sqlite::id_integer >::set_value (
+ v,
+ i.alt_naming_value,
+ i.alt_naming_null);
+ }
+
+ // bootstrap_build
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.bootstrap_build;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.bootstrap_build_value,
+ i.bootstrap_build_size,
+ i.bootstrap_build_null);
+ }
+
+ // root_build
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.root_build;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.root_build_value,
+ i.root_build_size,
+ i.root_build_null);
+ }
+
+ // sha256sum
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.sha256sum;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.sha256sum_value,
+ i.sha256sum_size,
+ i.sha256sum_null);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ init (id_image_type& i, const id_type& id)
+ {
+ bool grew (false);
+ sqlite::statement_kind sk (sqlite::statement_select);
+ {
+ if (composite_value_traits< ::bpkg::available_package_id, id_sqlite >::init (
+ i.id_value,
+ id,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::persist_statement[] =
+ "INSERT INTO \"main\".\"available_package\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"version_upstream\", "
+ "\"version_release\", "
+ "\"upstream_version\", "
+ "\"type\", "
+ "\"project\", "
+ "\"alt_naming\", "
+ "\"bootstrap_build\", "
+ "\"root_build\", "
+ "\"sha256sum\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::find_statement[] =
+ "SELECT "
+ "\"main\".\"available_package\".\"name\", "
+ "\"main\".\"available_package\".\"version_epoch\", "
+ "\"main\".\"available_package\".\"version_canonical_upstream\", "
+ "\"main\".\"available_package\".\"version_canonical_release\", "
+ "\"main\".\"available_package\".\"version_revision\", "
+ "\"main\".\"available_package\".\"version_iteration\", "
+ "\"main\".\"available_package\".\"version_upstream\", "
+ "\"main\".\"available_package\".\"version_release\", "
+ "\"main\".\"available_package\".\"upstream_version\", "
+ "\"main\".\"available_package\".\"type\", "
+ "\"main\".\"available_package\".\"project\", "
+ "\"main\".\"available_package\".\"alt_naming\", "
+ "\"main\".\"available_package\".\"bootstrap_build\", "
+ "\"main\".\"available_package\".\"root_build\", "
+ "\"main\".\"available_package\".\"sha256sum\" "
+ "FROM \"main\".\"available_package\" "
+ "WHERE \"main\".\"available_package\".\"name\"=? AND \"main\".\"available_package\".\"version_epoch\"=? AND \"main\".\"available_package\".\"version_canonical_upstream\"=? AND \"main\".\"available_package\".\"version_canonical_release\"=? AND \"main\".\"available_package\".\"version_revision\"=? AND \"main\".\"available_package\".\"version_iteration\"=?";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::update_statement[] =
+ "UPDATE \"main\".\"available_package\" "
+ "SET "
+ "\"version_upstream\"=?, "
+ "\"version_release\"=?, "
+ "\"upstream_version\"=?, "
+ "\"type\"=?, "
+ "\"project\"=?, "
+ "\"alt_naming\"=?, "
+ "\"bootstrap_build\"=?, "
+ "\"root_build\"=?, "
+ "\"sha256sum\"=? "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::erase_statement[] =
+ "DELETE FROM \"main\".\"available_package\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::query_statement[] =
+ "SELECT "
+ "\"main\".\"available_package\".\"name\", "
+ "\"main\".\"available_package\".\"version_epoch\", "
+ "\"main\".\"available_package\".\"version_canonical_upstream\", "
+ "\"main\".\"available_package\".\"version_canonical_release\", "
+ "\"main\".\"available_package\".\"version_revision\", "
+ "\"main\".\"available_package\".\"version_iteration\", "
+ "\"main\".\"available_package\".\"version_upstream\", "
+ "\"main\".\"available_package\".\"version_release\", "
+ "\"main\".\"available_package\".\"upstream_version\", "
+ "\"main\".\"available_package\".\"type\", "
+ "\"main\".\"available_package\".\"project\", "
+ "\"main\".\"available_package\".\"alt_naming\", "
+ "\"main\".\"available_package\".\"bootstrap_build\", "
+ "\"main\".\"available_package\".\"root_build\", "
+ "\"main\".\"available_package\".\"sha256sum\" "
+ "FROM \"main\".\"available_package\"";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::erase_query_statement[] =
+ "DELETE FROM \"main\".\"available_package\"";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::table_name[] =
+ "\"main\".\"available_package\"";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ persist (database& db, const object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ callback (db,
+ obj,
+ callback_event::pre_persist);
+
+ image_type& im (sts.image ());
+ binding& imb (sts.insert_image_binding ());
+
+ if (init (im, obj, statement_insert))
+ im.version++;
+
+ if (im.version != sts.insert_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_insert);
+ sts.insert_image_version (im.version);
+ imb.version++;
+ }
+
+ insert_statement& st (sts.persist_statement ());
+ if (!st.execute ())
+ throw object_already_persistent ();
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // languages
+ //
+ {
+ ::butl::small_vector< ::bpkg::language, 1 > const& v =
+ obj.languages;
+
+ languages_traits::persist (
+ v,
+ esc.languages);
+ }
+
+ // locations
+ //
+ {
+ ::butl::small_vector< ::bpkg::package_location, 1 > const& v =
+ obj.locations;
+
+ locations_traits::persist (
+ v,
+ esc.locations);
+ }
+
+ // dependencies
+ //
+ {
+ ::bpkg::available_package::dependencies_type const& v =
+ obj.dependencies;
+
+ dependencies_traits::persist (
+ v,
+ esc.dependencies);
+ }
+
+ // dependency_alternatives
+ //
+ {
+ // From package.hxx:868:7
+ ::std::map< ::odb::nested_key< ::bpkg::dependency_alternatives_ex >, ::bpkg::dependency_alternative > const& v =
+ odb::nested_get (obj.dependencies);
+
+ dependency_alternatives_traits::persist (
+ v,
+ esc.dependency_alternatives);
+ }
+
+ // dependency_alternative_dependencies
+ //
+ {
+ // From package.hxx:886:7
+ ::std::map< ::odb::nested2_key< ::bpkg::dependency_alternatives_ex >, ::bpkg::dependency > const& v =
+ odb::nested2_get (obj.dependencies);
+
+ dependency_alternative_dependencies_traits::persist (
+ v,
+ esc.dependency_alternative_dependencies);
+ }
+
+ // tests
+ //
+ {
+ ::butl::small_vector< ::bpkg::test_dependency, 1 > const& v =
+ obj.tests;
+
+ tests_traits::persist (
+ v,
+ esc.tests);
+ }
+
+ // buildfiles
+ //
+ {
+ ::std::vector< ::bpkg::buildfile > const& v =
+ obj.buildfiles;
+
+ buildfiles_traits::persist (
+ v,
+ esc.buildfiles);
+ }
+
+ // distribution_values
+ //
+ {
+ ::std::vector< ::bpkg::distribution_name_value > const& v =
+ obj.distribution_values;
+
+ distribution_values_traits::persist (
+ v,
+ esc.distribution_values);
+ }
+
+ obj.languages_section.reset (true, false);
+
+ callback (db,
+ obj,
+ callback_event::post_persist);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ update (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+ using sqlite::update_statement;
+
+ callback (db, obj, callback_event::pre_update);
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ sqlite::connection& conn (tr.connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& idi (sts.id_image ());
+ init (idi, id (obj));
+
+ image_type& im (sts.image ());
+ if (init (im, obj, statement_update))
+ im.version++;
+
+ bool u (false);
+ binding& imb (sts.update_image_binding ());
+ if (im.version != sts.update_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_update);
+ sts.update_image_version (im.version);
+ imb.version++;
+ u = true;
+ }
+
+ binding& idb (sts.id_image_binding ());
+ if (idi.version != sts.update_id_image_version () ||
+ idb.version == 0)
+ {
+ if (idi.version != sts.id_image_version () ||
+ idb.version == 0)
+ {
+ bind (idb.bind, idi);
+ sts.id_image_version (idi.version);
+ idb.version++;
+ }
+
+ sts.update_id_image_version (idi.version);
+
+ if (!u)
+ imb.version++;
+ }
+
+ update_statement& st (sts.update_statement ());
+ if (st.execute () == 0)
+ throw object_not_persistent ();
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // locations
+ //
+ {
+ ::butl::small_vector< ::bpkg::package_location, 1 > const& v =
+ obj.locations;
+
+ locations_traits::update (
+ v,
+ esc.locations);
+ }
+
+ // dependencies
+ //
+ {
+ ::bpkg::available_package::dependencies_type const& v =
+ obj.dependencies;
+
+ dependencies_traits::update (
+ v,
+ esc.dependencies);
+ }
+
+ // dependency_alternatives
+ //
+ {
+ // From package.hxx:868:7
+ ::std::map< ::odb::nested_key< ::bpkg::dependency_alternatives_ex >, ::bpkg::dependency_alternative > const& v =
+ odb::nested_get (obj.dependencies);
+
+ dependency_alternatives_traits::update (
+ v,
+ esc.dependency_alternatives);
+ }
+
+ // dependency_alternative_dependencies
+ //
+ {
+ // From package.hxx:886:7
+ ::std::map< ::odb::nested2_key< ::bpkg::dependency_alternatives_ex >, ::bpkg::dependency > const& v =
+ odb::nested2_get (obj.dependencies);
+
+ dependency_alternative_dependencies_traits::update (
+ v,
+ esc.dependency_alternative_dependencies);
+ }
+
+ // tests
+ //
+ {
+ ::butl::small_vector< ::bpkg::test_dependency, 1 > const& v =
+ obj.tests;
+
+ tests_traits::update (
+ v,
+ esc.tests);
+ }
+
+ // buildfiles
+ //
+ {
+ ::std::vector< ::bpkg::buildfile > const& v =
+ obj.buildfiles;
+
+ buildfiles_traits::update (
+ v,
+ esc.buildfiles);
+ }
+
+ // distribution_values
+ //
+ {
+ ::std::vector< ::bpkg::distribution_name_value > const& v =
+ obj.distribution_values;
+
+ distribution_values_traits::update (
+ v,
+ esc.distribution_values);
+ }
+
+ if (obj.languages_section.loaded ())
+ {
+ languages_section_traits::update (esc, obj);
+ }
+
+ callback (db, obj, callback_event::post_update);
+ pointer_cache_traits::update (db, obj);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ erase (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // languages
+ //
+ {
+ languages_traits::erase (
+ esc.languages);
+ }
+
+ // locations
+ //
+ {
+ locations_traits::erase (
+ esc.locations);
+ }
+
+ // dependencies
+ //
+ {
+ dependencies_traits::erase (
+ esc.dependencies);
+ }
+
+ // dependency_alternatives
+ //
+ {
+ dependency_alternatives_traits::erase (
+ esc.dependency_alternatives);
+ }
+
+ // dependency_alternative_dependencies
+ //
+ {
+ dependency_alternative_dependencies_traits::erase (
+ esc.dependency_alternative_dependencies);
+ }
+
+ // tests
+ //
+ {
+ tests_traits::erase (
+ esc.tests);
+ }
+
+ // buildfiles
+ //
+ {
+ buildfiles_traits::erase (
+ esc.buildfiles);
+ }
+
+ // distribution_values
+ //
+ {
+ distribution_values_traits::erase (
+ esc.distribution_values);
+ }
+
+ if (sts.erase_statement ().execute () != 1)
+ throw object_not_persistent ();
+
+ pointer_cache_traits::erase (db, id);
+ }
+
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::pointer_type
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ find (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ {
+ pointer_type p (pointer_cache_traits::find (db, id));
+
+ if (!pointer_traits::null_ptr (p))
+ return p;
+ }
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+
+ if (l.locked ())
+ {
+ if (!find_ (sts, &id))
+ return pointer_type ();
+ }
+
+ pointer_type p (
+ access::object_factory<object_type, pointer_type>::create ());
+ pointer_traits::guard pg (p);
+
+ pointer_cache_traits::insert_guard ig (
+ pointer_cache_traits::insert (db, id, p));
+
+ object_type& obj (pointer_traits::get_ref (p));
+
+ if (l.locked ())
+ {
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ pointer_cache_traits::load (ig.position ());
+ }
+ else
+ sts.delay_load (id, obj, ig.position ());
+
+ ig.release ();
+ pg.release ();
+ return p;
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ find (database& db, const id_type& id, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ reference_cache_traits::position_type pos (
+ reference_cache_traits::insert (db, id, obj));
+ reference_cache_traits::insert_guard ig (pos);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ reference_cache_traits::load (pos);
+ ig.release ();
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ reload (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ const id_type& id (object_traits_impl::id (obj));
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, true);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ load (connection& conn, object_type& obj, section& s)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& c (static_cast<sqlite::connection&> (conn));
+ statements_type& sts (c.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ bool r (false);
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ if (!r && &s == &obj.languages_section)
+ {
+ languages_section_traits::load (esc, obj);
+ r = true;
+ }
+
+ sts.load_delayed (0);
+ l.unlock ();
+ return r;
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ update (connection& conn, const object_type& obj, const section& s)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& c (static_cast<sqlite::connection&> (conn));
+ statements_type& sts (c.statement_cache ().find_object<object_type> ());
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ if (&s == &obj.languages_section)languages_section_traits::update (esc, obj);
+ else
+ return false;
+
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ find_ (statements_type& sts,
+ const id_type* id)
+ {
+ using namespace sqlite;
+
+ id_image_type& i (sts.id_image ());
+ init (i, *id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ select_statement& st (sts.find_statement ());
+
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ if (grow (im, sts.select_image_truncated ()))
+ im.version++;
+
+ if (im.version != sts.select_image_version ())
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ load_ (statements_type& sts,
+ object_type& obj,
+ bool reload)
+ {
+ ODB_POTENTIALLY_UNUSED (reload);
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // locations
+ //
+ {
+ ::butl::small_vector< ::bpkg::package_location, 1 >& v =
+ obj.locations;
+
+ locations_traits::load (
+ v,
+ esc.locations);
+ }
+
+ // dependencies
+ //
+ {
+ ::bpkg::available_package::dependencies_type& v =
+ obj.dependencies;
+
+ dependencies_traits::load (
+ v,
+ esc.dependencies);
+ }
+
+ // dependency_alternatives
+ //
+ {
+ ::std::map< ::odb::nested_key< ::bpkg::dependency_alternatives_ex >, ::bpkg::dependency_alternative > v;
+
+ dependency_alternatives_traits::load (
+ v,
+ esc.dependency_alternatives);
+
+ // From package.hxx:869:7
+ odb::nested_set (obj.dependencies, std::move (v));
+ }
+
+ // dependency_alternative_dependencies
+ //
+ {
+ ::std::map< ::odb::nested2_key< ::bpkg::dependency_alternatives_ex >, ::bpkg::dependency > v;
+
+ dependency_alternative_dependencies_traits::load (
+ v,
+ esc.dependency_alternative_dependencies);
+
+ // From package.hxx:887:7
+ odb::nested2_set (obj.dependencies, std::move (v));
+ }
+
+ // tests
+ //
+ {
+ ::butl::small_vector< ::bpkg::test_dependency, 1 >& v =
+ obj.tests;
+
+ tests_traits::load (
+ v,
+ esc.tests);
+ }
+
+ // buildfiles
+ //
+ {
+ ::std::vector< ::bpkg::buildfile >& v =
+ obj.buildfiles;
+
+ buildfiles_traits::load (
+ v,
+ esc.buildfiles);
+ }
+
+ // distribution_values
+ //
+ {
+ ::std::vector< ::bpkg::distribution_name_value >& v =
+ obj.distribution_values;
+
+ distribution_values_traits::load (
+ v,
+ esc.distribution_values);
+ }
+
+ if (reload)
+ {
+ if (obj.languages_section.loaded ())
+ {
+ languages_section_traits::load (esc, obj);
+ obj.languages_section.reset (true, false);
+ }
+ }
+ else
+ obj.languages_section.reset ();
+ }
+
+ result< access::object_traits_impl< ::bpkg::available_package, id_sqlite >::object_type >
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ q.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::object_result_impl<object_type> > r (
+ new (shared) sqlite::object_result_impl<object_type> (
+ q, st, sts, 0));
+
+ return result<object_type> (r);
+ }
+
+ unsigned long long access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ erase_query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ std::string text (erase_query_statement);
+ if (!q.empty ())
+ {
+ text += ' ';
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ delete_statement st (
+ conn,
+ text,
+ q.parameters_binding ());
+
+ return st.execute ();
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = q;
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::object_result_impl<object_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // available_package_count
+ //
+
+ bool access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // result
+ //
+ t[0UL] = false;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // result
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.result_value;
+ b[n].is_null = &i.result_null;
+ n++;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // result
+ //
+ {
+ ::std::size_t& v =
+ o.result;
+
+ sqlite::value_traits<
+ ::std::size_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.result_value,
+ i.result_null);
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "count(*) ");
+
+ r += "FROM \"main\".\"available_package\"";
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // available_test
+ //
+
+ const char alias_traits< ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::package_tag>::
+ table_name[] = "\"package\"";
+
+ bool access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // package
+ //
+ if (object_traits_impl< ::bpkg::available_package, id_sqlite >::grow (
+ i.package_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // package
+ //
+ object_traits_impl< ::bpkg::available_package, id_sqlite >::bind (
+ b + n, i.package_value, sk);
+ n += 15UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (*db));
+
+ // package pre
+ //
+ typedef ::bpkg::available_package package_object_type;
+ typedef object_traits_impl<package_object_type, id_sqlite> package_object_traits;
+ typedef package_object_traits::pointer_type package_pointer_type;
+ typedef package_object_traits::pointer_traits package_pointer_traits;
+ typedef package_object_traits::pointer_cache_traits package_cache_traits;
+
+ package_object_traits::id_type package_id;
+ package_pointer_type package_p;
+ package_pointer_traits::guard package_pg;
+ package_cache_traits::insert_guard package_ig;
+ package_object_type* package_o (0);
+
+ {
+ if (!composite_value_traits< package_object_traits::id_type, id_sqlite >::get_null (
+ i.package_value.id_value))
+ {
+ package_id = package_object_traits::id (i.package_value);
+ package_p = package_cache_traits::find (*db, package_id);
+
+ if (package_pointer_traits::null_ptr (package_p))
+ {
+ package_p = object_factory<package_object_type, package_pointer_type>::create ();
+ package_pg.reset (package_p);
+ package_ig.reset (package_cache_traits::insert (*db, package_id, package_p));
+ package_o = package_pointer_traits::get_ptr (package_p);
+ }
+ }
+ }
+
+ // package
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::pre_load);
+ package_object_traits::init (*package_o, i.package_value, db);
+ package_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<package_object_type> ());
+ package_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ package_object_traits::id_image_type& i (sts.id_image ());
+ package_object_traits::init (i, package_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ package_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ package_object_traits::load_ (sts, *package_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // package post
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::post_load);
+ package_cache_traits::load (package_ig.position ());
+ package_ig.release ();
+ package_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.package = ::std::shared_ptr< ::bpkg::available_package > (
+ std::move (package_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"package\".\"name\", "
+ "\"package\".\"version_epoch\", "
+ "\"package\".\"version_canonical_upstream\", "
+ "\"package\".\"version_canonical_release\", "
+ "\"package\".\"version_revision\", "
+ "\"package\".\"version_iteration\", "
+ "\"package\".\"version_upstream\", "
+ "\"package\".\"version_release\", "
+ "\"package\".\"upstream_version\", "
+ "\"package\".\"type\", "
+ "\"package\".\"project\", "
+ "\"package\".\"alt_naming\", "
+ "\"package\".\"bootstrap_build\", "
+ "\"package\".\"root_build\", "
+ "\"package\".\"sha256sum\" ");
+
+ r += "FROM \"main\".\"available_package\" AS \"package\"";
+
+ r += " INNER JOIN \"main\".\"available_package_dependencies\" AS \"pd\" ON";
+ // From package.hxx:952:5
+ r += "pd.type IN ('tests', 'examples', 'benchmarks') AND pd.name = " + query_columns::id.name + "AND" + "pd.version_epoch = " + query_columns::id.version.epoch + "AND" + "pd.version_canonical_upstream = " + query_columns::id.version.canonical_upstream + "AND" + "pd.version_canonical_release = " + query_columns::id.version.canonical_release + "AND" + "pd.version_revision = " + query_columns::id.version.revision + "AND" + "pd.version_iteration = " + query_columns::id.version.iteration;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::available_test, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // available_main
+ //
+
+ const char alias_traits< ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::package_tag>::
+ table_name[] = "\"package\"";
+
+ bool access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // package
+ //
+ if (object_traits_impl< ::bpkg::available_package, id_sqlite >::grow (
+ i.package_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // package
+ //
+ object_traits_impl< ::bpkg::available_package, id_sqlite >::bind (
+ b + n, i.package_value, sk);
+ n += 15UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (*db));
+
+ // package pre
+ //
+ typedef ::bpkg::available_package package_object_type;
+ typedef object_traits_impl<package_object_type, id_sqlite> package_object_traits;
+ typedef package_object_traits::pointer_type package_pointer_type;
+ typedef package_object_traits::pointer_traits package_pointer_traits;
+ typedef package_object_traits::pointer_cache_traits package_cache_traits;
+
+ package_object_traits::id_type package_id;
+ package_pointer_type package_p;
+ package_pointer_traits::guard package_pg;
+ package_cache_traits::insert_guard package_ig;
+ package_object_type* package_o (0);
+
+ {
+ if (!composite_value_traits< package_object_traits::id_type, id_sqlite >::get_null (
+ i.package_value.id_value))
+ {
+ package_id = package_object_traits::id (i.package_value);
+ package_p = package_cache_traits::find (*db, package_id);
+
+ if (package_pointer_traits::null_ptr (package_p))
+ {
+ package_p = object_factory<package_object_type, package_pointer_type>::create ();
+ package_pg.reset (package_p);
+ package_ig.reset (package_cache_traits::insert (*db, package_id, package_p));
+ package_o = package_pointer_traits::get_ptr (package_p);
+ }
+ }
+ }
+
+ // package
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::pre_load);
+ package_object_traits::init (*package_o, i.package_value, db);
+ package_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<package_object_type> ());
+ package_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ package_object_traits::id_image_type& i (sts.id_image ());
+ package_object_traits::init (i, package_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ package_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ package_object_traits::load_ (sts, *package_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // package post
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::post_load);
+ package_cache_traits::load (package_ig.position ());
+ package_ig.release ();
+ package_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.package = ::std::shared_ptr< ::bpkg::available_package > (
+ std::move (package_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT DISTINCT "
+ "\"package\".\"name\", "
+ "\"package\".\"version_epoch\", "
+ "\"package\".\"version_canonical_upstream\", "
+ "\"package\".\"version_canonical_release\", "
+ "\"package\".\"version_revision\", "
+ "\"package\".\"version_iteration\", "
+ "\"package\".\"version_upstream\", "
+ "\"package\".\"version_release\", "
+ "\"package\".\"upstream_version\", "
+ "\"package\".\"type\", "
+ "\"package\".\"project\", "
+ "\"package\".\"alt_naming\", "
+ "\"package\".\"bootstrap_build\", "
+ "\"package\".\"root_build\", "
+ "\"package\".\"sha256sum\" ");
+
+ r += "FROM \"main\".\"available_package\" AS \"package\"";
+
+ r += " INNER JOIN \"main\".\"available_package_tests\" AS \"pt\" ON";
+ // From package.hxx:971:5
+ r += "pt.name = " + query_columns::id.name + "AND" + "pt.version_epoch = " + query_columns::id.version.epoch + "AND" + "pt.version_canonical_upstream = " + query_columns::id.version.canonical_upstream + "AND" + "pt.version_canonical_release = " + query_columns::id.version.canonical_release + "AND" + "pt.version_revision = " + query_columns::id.version.revision + "AND" + "pt.version_iteration = " + query_columns::id.version.iteration;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::available_main, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // prerequisite_info
+ //
+
+ bool access::composite_value_traits< ::bpkg::prerequisite_info, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // constraint
+ //
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::grow (
+ i.constraint_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::prerequisite_info, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // constraint
+ //
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::bind (
+ b + n, i.constraint_value, sk);
+ n += 16UL;
+ }
+
+ bool access::composite_value_traits< ::bpkg::prerequisite_info, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // constraint
+ //
+ {
+ ::butl::optional< ::bpkg::version_constraint > const& v =
+ o.constraint;
+
+ if (wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::get_null (v))
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::set_null (
+ i.constraint_value, sk);
+ else
+ {
+ const::bpkg::version_constraint& vw =
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::get_ref (v);
+
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::init (
+ i.constraint_value,
+ vw,
+ sk))
+ grew = true;
+ }
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::prerequisite_info, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // constraint
+ //
+ {
+ ::butl::optional< ::bpkg::version_constraint >& v =
+ o.constraint;
+
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::get_null (
+ i.constraint_value))
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::set_null (v);
+ else
+ {
+ ::bpkg::version_constraint& vw =
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::set_ref (v);
+
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::init (
+ vw,
+ i.constraint_value,
+ db);
+ }
+ }
+ }
+
+ // _selected_package_ref
+ //
+
+ bool access::composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // configuration
+ //
+ if (t[0UL])
+ {
+ i.configuration_value.capacity (i.configuration_size);
+ grew = true;
+ }
+
+ // prerequisite
+ //
+ if (t[1UL])
+ {
+ i.prerequisite_value.capacity (i.prerequisite_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // configuration
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.configuration_value.data ();
+ b[n].size = &i.configuration_size;
+ b[n].capacity = i.configuration_value.capacity ();
+ b[n].is_null = &i.configuration_null;
+ n++;
+
+ // prerequisite
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::package_name,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.prerequisite_value.data ();
+ b[n].size = &i.prerequisite_size;
+ b[n].capacity = i.prerequisite_value.capacity ();
+ b[n].is_null = &i.prerequisite_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // configuration
+ //
+ {
+ ::butl::uuid const& v =
+ o.configuration;
+
+ // From package.hxx:66:14
+ ::std::string const& vt =
+ (v).string ();
+
+ bool is_null (false);
+ std::size_t cap (i.configuration_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.configuration_value,
+ i.configuration_size,
+ is_null,
+ vt);
+ i.configuration_null = is_null;
+ grew = grew || (cap != i.configuration_value.capacity ());
+ }
+
+ // prerequisite
+ //
+ {
+ ::bpkg::package_name const& v =
+ o.prerequisite;
+
+ bool is_null (false);
+ std::size_t cap (i.prerequisite_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_image (
+ i.prerequisite_value,
+ i.prerequisite_size,
+ is_null,
+ v);
+ i.prerequisite_null = is_null;
+ grew = grew || (cap != i.prerequisite_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // configuration
+ //
+ {
+ ::butl::uuid& v =
+ o.configuration;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.configuration_value,
+ i.configuration_size,
+ i.configuration_null);
+
+ // From package.hxx:66:14
+ v = bpkg::uuid (vt);
+ }
+
+ // prerequisite
+ //
+ {
+ ::bpkg::package_name& v =
+ o.prerequisite;
+
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_value (
+ v,
+ i.prerequisite_value,
+ i.prerequisite_size,
+ i.prerequisite_null);
+ }
+ }
+
+ // config_variable
+ //
+
+ bool access::composite_value_traits< ::bpkg::config_variable, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // name
+ //
+ if (t[0UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // source
+ //
+ if (t[1UL])
+ {
+ i.source_value.capacity (i.source_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::config_variable, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (b);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+ ODB_POTENTIALLY_UNUSED (n);
+
+ // name
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.name_value.data ();
+ b[n].size = &i.name_size;
+ b[n].capacity = i.name_value.capacity ();
+ b[n].is_null = &i.name_null;
+ n++;
+
+ // source
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.source_value.data ();
+ b[n].size = &i.source_size;
+ b[n].capacity = i.source_value.capacity ();
+ b[n].is_null = &i.source_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::config_variable, id_sqlite >::
+ init (image_type& i,
+ const value_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // name
+ //
+ {
+ ::std::string const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.name_value,
+ i.name_size,
+ is_null,
+ v);
+ i.name_null = is_null;
+ grew = grew || (cap != i.name_value.capacity ());
+ }
+
+ // source
+ //
+ {
+ ::bpkg::config_source const& v =
+ o.source;
+
+ // From package.hxx:1151:14
+ ::std::string const& vt =
+ to_string (v);
+
+ bool is_null (false);
+ std::size_t cap (i.source_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.source_value,
+ i.source_size,
+ is_null,
+ vt);
+ i.source_null = is_null;
+ grew = grew || (cap != i.source_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::config_variable, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // name
+ //
+ {
+ ::std::string& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // source
+ //
+ {
+ ::bpkg::config_source& v =
+ o.source;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.source_value,
+ i.source_size,
+ i.source_null);
+
+ // From package.hxx:1151:14
+ v = bpkg::to_config_source (vt);
+ }
+ }
+
+ // selected_package
+ //
+
+ struct access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::extra_statement_cache_type
+ {
+ sqlite::container_statements_impl< prerequisites_traits > prerequisites;
+ sqlite::container_statements_impl< dependency_alternatives_traits > dependency_alternatives;
+ sqlite::container_statements_impl< config_variables_traits > config_variables;
+
+ sqlite::section_statements< ::bpkg::selected_package, dependency_alternatives_section_traits > dependency_alternatives_section;
+
+ extra_statement_cache_type (
+ sqlite::connection& c,
+ image_type& im,
+ id_image_type& idim,
+ sqlite::binding& id,
+ sqlite::binding& idv)
+ : prerequisites (c, id),
+ dependency_alternatives (c, id),
+ config_variables (c, id),
+ dependency_alternatives_section (c, im, idim, id, idv)
+ {
+ }
+ };
+
+ // prerequisites
+ //
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"selected_package_prerequisites\".\"configuration\", "
+ "\"main\".\"selected_package_prerequisites\".\"prerequisite\", "
+ "\"main\".\"selected_package_prerequisites\".\"min_version_epoch\", "
+ "\"main\".\"selected_package_prerequisites\".\"min_version_canonical_upstream\", "
+ "\"main\".\"selected_package_prerequisites\".\"min_version_canonical_release\", "
+ "\"main\".\"selected_package_prerequisites\".\"min_version_revision\", "
+ "\"main\".\"selected_package_prerequisites\".\"min_version_iteration\", "
+ "\"main\".\"selected_package_prerequisites\".\"min_version_upstream\", "
+ "\"main\".\"selected_package_prerequisites\".\"min_version_release\", "
+ "\"main\".\"selected_package_prerequisites\".\"max_version_epoch\", "
+ "\"main\".\"selected_package_prerequisites\".\"max_version_canonical_upstream\", "
+ "\"main\".\"selected_package_prerequisites\".\"max_version_canonical_release\", "
+ "\"main\".\"selected_package_prerequisites\".\"max_version_revision\", "
+ "\"main\".\"selected_package_prerequisites\".\"max_version_iteration\", "
+ "\"main\".\"selected_package_prerequisites\".\"max_version_upstream\", "
+ "\"main\".\"selected_package_prerequisites\".\"max_version_release\", "
+ "\"main\".\"selected_package_prerequisites\".\"min_open\", "
+ "\"main\".\"selected_package_prerequisites\".\"max_open\" "
+ "FROM \"main\".\"selected_package_prerequisites\" "
+ "WHERE \"main\".\"selected_package_prerequisites\".\"package\"=?";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"selected_package_prerequisites\" "
+ "(\"package\", "
+ "\"configuration\", "
+ "\"prerequisite\", "
+ "\"min_version_epoch\", "
+ "\"min_version_canonical_upstream\", "
+ "\"min_version_canonical_release\", "
+ "\"min_version_revision\", "
+ "\"min_version_iteration\", "
+ "\"min_version_upstream\", "
+ "\"min_version_release\", "
+ "\"max_version_epoch\", "
+ "\"max_version_canonical_upstream\", "
+ "\"max_version_canonical_release\", "
+ "\"max_version_revision\", "
+ "\"max_version_iteration\", "
+ "\"max_version_upstream\", "
+ "\"max_version_release\", "
+ "\"min_open\", "
+ "\"max_open\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"selected_package_prerequisites\" "
+ "WHERE \"package\"=?";
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // key
+ //
+ composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >::bind (
+ b + n, d.key_value, sk);
+ n += 2UL;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // key
+ //
+ if (composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >::grow (
+ i.key_value, t + 0UL))
+ grew = true;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 2UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ init (data_image_type& i,
+ const key_type* k,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // key
+ //
+ if (k != 0)
+ {
+ // From package.hxx:1133:14
+ ::bpkg::_selected_package_ref const& vt =
+ bpkg::_selected_package_ref (*k);
+
+ if (composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >::init (
+ i.key_value,
+ vt,
+ sk))
+ grew = true;
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ init (key_type& k,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // key
+ //
+ {
+ ::bpkg::_selected_package_ref vt;
+
+ composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >::init (
+ vt,
+ i.key_value,
+ db);
+
+ // From package.hxx:1133:14
+ k = std::move (vt).to_ptr ( * db);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ insert (const key_type& k, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &k, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ select (key_type& k, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (k, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::erase (fs);
+ }
+
+ // dependency_alternatives
+ //
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"selected_package_dependency_alternatives\".\"index\", "
+ "\"main\".\"selected_package_dependency_alternatives\".\"position\" "
+ "FROM \"main\".\"selected_package_dependency_alternatives\" "
+ "WHERE \"main\".\"selected_package_dependency_alternatives\".\"package\"=? ORDER BY \"main\".\"selected_package_dependency_alternatives\".\"index\"";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"selected_package_dependency_alternatives\" "
+ "(\"package\", "
+ "\"index\", "
+ "\"position\") "
+ "VALUES "
+ "(?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"selected_package_dependency_alternatives\" "
+ "WHERE \"package\"=?";
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // index
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.index_value;
+ b[n].is_null = &d.index_null;
+ n++;
+
+ // value
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.value_value;
+ b[n].is_null = &d.value_null;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // index
+ //
+ t[0UL] = false;
+
+ // value
+ //
+ t[1UL] = false;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ init (data_image_type& i,
+ index_type* j,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // index
+ //
+ if (j != 0)
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_image (
+ i.index_value,
+ is_null,
+ *j);
+ i.index_null = is_null;
+ }
+
+ // value
+ //
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ value_type,
+ sqlite::id_integer >::set_image (
+ i.value_value,
+ is_null,
+ v);
+ i.value_null = is_null;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ init (index_type& j,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // index
+ //
+ {
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_value (
+ j,
+ i.index_value,
+ i.index_null);
+ }
+
+ // value
+ //
+ {
+ sqlite::value_traits<
+ value_type,
+ sqlite::id_integer >::set_value (
+ v,
+ i.value_value,
+ i.value_null);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ insert (index_type i, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &i, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ select (index_type& i, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (i, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::erase (fs);
+ }
+
+ // config_variables
+ //
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ select_statement[] =
+ "SELECT "
+ "\"main\".\"selected_package_config_variables\".\"index\", "
+ "\"main\".\"selected_package_config_variables\".\"name\", "
+ "\"main\".\"selected_package_config_variables\".\"source\" "
+ "FROM \"main\".\"selected_package_config_variables\" "
+ "WHERE \"main\".\"selected_package_config_variables\".\"package\"=? ORDER BY \"main\".\"selected_package_config_variables\".\"index\"";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ insert_statement[] =
+ "INSERT INTO \"main\".\"selected_package_config_variables\" "
+ "(\"package\", "
+ "\"index\", "
+ "\"name\", "
+ "\"source\") "
+ "VALUES "
+ "(?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ delete_statement[] =
+ "DELETE FROM \"main\".\"selected_package_config_variables\" "
+ "WHERE \"package\"=?";
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // index
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.index_value;
+ b[n].is_null = &d.index_null;
+ n++;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // index
+ //
+ t[0UL] = false;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 1UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ init (data_image_type& i,
+ index_type* j,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // index
+ //
+ if (j != 0)
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_image (
+ i.index_value,
+ is_null,
+ *j);
+ i.index_null = is_null;
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ init (index_type& j,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // index
+ //
+ {
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_value (
+ j,
+ i.index_value,
+ i.index_null);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ insert (index_type i, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &i, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ select (index_type& i, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (i, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::config_variables_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::erase (fs);
+ }
+
+ // dependency_alternatives_section
+ //
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_section_traits::
+ load (extra_statement_cache_type& esc, object_type& obj)
+ {
+ // dependency_alternatives
+ //
+ {
+ ::bpkg::selected_package::indexes_type& v =
+ obj.dependency_alternatives;
+
+ dependency_alternatives_traits::load (
+ v,
+ esc.dependency_alternatives);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::dependency_alternatives_section_traits::
+ update (extra_statement_cache_type& esc, const object_type& obj)
+ {
+ // dependency_alternatives
+ //
+ {
+ ::bpkg::selected_package::indexes_type const& v =
+ obj.dependency_alternatives;
+
+ dependency_alternatives_traits::update (
+ v,
+ esc.dependency_alternatives);
+ }
+ }
+
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ id (const image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_value (
+ id,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ return id;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // name
+ //
+ if (t[0UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // version
+ //
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::grow (
+ i.version_value, t + 1UL))
+ grew = true;
+
+ // state
+ //
+ if (t[8UL])
+ {
+ i.state_value.capacity (i.state_size);
+ grew = true;
+ }
+
+ // substate
+ //
+ if (t[9UL])
+ {
+ i.substate_value.capacity (i.substate_size);
+ grew = true;
+ }
+
+ // hold_package
+ //
+ t[10UL] = false;
+
+ // hold_version
+ //
+ t[11UL] = false;
+
+ // repository_fragment
+ //
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::grow (
+ i.repository_fragment_value, t + 12UL))
+ grew = true;
+
+ // archive
+ //
+ if (t[14UL])
+ {
+ i.archive_value.capacity (i.archive_size);
+ grew = true;
+ }
+
+ // purge_archive
+ //
+ t[15UL] = false;
+
+ // src_root
+ //
+ if (t[16UL])
+ {
+ i.src_root_value.capacity (i.src_root_size);
+ grew = true;
+ }
+
+ // purge_src
+ //
+ t[17UL] = false;
+
+ // manifest_checksum
+ //
+ if (t[18UL])
+ {
+ i.manifest_checksum_value.capacity (i.manifest_checksum_size);
+ grew = true;
+ }
+
+ // buildfiles_checksum
+ //
+ if (t[19UL])
+ {
+ i.buildfiles_checksum_value.capacity (i.buildfiles_checksum_size);
+ grew = true;
+ }
+
+ // out_root
+ //
+ if (t[20UL])
+ {
+ i.out_root_value.capacity (i.out_root_size);
+ grew = true;
+ }
+
+ // config_checksum
+ //
+ if (t[21UL])
+ {
+ i.config_checksum_value.capacity (i.config_checksum_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+
+ // name
+ //
+ if (sk != statement_update)
+ {
+ b[n].type = sqlite::image_traits<
+ ::bpkg::package_name,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.name_value.data ();
+ b[n].size = &i.name_size;
+ b[n].capacity = i.name_value.capacity ();
+ b[n].is_null = &i.name_null;
+ n++;
+ }
+
+ // version
+ //
+ composite_value_traits< ::bpkg::_version, id_sqlite >::bind (
+ b + n, i.version_value, sk);
+ n += 7UL;
+
+ // state
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.state_value.data ();
+ b[n].size = &i.state_size;
+ b[n].capacity = i.state_value.capacity ();
+ b[n].is_null = &i.state_null;
+ n++;
+
+ // substate
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.substate_value.data ();
+ b[n].size = &i.substate_size;
+ b[n].capacity = i.substate_value.capacity ();
+ b[n].is_null = &i.substate_null;
+ n++;
+
+ // hold_package
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.hold_package_value;
+ b[n].is_null = &i.hold_package_null;
+ n++;
+
+ // hold_version
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.hold_version_value;
+ b[n].is_null = &i.hold_version_null;
+ n++;
+
+ // repository_fragment
+ //
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::bind (
+ b + n, i.repository_fragment_value, sk);
+ n += 2UL;
+
+ // archive
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.archive_value.data ();
+ b[n].size = &i.archive_size;
+ b[n].capacity = i.archive_value.capacity ();
+ b[n].is_null = &i.archive_null;
+ n++;
+
+ // purge_archive
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.purge_archive_value;
+ b[n].is_null = &i.purge_archive_null;
+ n++;
+
+ // src_root
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.src_root_value.data ();
+ b[n].size = &i.src_root_size;
+ b[n].capacity = i.src_root_value.capacity ();
+ b[n].is_null = &i.src_root_null;
+ n++;
+
+ // purge_src
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.purge_src_value;
+ b[n].is_null = &i.purge_src_null;
+ n++;
+
+ // manifest_checksum
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.manifest_checksum_value.data ();
+ b[n].size = &i.manifest_checksum_size;
+ b[n].capacity = i.manifest_checksum_value.capacity ();
+ b[n].is_null = &i.manifest_checksum_null;
+ n++;
+
+ // buildfiles_checksum
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.buildfiles_checksum_value.data ();
+ b[n].size = &i.buildfiles_checksum_size;
+ b[n].capacity = i.buildfiles_checksum_value.capacity ();
+ b[n].is_null = &i.buildfiles_checksum_null;
+ n++;
+
+ // out_root
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.out_root_value.data ();
+ b[n].size = &i.out_root_size;
+ b[n].capacity = i.out_root_value.capacity ();
+ b[n].is_null = &i.out_root_null;
+ n++;
+
+ // config_checksum
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.config_checksum_value.data ();
+ b[n].size = &i.config_checksum_size;
+ b[n].capacity = i.config_checksum_value.capacity ();
+ b[n].is_null = &i.config_checksum_null;
+ n++;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ bind (sqlite::bind* b, id_image_type& i)
+ {
+ std::size_t n (0);
+ b[n].type = sqlite::image_traits<
+ ::bpkg::package_name,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.id_value.data ();
+ b[n].size = &i.id_size;
+ b[n].capacity = i.id_value.capacity ();
+ b[n].is_null = &i.id_null;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ init (image_type& i,
+ const object_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // name
+ //
+ if (sk == statement_insert)
+ {
+ ::bpkg::package_name const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_image (
+ i.name_value,
+ i.name_size,
+ is_null,
+ v);
+ i.name_null = is_null;
+ grew = grew || (cap != i.name_value.capacity ());
+ }
+
+ // version
+ //
+ {
+ ::bpkg::selected_package::version_type const& v =
+ o.version;
+
+ // From package.hxx:308:14
+ ::bpkg::_version const& vt =
+ bpkg::_version
+ {
+ (v).epoch, (v).canonical_upstream, (v).canonical_release, (v).revision, (v).iteration, (v).upstream, (v).release
+ };
+
+
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ i.version_value,
+ vt,
+ sk))
+ grew = true;
+ }
+
+ // state
+ //
+ {
+ ::bpkg::package_state const& v =
+ o.state;
+
+ // From package.hxx:1018:14
+ ::std::string const& vt =
+ to_string (v);
+
+ bool is_null (false);
+ std::size_t cap (i.state_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.state_value,
+ i.state_size,
+ is_null,
+ vt);
+ i.state_null = is_null;
+ grew = grew || (cap != i.state_value.capacity ());
+ }
+
+ // substate
+ //
+ {
+ ::bpkg::package_substate const& v =
+ o.substate;
+
+ // From package.hxx:1039:14
+ ::std::string const& vt =
+ to_string (v);
+
+ bool is_null (false);
+ std::size_t cap (i.substate_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.substate_value,
+ i.substate_size,
+ is_null,
+ vt);
+ i.substate_null = is_null;
+ grew = grew || (cap != i.substate_value.capacity ());
+ }
+
+ // hold_package
+ //
+ {
+ bool const& v =
+ o.hold_package;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.hold_package_value,
+ is_null,
+ v);
+ i.hold_package_null = is_null;
+ }
+
+ // hold_version
+ //
+ {
+ bool const& v =
+ o.hold_version;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.hold_version_value,
+ is_null,
+ v);
+ i.hold_version_null = is_null;
+ }
+
+ // repository_fragment
+ //
+ {
+ ::bpkg::repository_location const& v =
+ o.repository_fragment;
+
+ // From package.hxx:368:14
+ ::bpkg::_repository_location const& vt =
+ bpkg::_repository_location
+ {
+ (v).url (), (v).empty () ? bpkg::repository_type::pkg : (v).type ()
+ };
+
+
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ i.repository_fragment_value,
+ vt,
+ sk))
+ grew = true;
+ }
+
+ // archive
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::any_path_kind< char > > > const& v =
+ o.archive;
+
+ // From package.hxx:53:14
+ ::bpkg::optional_string const& vt =
+ (v) ? (v)->string () : bpkg::optional_string ();
+
+ bool is_null (true);
+ std::size_t cap (i.archive_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_image (
+ i.archive_value,
+ i.archive_size,
+ is_null,
+ vt);
+ i.archive_null = is_null;
+ grew = grew || (cap != i.archive_value.capacity ());
+ }
+
+ // purge_archive
+ //
+ {
+ bool const& v =
+ o.purge_archive;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.purge_archive_value,
+ is_null,
+ v);
+ i.purge_archive_null = is_null;
+ }
+
+ // src_root
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::dir_path_kind< char > > > const& v =
+ o.src_root;
+
+ // From package.hxx:60:14
+ ::bpkg::optional_string const& vt =
+ (v) ? (v)->string () : bpkg::optional_string ();
+
+ bool is_null (true);
+ std::size_t cap (i.src_root_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_image (
+ i.src_root_value,
+ i.src_root_size,
+ is_null,
+ vt);
+ i.src_root_null = is_null;
+ grew = grew || (cap != i.src_root_value.capacity ());
+ }
+
+ // purge_src
+ //
+ {
+ bool const& v =
+ o.purge_src;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.purge_src_value,
+ is_null,
+ v);
+ i.purge_src_null = is_null;
+ }
+
+ // manifest_checksum
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.manifest_checksum;
+
+ bool is_null (true);
+ std::size_t cap (i.manifest_checksum_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.manifest_checksum_value,
+ i.manifest_checksum_size,
+ is_null,
+ v);
+ i.manifest_checksum_null = is_null;
+ grew = grew || (cap != i.manifest_checksum_value.capacity ());
+ }
+
+ // buildfiles_checksum
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.buildfiles_checksum;
+
+ bool is_null (true);
+ std::size_t cap (i.buildfiles_checksum_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.buildfiles_checksum_value,
+ i.buildfiles_checksum_size,
+ is_null,
+ v);
+ i.buildfiles_checksum_null = is_null;
+ grew = grew || (cap != i.buildfiles_checksum_value.capacity ());
+ }
+
+ // out_root
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::dir_path_kind< char > > > const& v =
+ o.out_root;
+
+ // From package.hxx:60:14
+ ::bpkg::optional_string const& vt =
+ (v) ? (v)->string () : bpkg::optional_string ();
+
+ bool is_null (true);
+ std::size_t cap (i.out_root_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_image (
+ i.out_root_value,
+ i.out_root_size,
+ is_null,
+ vt);
+ i.out_root_null = is_null;
+ grew = grew || (cap != i.out_root_value.capacity ());
+ }
+
+ // config_checksum
+ //
+ {
+ ::std::string const& v =
+ o.config_checksum;
+
+ bool is_null (false);
+ std::size_t cap (i.config_checksum_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.config_checksum_value,
+ i.config_checksum_size,
+ is_null,
+ v);
+ i.config_checksum_null = is_null;
+ grew = grew || (cap != i.config_checksum_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ init (object_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // name
+ //
+ {
+ ::bpkg::package_name& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // version
+ //
+ {
+ ::bpkg::selected_package::version_type& v =
+ o.version;
+
+ ::bpkg::_version vt;
+
+ composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ vt,
+ i.version_value,
+ db);
+
+ // From package.hxx:308:14
+ v = bpkg::version ((vt).epoch, std::move ((vt).upstream), std::move ((vt).release), (vt).revision, (vt).iteration);
+ }
+
+ // state
+ //
+ {
+ ::bpkg::package_state& v =
+ o.state;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.state_value,
+ i.state_size,
+ i.state_null);
+
+ // From package.hxx:1018:14
+ v = bpkg::to_package_state (vt);
+ }
+
+ // substate
+ //
+ {
+ ::bpkg::package_substate& v =
+ o.substate;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.substate_value,
+ i.substate_size,
+ i.substate_null);
+
+ // From package.hxx:1039:14
+ v = bpkg::to_package_substate (vt);
+ }
+
+ // hold_package
+ //
+ {
+ bool& v =
+ o.hold_package;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.hold_package_value,
+ i.hold_package_null);
+ }
+
+ // hold_version
+ //
+ {
+ bool& v =
+ o.hold_version;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.hold_version_value,
+ i.hold_version_null);
+ }
+
+ // repository_fragment
+ //
+ {
+ ::bpkg::repository_location& v =
+ o.repository_fragment;
+
+ ::bpkg::_repository_location vt;
+
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ vt,
+ i.repository_fragment_value,
+ db);
+
+ // From package.hxx:368:14
+ v = bpkg::repository_location (std::move ((vt).url), (vt).type);
+ }
+
+ // archive
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::any_path_kind< char > > >& v =
+ o.archive;
+
+ ::bpkg::optional_string vt;
+
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.archive_value,
+ i.archive_size,
+ i.archive_null);
+
+ // From package.hxx:53:14
+ v = (vt) ? bpkg::path ( * (vt)) : bpkg::optional_path ();
+ }
+
+ // purge_archive
+ //
+ {
+ bool& v =
+ o.purge_archive;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.purge_archive_value,
+ i.purge_archive_null);
+ }
+
+ // src_root
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::dir_path_kind< char > > >& v =
+ o.src_root;
+
+ ::bpkg::optional_string vt;
+
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.src_root_value,
+ i.src_root_size,
+ i.src_root_null);
+
+ // From package.hxx:60:14
+ v = (vt) ? bpkg::dir_path ( * (vt)) : bpkg::optional_dir_path ();
+ }
+
+ // purge_src
+ //
+ {
+ bool& v =
+ o.purge_src;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.purge_src_value,
+ i.purge_src_null);
+ }
+
+ // manifest_checksum
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.manifest_checksum;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.manifest_checksum_value,
+ i.manifest_checksum_size,
+ i.manifest_checksum_null);
+ }
+
+ // buildfiles_checksum
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.buildfiles_checksum;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.buildfiles_checksum_value,
+ i.buildfiles_checksum_size,
+ i.buildfiles_checksum_null);
+ }
+
+ // out_root
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::dir_path_kind< char > > >& v =
+ o.out_root;
+
+ ::bpkg::optional_string vt;
+
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.out_root_value,
+ i.out_root_size,
+ i.out_root_null);
+
+ // From package.hxx:60:14
+ v = (vt) ? bpkg::dir_path ( * (vt)) : bpkg::optional_dir_path ();
+ }
+
+ // config_checksum
+ //
+ {
+ ::std::string& v =
+ o.config_checksum;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.config_checksum_value,
+ i.config_checksum_size,
+ i.config_checksum_null);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ init (id_image_type& i, const id_type& id)
+ {
+ bool grew (false);
+ {
+ bool is_null (false);
+ std::size_t cap (i.id_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_image (
+ i.id_value,
+ i.id_size,
+ is_null,
+ id);
+ i.id_null = is_null;
+ grew = grew || (cap != i.id_value.capacity ());
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::persist_statement[] =
+ "INSERT INTO \"main\".\"selected_package\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"version_upstream\", "
+ "\"version_release\", "
+ "\"state\", "
+ "\"substate\", "
+ "\"hold_package\", "
+ "\"hold_version\", "
+ "\"repository_fragment_url\", "
+ "\"repository_fragment_type\", "
+ "\"archive\", "
+ "\"purge_archive\", "
+ "\"src_root\", "
+ "\"purge_src\", "
+ "\"manifest_checksum\", "
+ "\"buildfiles_checksum\", "
+ "\"out_root\", "
+ "\"config_checksum\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::find_statement[] =
+ "SELECT "
+ "\"main\".\"selected_package\".\"name\", "
+ "\"main\".\"selected_package\".\"version_epoch\", "
+ "\"main\".\"selected_package\".\"version_canonical_upstream\", "
+ "\"main\".\"selected_package\".\"version_canonical_release\", "
+ "\"main\".\"selected_package\".\"version_revision\", "
+ "\"main\".\"selected_package\".\"version_iteration\", "
+ "\"main\".\"selected_package\".\"version_upstream\", "
+ "\"main\".\"selected_package\".\"version_release\", "
+ "\"main\".\"selected_package\".\"state\", "
+ "\"main\".\"selected_package\".\"substate\", "
+ "\"main\".\"selected_package\".\"hold_package\", "
+ "\"main\".\"selected_package\".\"hold_version\", "
+ "\"main\".\"selected_package\".\"repository_fragment_url\", "
+ "\"main\".\"selected_package\".\"repository_fragment_type\", "
+ "\"main\".\"selected_package\".\"archive\", "
+ "\"main\".\"selected_package\".\"purge_archive\", "
+ "\"main\".\"selected_package\".\"src_root\", "
+ "\"main\".\"selected_package\".\"purge_src\", "
+ "\"main\".\"selected_package\".\"manifest_checksum\", "
+ "\"main\".\"selected_package\".\"buildfiles_checksum\", "
+ "\"main\".\"selected_package\".\"out_root\", "
+ "\"main\".\"selected_package\".\"config_checksum\" "
+ "FROM \"main\".\"selected_package\" "
+ "WHERE \"main\".\"selected_package\".\"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::update_statement[] =
+ "UPDATE \"main\".\"selected_package\" "
+ "SET "
+ "\"version_epoch\"=?, "
+ "\"version_canonical_upstream\"=?, "
+ "\"version_canonical_release\"=?, "
+ "\"version_revision\"=?, "
+ "\"version_iteration\"=?, "
+ "\"version_upstream\"=?, "
+ "\"version_release\"=?, "
+ "\"state\"=?, "
+ "\"substate\"=?, "
+ "\"hold_package\"=?, "
+ "\"hold_version\"=?, "
+ "\"repository_fragment_url\"=?, "
+ "\"repository_fragment_type\"=?, "
+ "\"archive\"=?, "
+ "\"purge_archive\"=?, "
+ "\"src_root\"=?, "
+ "\"purge_src\"=?, "
+ "\"manifest_checksum\"=?, "
+ "\"buildfiles_checksum\"=?, "
+ "\"out_root\"=?, "
+ "\"config_checksum\"=? "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::erase_statement[] =
+ "DELETE FROM \"main\".\"selected_package\" "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::query_statement[] =
+ "SELECT "
+ "\"main\".\"selected_package\".\"name\", "
+ "\"main\".\"selected_package\".\"version_epoch\", "
+ "\"main\".\"selected_package\".\"version_canonical_upstream\", "
+ "\"main\".\"selected_package\".\"version_canonical_release\", "
+ "\"main\".\"selected_package\".\"version_revision\", "
+ "\"main\".\"selected_package\".\"version_iteration\", "
+ "\"main\".\"selected_package\".\"version_upstream\", "
+ "\"main\".\"selected_package\".\"version_release\", "
+ "\"main\".\"selected_package\".\"state\", "
+ "\"main\".\"selected_package\".\"substate\", "
+ "\"main\".\"selected_package\".\"hold_package\", "
+ "\"main\".\"selected_package\".\"hold_version\", "
+ "\"main\".\"selected_package\".\"repository_fragment_url\", "
+ "\"main\".\"selected_package\".\"repository_fragment_type\", "
+ "\"main\".\"selected_package\".\"archive\", "
+ "\"main\".\"selected_package\".\"purge_archive\", "
+ "\"main\".\"selected_package\".\"src_root\", "
+ "\"main\".\"selected_package\".\"purge_src\", "
+ "\"main\".\"selected_package\".\"manifest_checksum\", "
+ "\"main\".\"selected_package\".\"buildfiles_checksum\", "
+ "\"main\".\"selected_package\".\"out_root\", "
+ "\"main\".\"selected_package\".\"config_checksum\" "
+ "FROM \"main\".\"selected_package\"";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::erase_query_statement[] =
+ "DELETE FROM \"main\".\"selected_package\"";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::table_name[] =
+ "\"main\".\"selected_package\"";
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ persist (database& db, const object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ callback (db,
+ obj,
+ callback_event::pre_persist);
+
+ image_type& im (sts.image ());
+ binding& imb (sts.insert_image_binding ());
+
+ if (init (im, obj, statement_insert))
+ im.version++;
+
+ if (im.version != sts.insert_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_insert);
+ sts.insert_image_version (im.version);
+ imb.version++;
+ }
+
+ insert_statement& st (sts.persist_statement ());
+ if (!st.execute ())
+ throw object_already_persistent ();
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // prerequisites
+ //
+ {
+ ::bpkg::package_prerequisites const& v =
+ obj.prerequisites;
+
+ prerequisites_traits::persist (
+ v,
+ esc.prerequisites);
+ }
+
+ // dependency_alternatives
+ //
+ {
+ ::bpkg::selected_package::indexes_type const& v =
+ obj.dependency_alternatives;
+
+ dependency_alternatives_traits::persist (
+ v,
+ esc.dependency_alternatives);
+ }
+
+ // config_variables
+ //
+ {
+ ::std::vector< ::bpkg::config_variable > const& v =
+ obj.config_variables;
+
+ config_variables_traits::persist (
+ v,
+ esc.config_variables);
+ }
+
+ obj.dependency_alternatives_section.reset (true, false);
+
+ callback (db,
+ obj,
+ callback_event::post_persist);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ update (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+ using sqlite::update_statement;
+
+ callback (db, obj, callback_event::pre_update);
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ sqlite::connection& conn (tr.connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& idi (sts.id_image ());
+ init (idi, id (obj));
+
+ image_type& im (sts.image ());
+ if (init (im, obj, statement_update))
+ im.version++;
+
+ bool u (false);
+ binding& imb (sts.update_image_binding ());
+ if (im.version != sts.update_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_update);
+ sts.update_image_version (im.version);
+ imb.version++;
+ u = true;
+ }
+
+ binding& idb (sts.id_image_binding ());
+ if (idi.version != sts.update_id_image_version () ||
+ idb.version == 0)
+ {
+ if (idi.version != sts.id_image_version () ||
+ idb.version == 0)
+ {
+ bind (idb.bind, idi);
+ sts.id_image_version (idi.version);
+ idb.version++;
+ }
+
+ sts.update_id_image_version (idi.version);
+
+ if (!u)
+ imb.version++;
+ }
+
+ update_statement& st (sts.update_statement ());
+ if (st.execute () == 0)
+ throw object_not_persistent ();
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // prerequisites
+ //
+ {
+ ::bpkg::package_prerequisites const& v =
+ obj.prerequisites;
+
+ prerequisites_traits::update (
+ v,
+ esc.prerequisites);
+ }
+
+ // config_variables
+ //
+ {
+ ::std::vector< ::bpkg::config_variable > const& v =
+ obj.config_variables;
+
+ config_variables_traits::update (
+ v,
+ esc.config_variables);
+ }
+
+ if (obj.dependency_alternatives_section.loaded ())
+ {
+ dependency_alternatives_section_traits::update (esc, obj);
+ }
+
+ callback (db, obj, callback_event::post_update);
+ pointer_cache_traits::update (db, obj);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ erase (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // prerequisites
+ //
+ {
+ prerequisites_traits::erase (
+ esc.prerequisites);
+ }
+
+ // dependency_alternatives
+ //
+ {
+ dependency_alternatives_traits::erase (
+ esc.dependency_alternatives);
+ }
+
+ // config_variables
+ //
+ {
+ config_variables_traits::erase (
+ esc.config_variables);
+ }
+
+ if (sts.erase_statement ().execute () != 1)
+ throw object_not_persistent ();
+
+ pointer_cache_traits::erase (db, id);
+ }
+
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::pointer_type
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ find (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ {
+ pointer_type p (pointer_cache_traits::find (db, id));
+
+ if (!pointer_traits::null_ptr (p))
+ return p;
+ }
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+
+ if (l.locked ())
+ {
+ if (!find_ (sts, &id))
+ return pointer_type ();
+ }
+
+ pointer_type p (
+ access::object_factory<object_type, pointer_type>::create ());
+ pointer_traits::guard pg (p);
+
+ pointer_cache_traits::insert_guard ig (
+ pointer_cache_traits::insert (db, id, p));
+
+ object_type& obj (pointer_traits::get_ref (p));
+
+ if (l.locked ())
+ {
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ pointer_cache_traits::load (ig.position ());
+ }
+ else
+ sts.delay_load (id, obj, ig.position ());
+
+ ig.release ();
+ pg.release ();
+ return p;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ find (database& db, const id_type& id, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ reference_cache_traits::position_type pos (
+ reference_cache_traits::insert (db, id, obj));
+ reference_cache_traits::insert_guard ig (pos);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ reference_cache_traits::load (pos);
+ ig.release ();
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ reload (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ const id_type& id (object_traits_impl::id (obj));
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, true);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ load (connection& conn, object_type& obj, section& s)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& c (static_cast<sqlite::connection&> (conn));
+ statements_type& sts (c.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ bool r (false);
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ if (!r && &s == &obj.dependency_alternatives_section)
+ {
+ dependency_alternatives_section_traits::load (esc, obj);
+ r = true;
+ }
+
+ sts.load_delayed (0);
+ l.unlock ();
+ return r;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ update (connection& conn, const object_type& obj, const section& s)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& c (static_cast<sqlite::connection&> (conn));
+ statements_type& sts (c.statement_cache ().find_object<object_type> ());
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ if (&s == &obj.dependency_alternatives_section)dependency_alternatives_section_traits::update (esc, obj);
+ else
+ return false;
+
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ find_ (statements_type& sts,
+ const id_type* id)
+ {
+ using namespace sqlite;
+
+ id_image_type& i (sts.id_image ());
+ init (i, *id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ select_statement& st (sts.find_statement ());
+
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ if (grow (im, sts.select_image_truncated ()))
+ im.version++;
+
+ if (im.version != sts.select_image_version ())
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ load_ (statements_type& sts,
+ object_type& obj,
+ bool reload)
+ {
+ ODB_POTENTIALLY_UNUSED (reload);
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // prerequisites
+ //
+ {
+ ::bpkg::package_prerequisites& v =
+ obj.prerequisites;
+
+ prerequisites_traits::load (
+ v,
+ esc.prerequisites);
+ }
+
+ // config_variables
+ //
+ {
+ ::std::vector< ::bpkg::config_variable >& v =
+ obj.config_variables;
+
+ config_variables_traits::load (
+ v,
+ esc.config_variables);
+ }
+
+ if (reload)
+ {
+ if (obj.dependency_alternatives_section.loaded ())
+ {
+ dependency_alternatives_section_traits::load (esc, obj);
+ obj.dependency_alternatives_section.reset (true, false);
+ }
+ }
+ else
+ obj.dependency_alternatives_section.reset ();
+ }
+
+ result< access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::object_type >
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ q.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::object_result_impl<object_type> > r (
+ new (shared) sqlite::object_result_impl<object_type> (
+ q, st, sts, 0));
+
+ return result<object_type> (r);
+ }
+
+ unsigned long long access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ erase_query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ std::string text (erase_query_statement);
+ if (!q.empty ())
+ {
+ text += ' ';
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ delete_statement st (
+ conn,
+ text,
+ q.parameters_binding ());
+
+ return st.execute ();
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = q;
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::object_result_impl<object_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // certificate
+ //
+
+ struct access::object_traits_impl< ::bpkg::certificate, id_sqlite >::extra_statement_cache_type
+ {
+ extra_statement_cache_type (
+ sqlite::connection&,
+ image_type&,
+ id_image_type&,
+ sqlite::binding&,
+ sqlite::binding&)
+ {
+ }
+ };
+
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ id (const image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ id,
+ i.id_value,
+ i.id_size,
+ i.id_null);
+ }
+
+ return id;
+ }
+
+ bool access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // id
+ //
+ if (t[0UL])
+ {
+ i.id_value.capacity (i.id_size);
+ grew = true;
+ }
+
+ // fingerprint
+ //
+ if (t[1UL])
+ {
+ i.fingerprint_value.capacity (i.fingerprint_size);
+ grew = true;
+ }
+
+ // name
+ //
+ if (t[2UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // organization
+ //
+ if (t[3UL])
+ {
+ i.organization_value.capacity (i.organization_size);
+ grew = true;
+ }
+
+ // email
+ //
+ if (t[4UL])
+ {
+ i.email_value.capacity (i.email_size);
+ grew = true;
+ }
+
+ // start_date
+ //
+ t[5UL] = false;
+
+ // end_date
+ //
+ t[6UL] = false;
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+
+ // id
+ //
+ if (sk != statement_update)
+ {
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.id_value.data ();
+ b[n].size = &i.id_size;
+ b[n].capacity = i.id_value.capacity ();
+ b[n].is_null = &i.id_null;
+ n++;
+ }
+
+ // fingerprint
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.fingerprint_value.data ();
+ b[n].size = &i.fingerprint_size;
+ b[n].capacity = i.fingerprint_value.capacity ();
+ b[n].is_null = &i.fingerprint_null;
+ n++;
+
+ // name
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.name_value.data ();
+ b[n].size = &i.name_size;
+ b[n].capacity = i.name_value.capacity ();
+ b[n].is_null = &i.name_null;
+ n++;
+
+ // organization
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.organization_value.data ();
+ b[n].size = &i.organization_size;
+ b[n].capacity = i.organization_value.capacity ();
+ b[n].is_null = &i.organization_null;
+ n++;
+
+ // email
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.email_value.data ();
+ b[n].size = &i.email_size;
+ b[n].capacity = i.email_value.capacity ();
+ b[n].is_null = &i.email_null;
+ n++;
+
+ // start_date
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.start_date_value;
+ b[n].is_null = &i.start_date_null;
+ n++;
+
+ // end_date
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.end_date_value;
+ b[n].is_null = &i.end_date_null;
+ n++;
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ bind (sqlite::bind* b, id_image_type& i)
+ {
+ std::size_t n (0);
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.id_value.data ();
+ b[n].size = &i.id_size;
+ b[n].capacity = i.id_value.capacity ();
+ b[n].is_null = &i.id_null;
+ }
+
+ bool access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ init (image_type& i,
+ const object_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // id
+ //
+ if (sk == statement_insert)
+ {
+ ::std::string const& v =
+ o.id;
+
+ bool is_null (false);
+ std::size_t cap (i.id_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.id_value,
+ i.id_size,
+ is_null,
+ v);
+ i.id_null = is_null;
+ grew = grew || (cap != i.id_value.capacity ());
+ }
+
+ // fingerprint
+ //
+ {
+ ::std::string const& v =
+ o.fingerprint;
+
+ bool is_null (false);
+ std::size_t cap (i.fingerprint_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.fingerprint_value,
+ i.fingerprint_size,
+ is_null,
+ v);
+ i.fingerprint_null = is_null;
+ grew = grew || (cap != i.fingerprint_value.capacity ());
+ }
+
+ // name
+ //
+ {
+ ::std::string const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.name_value,
+ i.name_size,
+ is_null,
+ v);
+ i.name_null = is_null;
+ grew = grew || (cap != i.name_value.capacity ());
+ }
+
+ // organization
+ //
+ {
+ ::std::string const& v =
+ o.organization;
+
+ bool is_null (false);
+ std::size_t cap (i.organization_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.organization_value,
+ i.organization_size,
+ is_null,
+ v);
+ i.organization_null = is_null;
+ grew = grew || (cap != i.organization_value.capacity ());
+ }
+
+ // email
+ //
+ {
+ ::std::string const& v =
+ o.email;
+
+ bool is_null (false);
+ std::size_t cap (i.email_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.email_value,
+ i.email_size,
+ is_null,
+ v);
+ i.email_null = is_null;
+ grew = grew || (cap != i.email_value.capacity ());
+ }
+
+ // start_date
+ //
+ {
+ ::butl::timestamp const& v =
+ o.start_date;
+
+ // From package.hxx:84:14
+ ::uint64_t const& vt =
+ std::chrono::duration_cast < std::chrono::nanoseconds > ((v).time_since_epoch ()).count ();
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::uint64_t,
+ sqlite::id_integer >::set_image (
+ i.start_date_value,
+ is_null,
+ vt);
+ i.start_date_null = is_null;
+ }
+
+ // end_date
+ //
+ {
+ ::butl::timestamp const& v =
+ o.end_date;
+
+ // From package.hxx:84:14
+ ::uint64_t const& vt =
+ std::chrono::duration_cast < std::chrono::nanoseconds > ((v).time_since_epoch ()).count ();
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::uint64_t,
+ sqlite::id_integer >::set_image (
+ i.end_date_value,
+ is_null,
+ vt);
+ i.end_date_null = is_null;
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ init (object_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // id
+ //
+ {
+ ::std::string& v =
+ o.id;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.id_value,
+ i.id_size,
+ i.id_null);
+ }
+
+ // fingerprint
+ //
+ {
+ ::std::string& v =
+ o.fingerprint;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.fingerprint_value,
+ i.fingerprint_size,
+ i.fingerprint_null);
+ }
+
+ // name
+ //
+ {
+ ::std::string& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // organization
+ //
+ {
+ ::std::string& v =
+ o.organization;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.organization_value,
+ i.organization_size,
+ i.organization_null);
+ }
+
+ // email
+ //
+ {
+ ::std::string& v =
+ o.email;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.email_value,
+ i.email_size,
+ i.email_null);
+ }
+
+ // start_date
+ //
+ {
+ ::butl::timestamp& v =
+ o.start_date;
+
+ ::uint64_t vt;
+
+ sqlite::value_traits<
+ ::uint64_t,
+ sqlite::id_integer >::set_value (
+ vt,
+ i.start_date_value,
+ i.start_date_null);
+
+ // From package.hxx:84:14
+ v = butl::timestamp (std::chrono::duration_cast < butl::timestamp::duration > (std::chrono::nanoseconds (vt)));
+ }
+
+ // end_date
+ //
+ {
+ ::butl::timestamp& v =
+ o.end_date;
+
+ ::uint64_t vt;
+
+ sqlite::value_traits<
+ ::uint64_t,
+ sqlite::id_integer >::set_value (
+ vt,
+ i.end_date_value,
+ i.end_date_null);
+
+ // From package.hxx:84:14
+ v = butl::timestamp (std::chrono::duration_cast < butl::timestamp::duration > (std::chrono::nanoseconds (vt)));
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ init (id_image_type& i, const id_type& id)
+ {
+ bool grew (false);
+ {
+ bool is_null (false);
+ std::size_t cap (i.id_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.id_value,
+ i.id_size,
+ is_null,
+ id);
+ i.id_null = is_null;
+ grew = grew || (cap != i.id_value.capacity ());
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::persist_statement[] =
+ "INSERT INTO \"main\".\"certificate\" "
+ "(\"id\", "
+ "\"fingerprint\", "
+ "\"name\", "
+ "\"organization\", "
+ "\"email\", "
+ "\"start_date\", "
+ "\"end_date\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::find_statement[] =
+ "SELECT "
+ "\"main\".\"certificate\".\"id\", "
+ "\"main\".\"certificate\".\"fingerprint\", "
+ "\"main\".\"certificate\".\"name\", "
+ "\"main\".\"certificate\".\"organization\", "
+ "\"main\".\"certificate\".\"email\", "
+ "\"main\".\"certificate\".\"start_date\", "
+ "\"main\".\"certificate\".\"end_date\" "
+ "FROM \"main\".\"certificate\" "
+ "WHERE \"main\".\"certificate\".\"id\"=?";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::update_statement[] =
+ "UPDATE \"main\".\"certificate\" "
+ "SET "
+ "\"fingerprint\"=?, "
+ "\"name\"=?, "
+ "\"organization\"=?, "
+ "\"email\"=?, "
+ "\"start_date\"=?, "
+ "\"end_date\"=? "
+ "WHERE \"id\"=?";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::erase_statement[] =
+ "DELETE FROM \"main\".\"certificate\" "
+ "WHERE \"id\"=?";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::query_statement[] =
+ "SELECT "
+ "\"main\".\"certificate\".\"id\", "
+ "\"main\".\"certificate\".\"fingerprint\", "
+ "\"main\".\"certificate\".\"name\", "
+ "\"main\".\"certificate\".\"organization\", "
+ "\"main\".\"certificate\".\"email\", "
+ "\"main\".\"certificate\".\"start_date\", "
+ "\"main\".\"certificate\".\"end_date\" "
+ "FROM \"main\".\"certificate\"";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::erase_query_statement[] =
+ "DELETE FROM \"main\".\"certificate\"";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::table_name[] =
+ "\"main\".\"certificate\"";
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ persist (database& db, const object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ callback (db,
+ obj,
+ callback_event::pre_persist);
+
+ image_type& im (sts.image ());
+ binding& imb (sts.insert_image_binding ());
+
+ if (init (im, obj, statement_insert))
+ im.version++;
+
+ if (im.version != sts.insert_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_insert);
+ sts.insert_image_version (im.version);
+ imb.version++;
+ }
+
+ insert_statement& st (sts.persist_statement ());
+ if (!st.execute ())
+ throw object_already_persistent ();
+
+ callback (db,
+ obj,
+ callback_event::post_persist);
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ update (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+ using sqlite::update_statement;
+
+ callback (db, obj, callback_event::pre_update);
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ sqlite::connection& conn (tr.connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& idi (sts.id_image ());
+ init (idi, id (obj));
+
+ image_type& im (sts.image ());
+ if (init (im, obj, statement_update))
+ im.version++;
+
+ bool u (false);
+ binding& imb (sts.update_image_binding ());
+ if (im.version != sts.update_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_update);
+ sts.update_image_version (im.version);
+ imb.version++;
+ u = true;
+ }
+
+ binding& idb (sts.id_image_binding ());
+ if (idi.version != sts.update_id_image_version () ||
+ idb.version == 0)
+ {
+ if (idi.version != sts.id_image_version () ||
+ idb.version == 0)
+ {
+ bind (idb.bind, idi);
+ sts.id_image_version (idi.version);
+ idb.version++;
+ }
+
+ sts.update_id_image_version (idi.version);
+
+ if (!u)
+ imb.version++;
+ }
+
+ update_statement& st (sts.update_statement ());
+ if (st.execute () == 0)
+ throw object_not_persistent ();
+
+ callback (db, obj, callback_event::post_update);
+ pointer_cache_traits::update (db, obj);
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ erase (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ if (sts.erase_statement ().execute () != 1)
+ throw object_not_persistent ();
+
+ pointer_cache_traits::erase (db, id);
+ }
+
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::pointer_type
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ find (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ {
+ pointer_type p (pointer_cache_traits::find (db, id));
+
+ if (!pointer_traits::null_ptr (p))
+ return p;
+ }
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+
+ if (l.locked ())
+ {
+ if (!find_ (sts, &id))
+ return pointer_type ();
+ }
+
+ pointer_type p (
+ access::object_factory<object_type, pointer_type>::create ());
+ pointer_traits::guard pg (p);
+
+ pointer_cache_traits::insert_guard ig (
+ pointer_cache_traits::insert (db, id, p));
+
+ object_type& obj (pointer_traits::get_ref (p));
+
+ if (l.locked ())
+ {
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ pointer_cache_traits::load (ig.position ());
+ }
+ else
+ sts.delay_load (id, obj, ig.position ());
+
+ ig.release ();
+ pg.release ();
+ return p;
+ }
+
+ bool access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ find (database& db, const id_type& id, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ reference_cache_traits::position_type pos (
+ reference_cache_traits::insert (db, id, obj));
+ reference_cache_traits::insert_guard ig (pos);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ reference_cache_traits::load (pos);
+ ig.release ();
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ reload (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ const id_type& id (object_traits_impl::id (obj));
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, true);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ find_ (statements_type& sts,
+ const id_type* id)
+ {
+ using namespace sqlite;
+
+ id_image_type& i (sts.id_image ());
+ init (i, *id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ select_statement& st (sts.find_statement ());
+
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ if (grow (im, sts.select_image_truncated ()))
+ im.version++;
+
+ if (im.version != sts.select_image_version ())
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ result< access::object_traits_impl< ::bpkg::certificate, id_sqlite >::object_type >
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ q.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::object_result_impl<object_type> > r (
+ new (shared) sqlite::object_result_impl<object_type> (
+ q, st, sts, 0));
+
+ return result<object_type> (r);
+ }
+
+ unsigned long long access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ erase_query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+
+ std::string text (erase_query_statement);
+ if (!q.empty ())
+ {
+ text += ' ';
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ delete_statement st (
+ conn,
+ text,
+ q.parameters_binding ());
+
+ return st.execute ();
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = q;
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::object_result_impl<object_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // package_dependent
+ //
+
+ bool access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // name
+ //
+ if (t[0UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // constraint
+ //
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::grow (
+ i.constraint_value, t + 1UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // name
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::package_name,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.name_value.data ();
+ b[n].size = &i.name_size;
+ b[n].capacity = i.name_value.capacity ();
+ b[n].is_null = &i.name_null;
+ n++;
+
+ // constraint
+ //
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::bind (
+ b + n, i.constraint_value, sk);
+ n += 16UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // name
+ //
+ {
+ ::bpkg::package_name& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // constraint
+ //
+ {
+ ::butl::optional< ::bpkg::version_constraint >& v =
+ o.constraint;
+
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::get_null (
+ i.constraint_value))
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::set_null (v);
+ else
+ {
+ ::bpkg::version_constraint& vw =
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::set_ref (v);
+
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::init (
+ vw,
+ i.constraint_value,
+ db);
+ }
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"pp\".\"package\", "
+ "\"pp\".\"min_version_epoch\", "
+ "\"pp\".\"min_version_canonical_upstream\", "
+ "\"pp\".\"min_version_canonical_release\", "
+ "\"pp\".\"min_version_revision\", "
+ "\"pp\".\"min_version_iteration\", "
+ "\"pp\".\"min_version_upstream\", "
+ "\"pp\".\"min_version_release\", "
+ "\"pp\".\"max_version_epoch\", "
+ "\"pp\".\"max_version_canonical_upstream\", "
+ "\"pp\".\"max_version_canonical_release\", "
+ "\"pp\".\"max_version_revision\", "
+ "\"pp\".\"max_version_iteration\", "
+ "\"pp\".\"max_version_upstream\", "
+ "\"pp\".\"max_version_release\", "
+ "\"pp\".\"min_open\", "
+ "\"pp\".\"max_open\" ");
+
+ r += "FROM \"main\".\"selected_package_prerequisites\" AS \"pp\"";
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // fragment_repository_count
+ //
+
+ bool access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // result
+ //
+ t[0UL] = false;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // result
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.result_value;
+ b[n].is_null = &i.result_null;
+ n++;
+ }
+
+ void access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // result
+ //
+ {
+ ::std::size_t& v =
+ o.result;
+
+ sqlite::value_traits<
+ ::std::size_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.result_value,
+ i.result_null);
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "count(*) ");
+
+ r += "FROM \"main\".\"repository_fragments\"";
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // fragment_repository
+ //
+
+ bool access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // object
+ //
+ if (object_traits_impl< ::bpkg::repository, id_sqlite >::grow (
+ i.object_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // object
+ //
+ object_traits_impl< ::bpkg::repository, id_sqlite >::bind (
+ b + n, i.object_value, sk);
+ n += 5UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (*db));
+
+ // object pre
+ //
+ typedef ::bpkg::repository object_object_type;
+ typedef object_traits_impl<object_object_type, id_sqlite> object_object_traits;
+ typedef object_object_traits::pointer_type object_pointer_type;
+ typedef object_object_traits::pointer_traits object_pointer_traits;
+ typedef object_object_traits::pointer_cache_traits object_cache_traits;
+
+ object_object_traits::id_type object_id;
+ object_pointer_type object_p;
+ object_pointer_traits::guard object_pg;
+ object_cache_traits::insert_guard object_ig;
+ object_object_type* object_o (0);
+
+ {
+ if (!(i.object_value.name_null))
+ {
+ object_id = object_object_traits::id (i.object_value);
+ object_p = object_cache_traits::find (*db, object_id);
+
+ if (object_pointer_traits::null_ptr (object_p))
+ {
+ object_p = object_factory<object_object_type, object_pointer_type>::create ();
+ object_pg.reset (object_p);
+ object_ig.reset (object_cache_traits::insert (*db, object_id, object_p));
+ object_o = object_pointer_traits::get_ptr (object_p);
+ }
+ }
+ }
+
+ // object
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::pre_load);
+ object_object_traits::init (*object_o, i.object_value, db);
+ object_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<object_object_type> ());
+ object_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ object_object_traits::id_image_type& i (sts.id_image ());
+ object_object_traits::init (i, object_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ object_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ object_object_traits::load_ (sts, *object_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // object post
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::post_load);
+ object_cache_traits::load (object_ig.position ());
+ object_ig.release ();
+ object_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.object = ::std::shared_ptr< ::bpkg::repository > (
+ std::move (object_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"main\".\"repository\".\"name\", "
+ "\"main\".\"repository\".\"url\", "
+ "\"main\".\"repository\".\"type\", "
+ "\"main\".\"repository\".\"certificate\", "
+ "\"main\".\"repository\".\"local\" ");
+
+ r += "FROM \"main\".\"repository\"";
+
+ r += " INNER JOIN \"main\".\"repository_fragments\" AS \"rfs\" ON";
+ // From package.hxx:1731:5
+ r += "rfs.repository = " + query_columns::repository::name;
+
+ r += " INNER JOIN \"main\".\"repository_fragment\" ON";
+ // From package.hxx:1733:5
+ r += "rfs.fragment = " + query_columns::repository_fragment::name;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // repository_complement_dependent
+ //
+
+ const char alias_traits< ::bpkg::repository,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::complement_tag>::
+ table_name[] = "\"complement\"";
+
+ bool access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // object
+ //
+ if (object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::grow (
+ i.object_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // object
+ //
+ object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::bind (
+ b + n, i.object_value, sk);
+ n += 3UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (*db));
+
+ // object pre
+ //
+ typedef ::bpkg::repository_fragment object_object_type;
+ typedef object_traits_impl<object_object_type, id_sqlite> object_object_traits;
+ typedef object_object_traits::pointer_type object_pointer_type;
+ typedef object_object_traits::pointer_traits object_pointer_traits;
+ typedef object_object_traits::pointer_cache_traits object_cache_traits;
+
+ object_object_traits::id_type object_id;
+ object_pointer_type object_p;
+ object_pointer_traits::guard object_pg;
+ object_cache_traits::insert_guard object_ig;
+ object_object_type* object_o (0);
+
+ {
+ if (!(i.object_value.name_null))
+ {
+ object_id = object_object_traits::id (i.object_value);
+ object_p = object_cache_traits::find (*db, object_id);
+
+ if (object_pointer_traits::null_ptr (object_p))
+ {
+ object_p = object_factory<object_object_type, object_pointer_type>::create ();
+ object_pg.reset (object_p);
+ object_ig.reset (object_cache_traits::insert (*db, object_id, object_p));
+ object_o = object_pointer_traits::get_ptr (object_p);
+ }
+ }
+ }
+
+ // object
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::pre_load);
+ object_object_traits::init (*object_o, i.object_value, db);
+ object_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<object_object_type> ());
+ object_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ object_object_traits::id_image_type& i (sts.id_image ());
+ object_object_traits::init (i, object_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ object_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ object_object_traits::load_ (sts, *object_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // object post
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::post_load);
+ object_cache_traits::load (object_ig.position ());
+ object_ig.release ();
+ object_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.object = ::std::shared_ptr< ::bpkg::repository_fragment > (
+ std::move (object_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"main\".\"repository_fragment\".\"name\", "
+ "\"main\".\"repository_fragment\".\"url\", "
+ "\"main\".\"repository_fragment\".\"type\" ");
+
+ r += "FROM \"main\".\"repository\" AS \"complement\"";
+
+ r += " INNER JOIN \"main\".\"repository_fragment_complements\" AS \"rfc\" ON";
+ // From package.hxx:1746:5
+ r += "rfc.complement = " + query_columns::complement::name;
+
+ r += " INNER JOIN \"main\".\"repository_fragment\" ON";
+ // From package.hxx:1748:5
+ r += "rfc.repository_fragment = " + query_columns::repository_fragment::name;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // repository_prerequisite_dependent
+ //
+
+ const char alias_traits< ::bpkg::repository,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::prerequisite_tag>::
+ table_name[] = "\"prerequisite\"";
+
+ bool access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // object
+ //
+ if (object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::grow (
+ i.object_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // object
+ //
+ object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::bind (
+ b + n, i.object_value, sk);
+ n += 3UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (*db));
+
+ // object pre
+ //
+ typedef ::bpkg::repository_fragment object_object_type;
+ typedef object_traits_impl<object_object_type, id_sqlite> object_object_traits;
+ typedef object_object_traits::pointer_type object_pointer_type;
+ typedef object_object_traits::pointer_traits object_pointer_traits;
+ typedef object_object_traits::pointer_cache_traits object_cache_traits;
+
+ object_object_traits::id_type object_id;
+ object_pointer_type object_p;
+ object_pointer_traits::guard object_pg;
+ object_cache_traits::insert_guard object_ig;
+ object_object_type* object_o (0);
+
+ {
+ if (!(i.object_value.name_null))
+ {
+ object_id = object_object_traits::id (i.object_value);
+ object_p = object_cache_traits::find (*db, object_id);
+
+ if (object_pointer_traits::null_ptr (object_p))
+ {
+ object_p = object_factory<object_object_type, object_pointer_type>::create ();
+ object_pg.reset (object_p);
+ object_ig.reset (object_cache_traits::insert (*db, object_id, object_p));
+ object_o = object_pointer_traits::get_ptr (object_p);
+ }
+ }
+ }
+
+ // object
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::pre_load);
+ object_object_traits::init (*object_o, i.object_value, db);
+ object_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<object_object_type> ());
+ object_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ object_object_traits::id_image_type& i (sts.id_image ());
+ object_object_traits::init (i, object_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ object_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ object_object_traits::load_ (sts, *object_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // object post
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::post_load);
+ object_cache_traits::load (object_ig.position ());
+ object_ig.release ();
+ object_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.object = ::std::shared_ptr< ::bpkg::repository_fragment > (
+ std::move (object_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"main\".\"repository_fragment\".\"name\", "
+ "\"main\".\"repository_fragment\".\"url\", "
+ "\"main\".\"repository_fragment\".\"type\" ");
+
+ r += "FROM \"main\".\"repository\" AS \"prerequisite\"";
+
+ r += " INNER JOIN \"main\".\"repository_fragment_prerequisites\" AS \"rfp\" ON";
+ // From package.hxx:1761:5
+ r += "rfp.prerequisite = " + query_columns::prerequisite::name;
+
+ r += " INNER JOIN \"main\".\"repository_fragment\" ON";
+ // From package.hxx:1763:5
+ r += "rfp.repository_fragment = " + query_columns::repository_fragment::name;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // repository_fragment_package
+ //
+
+ const char alias_traits< ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::package_tag>::
+ table_name[] = "\"package\"";
+
+ bool access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // package
+ //
+ if (object_traits_impl< ::bpkg::available_package, id_sqlite >::grow (
+ i.package_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // package
+ //
+ object_traits_impl< ::bpkg::available_package, id_sqlite >::bind (
+ b + n, i.package_value, sk);
+ n += 15UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (*db));
+
+ // package pre
+ //
+ typedef ::bpkg::available_package package_object_type;
+ typedef object_traits_impl<package_object_type, id_sqlite> package_object_traits;
+ typedef package_object_traits::pointer_type package_pointer_type;
+ typedef package_object_traits::pointer_traits package_pointer_traits;
+ typedef package_object_traits::pointer_cache_traits package_cache_traits;
+
+ package_object_traits::id_type package_id;
+ package_pointer_type package_p;
+ package_pointer_traits::guard package_pg;
+ package_cache_traits::insert_guard package_ig;
+ package_object_type* package_o (0);
+
+ {
+ if (!composite_value_traits< package_object_traits::id_type, id_sqlite >::get_null (
+ i.package_value.id_value))
+ {
+ package_id = package_object_traits::id (i.package_value);
+ package_p = package_cache_traits::find (*db, package_id);
+
+ if (package_pointer_traits::null_ptr (package_p))
+ {
+ package_p = object_factory<package_object_type, package_pointer_type>::create ();
+ package_pg.reset (package_p);
+ package_ig.reset (package_cache_traits::insert (*db, package_id, package_p));
+ package_o = package_pointer_traits::get_ptr (package_p);
+ }
+ }
+ }
+
+ // package
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::pre_load);
+ package_object_traits::init (*package_o, i.package_value, db);
+ package_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<package_object_type> ());
+ package_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ package_object_traits::id_image_type& i (sts.id_image ());
+ package_object_traits::init (i, package_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ package_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ package_object_traits::load_ (sts, *package_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // package post
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::post_load);
+ package_cache_traits::load (package_ig.position ());
+ package_ig.release ();
+ package_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.package = ::std::shared_ptr< ::bpkg::available_package > (
+ std::move (package_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"package\".\"name\", "
+ "\"package\".\"version_epoch\", "
+ "\"package\".\"version_canonical_upstream\", "
+ "\"package\".\"version_canonical_release\", "
+ "\"package\".\"version_revision\", "
+ "\"package\".\"version_iteration\", "
+ "\"package\".\"version_upstream\", "
+ "\"package\".\"version_release\", "
+ "\"package\".\"upstream_version\", "
+ "\"package\".\"type\", "
+ "\"package\".\"project\", "
+ "\"package\".\"alt_naming\", "
+ "\"package\".\"bootstrap_build\", "
+ "\"package\".\"root_build\", "
+ "\"package\".\"sha256sum\" ");
+
+ r += "FROM \"main\".\"repository_fragment\"";
+
+ r += " INNER JOIN \"main\".\"available_package_locations\" AS \"pl\" ON";
+ // From package.hxx:1775:5
+ r += "pl.repository_fragment = " + query_columns::repository_fragment::name;
+
+ r += " INNER JOIN \"main\".\"available_package\" AS \"package\" ON";
+ // From package.hxx:1777:5
+ r += "pl.name = " + query_columns::package::id.name + "AND" + "pl.version_epoch = " + query_columns::package::id.version.epoch + "AND" + "pl.version_canonical_upstream = " + query_columns::package::id.version.canonical_upstream + "AND" + "pl.version_canonical_release = " + query_columns::package::id.version.canonical_release + "AND" + "pl.version_revision = " + query_columns::package::id.version.revision + "AND" + "pl.version_iteration = " + query_columns::package::id.version.iteration;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+
+ // package_repository_fragment
+ //
+
+ const char alias_traits< ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::package_tag>::
+ table_name[] = "\"package\"";
+
+ bool access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // package_id
+ //
+ if (composite_value_traits< ::bpkg::available_package_id, id_sqlite >::grow (
+ i.package_id_value, t + 0UL))
+ grew = true;
+
+ // repository_fragment
+ //
+ if (object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::grow (
+ i.repository_fragment_value, t + 6UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // package_id
+ //
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::bind (
+ b + n, i.package_id_value, sk);
+ n += 6UL;
+
+ // repository_fragment
+ //
+ object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::bind (
+ b + n, i.repository_fragment_value, sk);
+ n += 3UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (*db));
+
+ // repository_fragment pre
+ //
+ typedef ::bpkg::repository_fragment repository_fragment_object_type;
+ typedef object_traits_impl<repository_fragment_object_type, id_sqlite> repository_fragment_object_traits;
+ typedef repository_fragment_object_traits::pointer_type repository_fragment_pointer_type;
+ typedef repository_fragment_object_traits::pointer_traits repository_fragment_pointer_traits;
+ typedef repository_fragment_object_traits::pointer_cache_traits repository_fragment_cache_traits;
+
+ repository_fragment_object_traits::id_type repository_fragment_id;
+ repository_fragment_pointer_type repository_fragment_p;
+ repository_fragment_pointer_traits::guard repository_fragment_pg;
+ repository_fragment_cache_traits::insert_guard repository_fragment_ig;
+ repository_fragment_object_type* repository_fragment_o (0);
+
+ {
+ if (!(i.repository_fragment_value.name_null))
+ {
+ repository_fragment_id = repository_fragment_object_traits::id (i.repository_fragment_value);
+ repository_fragment_p = repository_fragment_cache_traits::find (*db, repository_fragment_id);
+
+ if (repository_fragment_pointer_traits::null_ptr (repository_fragment_p))
+ {
+ repository_fragment_p = object_factory<repository_fragment_object_type, repository_fragment_pointer_type>::create ();
+ repository_fragment_pg.reset (repository_fragment_p);
+ repository_fragment_ig.reset (repository_fragment_cache_traits::insert (*db, repository_fragment_id, repository_fragment_p));
+ repository_fragment_o = repository_fragment_pointer_traits::get_ptr (repository_fragment_p);
+ }
+ }
+ }
+
+ // package_id
+ //
+ {
+ ::bpkg::available_package_id& v =
+ o.package_id;
+
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::init (
+ v,
+ i.package_id_value,
+ db);
+ }
+
+ // repository_fragment
+ //
+ {
+ if (repository_fragment_o != 0)
+ {
+ repository_fragment_object_traits::callback (*db, *repository_fragment_o, callback_event::pre_load);
+ repository_fragment_object_traits::init (*repository_fragment_o, i.repository_fragment_value, db);
+ repository_fragment_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<repository_fragment_object_type> ());
+ repository_fragment_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ repository_fragment_object_traits::id_image_type& i (sts.id_image ());
+ repository_fragment_object_traits::init (i, repository_fragment_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ repository_fragment_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ repository_fragment_object_traits::load_ (sts, *repository_fragment_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // repository_fragment post
+ //
+ {
+ if (repository_fragment_o != 0)
+ {
+ repository_fragment_object_traits::callback (*db, *repository_fragment_o, callback_event::post_load);
+ repository_fragment_cache_traits::load (repository_fragment_ig.position ());
+ repository_fragment_ig.release ();
+ repository_fragment_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.repository_fragment = ::std::shared_ptr< ::bpkg::repository_fragment > (
+ std::move (repository_fragment_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"package\".\"name\", "
+ "\"package\".\"version_epoch\", "
+ "\"package\".\"version_canonical_upstream\", "
+ "\"package\".\"version_canonical_release\", "
+ "\"package\".\"version_revision\", "
+ "\"package\".\"version_iteration\", "
+ "\"main\".\"repository_fragment\".\"name\", "
+ "\"main\".\"repository_fragment\".\"url\", "
+ "\"main\".\"repository_fragment\".\"type\" ");
+
+ r += "FROM \"main\".\"repository_fragment\"";
+
+ r += " INNER JOIN \"main\".\"available_package_locations\" AS \"pl\" ON";
+ // From package.hxx:1796:5
+ r += "pl.repository_fragment = " + query_columns::repository_fragment::name;
+
+ r += " INNER JOIN \"main\".\"available_package\" AS \"package\" ON";
+ // From package.hxx:1798:5
+ r += "pl.name = " + query_columns::package::id.name + "AND" + "pl.version_epoch = " + query_columns::package::id.version.epoch + "AND" + "pl.version_canonical_upstream = " + query_columns::package::id.version.canonical_upstream + "AND" + "pl.version_canonical_release = " + query_columns::package::id.version.canonical_release + "AND" + "pl.version_revision = " + query_columns::package::id.version.revision + "AND" + "pl.version_iteration = " + query_columns::package::id.version.iteration;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ query (database& db, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection (db));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ odb::details::shared_ptr<prepared_query_impl>
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ prepare_query (connection& c, const char* n, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ static_cast<sqlite::connection&> (c));
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ shared_ptr<sqlite::prepared_query_impl> r (
+ new (shared) sqlite::prepared_query_impl (conn));
+ r->name = n;
+ r->execute = &execute_query;
+ r->query = query_statement (q);
+ r->stmt.reset (
+ new (shared) select_statement (
+ conn,
+ r->query.clause (),
+ false,
+ true,
+ r->query.parameters_binding (),
+ imb));
+
+ return r;
+ }
+
+ odb::details::shared_ptr<result_impl>
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ execute_query (prepared_query_impl& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::prepared_query_impl& pq (
+ static_cast<sqlite::prepared_query_impl&> (q));
+ shared_ptr<select_statement> st (
+ odb::details::inc_ref (
+ static_cast<select_statement*> (pq.stmt.get ())));
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ ODB_POTENTIALLY_UNUSED (tr);
+
+ // The connection used by the current transaction and the
+ // one used to prepare this statement must be the same.
+ //
+ assert (q.verify_connection (tr));
+
+ statements_type& sts (
+ st->connection ().statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ pq.query.init_parameters ();
+ st->execute ();
+
+ return shared_ptr<result_impl> (
+ new (shared) sqlite::view_result_impl<view_type> (
+ pq.query, st, sts, 0));
+ }
+}
+
+namespace odb
+{
+ static bool
+ create_schema (database& db, unsigned short pass, bool drop)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (pass);
+ ODB_POTENTIALLY_UNUSED (drop);
+
+ if (drop)
+ {
+ switch (pass)
+ {
+ case 1:
+ {
+ return true;
+ }
+ case 2:
+ {
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"certificate\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"selected_package_config_variables\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"selected_package_dependency_alternatives\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"selected_package_prerequisites\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"selected_package\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"available_package_distribution_values\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"available_package_buildfiles\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"available_package_tests\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"available_package_dependency_alternative_dependencies\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"available_package_dependency_alternatives\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"available_package_dependencies\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"available_package_locations\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"available_package_languages\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"available_package\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"repository_fragments\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"repository\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"repository_fragment_prerequisites\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"repository_fragment_complements\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"repository_fragment\"");
+ db.execute ("DROP TABLE IF EXISTS \"main\".\"configuration\"");
+ db.execute ("CREATE TABLE IF NOT EXISTS \"main\".\"schema_version\" (\n"
+ " \"name\" TEXT NOT NULL PRIMARY KEY,\n"
+ " \"version\" INTEGER NOT NULL,\n"
+ " \"migration\" INTEGER NOT NULL)");
+ db.execute ("DELETE FROM \"main\".\"schema_version\"\n"
+ " WHERE \"name\" = ''");
+ return false;
+ }
+ }
+ }
+ else
+ {
+ switch (pass)
+ {
+ case 1:
+ {
+ db.execute ("CREATE TABLE \"main\".\"configuration\" (\n"
+ " \"id\" INTEGER NULL PRIMARY KEY AUTOINCREMENT,\n"
+ " \"uuid\" TEXT NULL,\n"
+ " \"name\" TEXT NULL,\n"
+ " \"type\" TEXT NULL,\n"
+ " \"path\" TEXT NULL,\n"
+ " \"explicit\" INTEGER NULL)");
+ db.execute ("CREATE UNIQUE INDEX \"main\".\"configuration_uuid_i\"\n"
+ " ON \"configuration\" (\"uuid\")");
+ db.execute ("CREATE UNIQUE INDEX \"main\".\"configuration_name_i\"\n"
+ " ON \"configuration\" (\"name\")");
+ db.execute ("CREATE UNIQUE INDEX \"main\".\"configuration_path_i\"\n"
+ " ON \"configuration\" (\"path\")");
+ db.execute ("CREATE TABLE \"main\".\"repository_fragment\" (\n"
+ " \"name\" TEXT NULL PRIMARY KEY,\n"
+ " \"url\" TEXT NULL,\n"
+ " \"type\" TEXT NULL)");
+ db.execute ("CREATE TABLE \"main\".\"repository_fragment_complements\" (\n"
+ " \"repository_fragment\" TEXT NULL,\n"
+ " \"complement\" TEXT NULL,\n"
+ " CONSTRAINT \"repository_fragment_fk\"\n"
+ " FOREIGN KEY (\"repository_fragment\")\n"
+ " REFERENCES \"repository_fragment\" (\"name\")\n"
+ " ON DELETE CASCADE,\n"
+ " CONSTRAINT \"complement_fk\"\n"
+ " FOREIGN KEY (\"complement\")\n"
+ " REFERENCES \"repository\" (\"name\")\n"
+ " DEFERRABLE INITIALLY DEFERRED)");
+ db.execute ("CREATE INDEX \"main\".\"repository_fragment_complements_repository_fragment_i\"\n"
+ " ON \"repository_fragment_complements\" (\"repository_fragment\")");
+ db.execute ("CREATE TABLE \"main\".\"repository_fragment_prerequisites\" (\n"
+ " \"repository_fragment\" TEXT NULL,\n"
+ " \"prerequisite\" TEXT NULL,\n"
+ " CONSTRAINT \"repository_fragment_fk\"\n"
+ " FOREIGN KEY (\"repository_fragment\")\n"
+ " REFERENCES \"repository_fragment\" (\"name\")\n"
+ " ON DELETE CASCADE,\n"
+ " CONSTRAINT \"prerequisite_fk\"\n"
+ " FOREIGN KEY (\"prerequisite\")\n"
+ " REFERENCES \"repository\" (\"name\")\n"
+ " DEFERRABLE INITIALLY DEFERRED)");
+ db.execute ("CREATE INDEX \"main\".\"repository_fragment_prerequisites_repository_fragment_i\"\n"
+ " ON \"repository_fragment_prerequisites\" (\"repository_fragment\")");
+ db.execute ("CREATE TABLE \"main\".\"repository\" (\n"
+ " \"name\" TEXT NULL PRIMARY KEY,\n"
+ " \"url\" TEXT NULL,\n"
+ " \"type\" TEXT NULL,\n"
+ " \"certificate\" TEXT NULL,\n"
+ " \"local\" INTEGER NULL)");
+ db.execute ("CREATE TABLE \"main\".\"repository_fragments\" (\n"
+ " \"repository\" TEXT NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"friendly_name\" TEXT NULL,\n"
+ " \"fragment\" TEXT NULL,\n"
+ " CONSTRAINT \"repository_fk\"\n"
+ " FOREIGN KEY (\"repository\")\n"
+ " REFERENCES \"repository\" (\"name\")\n"
+ " ON DELETE CASCADE,\n"
+ " CONSTRAINT \"fragment_fk\"\n"
+ " FOREIGN KEY (\"fragment\")\n"
+ " REFERENCES \"repository_fragment\" (\"name\")\n"
+ " DEFERRABLE INITIALLY DEFERRED)");
+ db.execute ("CREATE INDEX \"main\".\"repository_fragments_repository_i\"\n"
+ " ON \"repository_fragments\" (\"repository\")");
+ db.execute ("CREATE INDEX \"main\".\"repository_fragments_index_i\"\n"
+ " ON \"repository_fragments\" (\"index\")");
+ db.execute ("CREATE TABLE \"main\".\"available_package\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"version_upstream\" TEXT NULL,\n"
+ " \"version_release\" TEXT NULL,\n"
+ " \"upstream_version\" TEXT NULL,\n"
+ " \"type\" TEXT NULL,\n"
+ " \"project\" TEXT NULL COLLATE NOCASE,\n"
+ " \"alt_naming\" INTEGER NULL DEFAULT 0,\n"
+ " \"bootstrap_build\" TEXT NULL DEFAULT '',\n"
+ " \"root_build\" TEXT NULL,\n"
+ " \"sha256sum\" TEXT NULL,\n"
+ " PRIMARY KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\"))");
+ db.execute ("CREATE TABLE \"main\".\"available_package_languages\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"language_name\" TEXT NULL,\n"
+ " \"language_impl\" INTEGER NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"main\".\"available_package_languages_object_id_i\"\n"
+ " ON \"available_package_languages\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE INDEX \"main\".\"available_package_languages_index_i\"\n"
+ " ON \"available_package_languages\" (\"index\")");
+ db.execute ("CREATE TABLE \"main\".\"available_package_locations\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"repository_fragment\" TEXT NULL,\n"
+ " \"location\" TEXT NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE,\n"
+ " CONSTRAINT \"repository_fragment_fk\"\n"
+ " FOREIGN KEY (\"repository_fragment\")\n"
+ " REFERENCES \"repository_fragment\" (\"name\")\n"
+ " DEFERRABLE INITIALLY DEFERRED)");
+ db.execute ("CREATE INDEX \"main\".\"available_package_locations_object_id_i\"\n"
+ " ON \"available_package_locations\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE TABLE \"main\".\"available_package_dependencies\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"buildtime\" INTEGER NULL,\n"
+ " \"comment\" TEXT NULL,\n"
+ " \"type\" TEXT NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"main\".\"available_package_dependencies_object_id_i\"\n"
+ " ON \"available_package_dependencies\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE INDEX \"main\".\"available_package_dependencies_index_i\"\n"
+ " ON \"available_package_dependencies\" (\"index\")");
+ db.execute ("CREATE TABLE \"main\".\"available_package_dependency_alternatives\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"dependency_index\" INTEGER NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"enable\" TEXT NULL,\n"
+ " \"reflect\" TEXT NULL,\n"
+ " \"prefer\" TEXT NULL,\n"
+ " \"accept\" TEXT NULL,\n"
+ " \"require\" TEXT NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"main\".\"available_package_dependency_alternatives_object_id_i\"\n"
+ " ON \"available_package_dependency_alternatives\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE TABLE \"main\".\"available_package_dependency_alternative_dependencies\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"dependency_index\" INTEGER NULL,\n"
+ " \"alternative_index\" INTEGER NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"dep_name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"dep_min_version_epoch\" INTEGER NULL,\n"
+ " \"dep_min_version_canonical_upstream\" TEXT NULL,\n"
+ " \"dep_min_version_canonical_release\" TEXT NULL,\n"
+ " \"dep_min_version_revision\" INTEGER NULL,\n"
+ " \"dep_min_version_iteration\" INTEGER NULL,\n"
+ " \"dep_min_version_upstream\" TEXT NULL,\n"
+ " \"dep_min_version_release\" TEXT NULL,\n"
+ " \"dep_max_version_epoch\" INTEGER NULL,\n"
+ " \"dep_max_version_canonical_upstream\" TEXT NULL,\n"
+ " \"dep_max_version_canonical_release\" TEXT NULL,\n"
+ " \"dep_max_version_revision\" INTEGER NULL,\n"
+ " \"dep_max_version_iteration\" INTEGER NULL,\n"
+ " \"dep_max_version_upstream\" TEXT NULL,\n"
+ " \"dep_max_version_release\" TEXT NULL,\n"
+ " \"dep_min_open\" INTEGER NULL,\n"
+ " \"dep_max_open\" INTEGER NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"main\".\"available_package_dependency_alternative_dependencies_object_id_i\"\n"
+ " ON \"available_package_dependency_alternative_dependencies\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE TABLE \"main\".\"available_package_tests\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"test_name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"test_min_version_epoch\" INTEGER NULL,\n"
+ " \"test_min_version_canonical_upstream\" TEXT NULL,\n"
+ " \"test_min_version_canonical_release\" TEXT NULL,\n"
+ " \"test_min_version_revision\" INTEGER NULL,\n"
+ " \"test_min_version_iteration\" INTEGER NULL,\n"
+ " \"test_min_version_upstream\" TEXT NULL,\n"
+ " \"test_min_version_release\" TEXT NULL,\n"
+ " \"test_max_version_epoch\" INTEGER NULL,\n"
+ " \"test_max_version_canonical_upstream\" TEXT NULL,\n"
+ " \"test_max_version_canonical_release\" TEXT NULL,\n"
+ " \"test_max_version_revision\" INTEGER NULL,\n"
+ " \"test_max_version_iteration\" INTEGER NULL,\n"
+ " \"test_max_version_upstream\" TEXT NULL,\n"
+ " \"test_max_version_release\" TEXT NULL,\n"
+ " \"test_min_open\" INTEGER NULL,\n"
+ " \"test_max_open\" INTEGER NULL,\n"
+ " \"test_type\" TEXT NULL,\n"
+ " \"test_buildtime\" INTEGER NULL DEFAULT 0,\n"
+ " \"test_enable\" TEXT NULL,\n"
+ " \"test_reflect\" TEXT NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"main\".\"available_package_tests_object_id_i\"\n"
+ " ON \"available_package_tests\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE INDEX \"main\".\"available_package_tests_index_i\"\n"
+ " ON \"available_package_tests\" (\"index\")");
+ db.execute ("CREATE TABLE \"main\".\"available_package_buildfiles\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"path\" TEXT NULL,\n"
+ " \"content\" TEXT NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"main\".\"available_package_buildfiles_object_id_i\"\n"
+ " ON \"available_package_buildfiles\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE INDEX \"main\".\"available_package_buildfiles_index_i\"\n"
+ " ON \"available_package_buildfiles\" (\"index\")");
+ db.execute ("CREATE TABLE \"main\".\"available_package_distribution_values\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"dist_name\" TEXT NULL,\n"
+ " \"dist_value\" TEXT NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"main\".\"available_package_distribution_values_object_id_i\"\n"
+ " ON \"available_package_distribution_values\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE INDEX \"main\".\"available_package_distribution_values_index_i\"\n"
+ " ON \"available_package_distribution_values\" (\"index\")");
+ db.execute ("CREATE TABLE \"main\".\"selected_package\" (\n"
+ " \"name\" TEXT NULL PRIMARY KEY COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"version_upstream\" TEXT NULL,\n"
+ " \"version_release\" TEXT NULL,\n"
+ " \"state\" TEXT NULL,\n"
+ " \"substate\" TEXT NULL,\n"
+ " \"hold_package\" INTEGER NULL,\n"
+ " \"hold_version\" INTEGER NULL,\n"
+ " \"repository_fragment_url\" TEXT NULL,\n"
+ " \"repository_fragment_type\" TEXT NULL,\n"
+ " \"archive\" TEXT NULL,\n"
+ " \"purge_archive\" INTEGER NULL,\n"
+ " \"src_root\" TEXT NULL,\n"
+ " \"purge_src\" INTEGER NULL,\n"
+ " \"manifest_checksum\" TEXT NULL,\n"
+ " \"buildfiles_checksum\" TEXT NULL,\n"
+ " \"out_root\" TEXT NULL,\n"
+ " \"config_checksum\" TEXT NULL DEFAULT '')");
+ db.execute ("CREATE TABLE \"main\".\"selected_package_prerequisites\" (\n"
+ " \"package\" TEXT NULL COLLATE NOCASE,\n"
+ " \"configuration\" TEXT NULL,\n"
+ " \"prerequisite\" TEXT NULL COLLATE NOCASE,\n"
+ " \"min_version_epoch\" INTEGER NULL,\n"
+ " \"min_version_canonical_upstream\" TEXT NULL,\n"
+ " \"min_version_canonical_release\" TEXT NULL,\n"
+ " \"min_version_revision\" INTEGER NULL,\n"
+ " \"min_version_iteration\" INTEGER NULL,\n"
+ " \"min_version_upstream\" TEXT NULL,\n"
+ " \"min_version_release\" TEXT NULL,\n"
+ " \"max_version_epoch\" INTEGER NULL,\n"
+ " \"max_version_canonical_upstream\" TEXT NULL,\n"
+ " \"max_version_canonical_release\" TEXT NULL,\n"
+ " \"max_version_revision\" INTEGER NULL,\n"
+ " \"max_version_iteration\" INTEGER NULL,\n"
+ " \"max_version_upstream\" TEXT NULL,\n"
+ " \"max_version_release\" TEXT NULL,\n"
+ " \"min_open\" INTEGER NULL,\n"
+ " \"max_open\" INTEGER NULL,\n"
+ " CONSTRAINT \"package_fk\"\n"
+ " FOREIGN KEY (\"package\")\n"
+ " REFERENCES \"selected_package\" (\"name\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"main\".\"selected_package_prerequisites_package_i\"\n"
+ " ON \"selected_package_prerequisites\" (\"package\")");
+ db.execute ("CREATE TABLE \"main\".\"selected_package_dependency_alternatives\" (\n"
+ " \"package\" TEXT NULL COLLATE NOCASE,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"position\" INTEGER NULL,\n"
+ " CONSTRAINT \"package_fk\"\n"
+ " FOREIGN KEY (\"package\")\n"
+ " REFERENCES \"selected_package\" (\"name\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"main\".\"selected_package_dependency_alternatives_package_i\"\n"
+ " ON \"selected_package_dependency_alternatives\" (\"package\")");
+ db.execute ("CREATE INDEX \"main\".\"selected_package_dependency_alternatives_index_i\"\n"
+ " ON \"selected_package_dependency_alternatives\" (\"index\")");
+ db.execute ("CREATE TABLE \"main\".\"selected_package_config_variables\" (\n"
+ " \"package\" TEXT NULL COLLATE NOCASE,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"name\" TEXT NULL,\n"
+ " \"source\" TEXT NULL,\n"
+ " CONSTRAINT \"package_fk\"\n"
+ " FOREIGN KEY (\"package\")\n"
+ " REFERENCES \"selected_package\" (\"name\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"main\".\"selected_package_config_variables_package_i\"\n"
+ " ON \"selected_package_config_variables\" (\"package\")");
+ db.execute ("CREATE INDEX \"main\".\"selected_package_config_variables_index_i\"\n"
+ " ON \"selected_package_config_variables\" (\"index\")");
+ db.execute ("CREATE TABLE \"main\".\"certificate\" (\n"
+ " \"id\" TEXT NULL PRIMARY KEY,\n"
+ " \"fingerprint\" TEXT NULL,\n"
+ " \"name\" TEXT NULL,\n"
+ " \"organization\" TEXT NULL,\n"
+ " \"email\" TEXT NULL,\n"
+ " \"start_date\" INTEGER NULL,\n"
+ " \"end_date\" INTEGER NULL)");
+ return true;
+ }
+ case 2:
+ {
+ db.execute ("CREATE TABLE IF NOT EXISTS \"main\".\"schema_version\" (\n"
+ " \"name\" TEXT NOT NULL PRIMARY KEY,\n"
+ " \"version\" INTEGER NOT NULL,\n"
+ " \"migration\" INTEGER NOT NULL)");
+ db.execute ("INSERT OR IGNORE INTO \"main\".\"schema_version\" (\n"
+ " \"name\", \"version\", \"migration\")\n"
+ " VALUES ('', 26, 0)");
+ return false;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ static const schema_catalog_create_entry
+ create_schema_entry_ (
+ id_sqlite,
+ "",
+ &create_schema);
+
+ static const schema_catalog_migrate_entry
+ migrate_schema_entry_23_ (
+ id_sqlite,
+ "",
+ 23ULL,
+ 0);
+
+ static bool
+ migrate_schema_24 (database& db, unsigned short pass, bool pre)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (pass);
+ ODB_POTENTIALLY_UNUSED (pre);
+
+ if (pre)
+ {
+ switch (pass)
+ {
+ case 1:
+ {
+ db.execute ("ALTER TABLE \"main\".\"selected_package\"\n"
+ " ADD COLUMN \"config_checksum\" TEXT NULL DEFAULT ''");
+ return true;
+ }
+ case 2:
+ {
+ db.execute ("UPDATE \"main\".\"schema_version\"\n"
+ " SET \"version\" = 24, \"migration\" = 1\n"
+ " WHERE \"name\" = ''");
+ return false;
+ }
+ }
+ }
+ else
+ {
+ switch (pass)
+ {
+ case 1:
+ {
+ return true;
+ }
+ case 2:
+ {
+ db.execute ("UPDATE \"main\".\"schema_version\"\n"
+ " SET \"migration\" = 0\n"
+ " WHERE \"name\" = ''");
+ return false;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ static const schema_catalog_migrate_entry
+ migrate_schema_entry_24_ (
+ id_sqlite,
+ "",
+ 24ULL,
+ &migrate_schema_24);
+
+ static bool
+ migrate_schema_25 (database& db, unsigned short pass, bool pre)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (pass);
+ ODB_POTENTIALLY_UNUSED (pre);
+
+ if (pre)
+ {
+ switch (pass)
+ {
+ case 1:
+ {
+ db.execute ("CREATE TABLE \"main\".\"selected_package_dependency_alternatives\" (\n"
+ " \"package\" TEXT NULL COLLATE NOCASE,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"position\" INTEGER NULL,\n"
+ " CONSTRAINT \"package_fk\"\n"
+ " FOREIGN KEY (\"package\")\n"
+ " REFERENCES \"selected_package\" (\"name\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"main\".\"selected_package_dependency_alternatives_package_i\"\n"
+ " ON \"selected_package_dependency_alternatives\" (\"package\")");
+ db.execute ("CREATE INDEX \"main\".\"selected_package_dependency_alternatives_index_i\"\n"
+ " ON \"selected_package_dependency_alternatives\" (\"index\")");
+ return true;
+ }
+ case 2:
+ {
+ db.execute ("UPDATE \"main\".\"schema_version\"\n"
+ " SET \"version\" = 25, \"migration\" = 1\n"
+ " WHERE \"name\" = ''");
+ return false;
+ }
+ }
+ }
+ else
+ {
+ switch (pass)
+ {
+ case 1:
+ {
+ return true;
+ }
+ case 2:
+ {
+ db.execute ("UPDATE \"main\".\"selected_package_prerequisites\"\n"
+ " SET \"config_dependency_index\" = NULL,\n"
+ " \"config_alternative_index\" = NULL");
+ db.execute ("UPDATE \"main\".\"schema_version\"\n"
+ " SET \"migration\" = 0\n"
+ " WHERE \"name\" = ''");
+ return false;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ static const schema_catalog_migrate_entry
+ migrate_schema_entry_25_ (
+ id_sqlite,
+ "",
+ 25ULL,
+ &migrate_schema_25);
+
+ static bool
+ migrate_schema_26 (database& db, unsigned short pass, bool pre)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (pass);
+ ODB_POTENTIALLY_UNUSED (pre);
+
+ if (pre)
+ {
+ switch (pass)
+ {
+ case 1:
+ {
+ db.execute ("ALTER TABLE \"main\".\"available_package_tests\"\n"
+ " ADD COLUMN \"test_enable\" TEXT NULL");
+ return true;
+ }
+ case 2:
+ {
+ db.execute ("UPDATE \"main\".\"schema_version\"\n"
+ " SET \"version\" = 26, \"migration\" = 1\n"
+ " WHERE \"name\" = ''");
+ return false;
+ }
+ }
+ }
+ else
+ {
+ switch (pass)
+ {
+ case 1:
+ {
+ return true;
+ }
+ case 2:
+ {
+ db.execute ("UPDATE \"main\".\"schema_version\"\n"
+ " SET \"migration\" = 0\n"
+ " WHERE \"name\" = ''");
+ return false;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ static const schema_catalog_migrate_entry
+ migrate_schema_entry_26_ (
+ id_sqlite,
+ "",
+ 26ULL,
+ &migrate_schema_26);
+}
+
+#include <odb/post.hxx>
diff --git a/bpkg/package-odb.hxx b/bpkg/package-odb.hxx
new file mode 100644
index 0000000..a60efde
--- /dev/null
+++ b/bpkg/package-odb.hxx
@@ -0,0 +1,6023 @@
+// -*- C++ -*-
+//
+// This file was generated by ODB, object-relational mapping (ORM)
+// compiler for C++.
+//
+
+#ifndef BPKG_PACKAGE_ODB_HXX
+#define BPKG_PACKAGE_ODB_HXX
+
+// Begin prologue.
+//
+#include <libbutl/small-vector-odb.hxx>
+#include <bpkg/pointer-traits.hxx>
+#include <bpkg/wrapper-traits.hxx>
+#include <bpkg/value-traits.hxx>
+//
+// End prologue.
+
+#include <odb/version.hxx>
+
+#if ODB_VERSION != 20478UL
+#error ODB runtime version mismatch
+#endif
+
+#include <odb/pre.hxx>
+
+#include <bpkg/package.hxx>
+
+#include <memory>
+#include <cstddef>
+#include <utility>
+
+#include <odb/core.hxx>
+#include <odb/traits.hxx>
+#include <odb/callback.hxx>
+#include <odb/wrapper-traits.hxx>
+#include <odb/pointer-traits.hxx>
+#include <odb/container-traits.hxx>
+#include <odb/session.hxx>
+#include <odb/cache-traits.hxx>
+#include <odb/prepared-query.hxx>
+#include <odb/result.hxx>
+#include <odb/simple-object-result.hxx>
+#include <odb/view-image.hxx>
+#include <odb/view-result.hxx>
+
+#include <odb/details/unused.hxx>
+#include <odb/details/shared-ptr.hxx>
+
+namespace odb
+{
+ // configuration
+ //
+ template <>
+ struct class_traits< ::bpkg::configuration >
+ {
+ static const class_kind kind = class_object;
+ };
+
+ template <>
+ class access::object_traits< ::bpkg::configuration >
+ {
+ public:
+ typedef ::bpkg::configuration object_type;
+ typedef ::std::shared_ptr< ::bpkg::configuration > pointer_type;
+ typedef odb::pointer_traits<pointer_type> pointer_traits;
+
+ static const bool polymorphic = false;
+
+ typedef ::bpkg::optional_uint64_t id_type;
+
+ static const bool auto_id = true;
+
+ static const bool abstract = false;
+
+ static id_type
+ id (const object_type&);
+
+ typedef
+ no_op_pointer_cache_traits<pointer_type>
+ pointer_cache_traits;
+
+ typedef
+ no_op_reference_cache_traits<object_type>
+ reference_cache_traits;
+
+ static void
+ callback (database&, object_type&, callback_event);
+
+ static void
+ callback (database&, const object_type&, callback_event);
+ };
+
+ // repository_fragment
+ //
+ template <>
+ struct class_traits< ::bpkg::repository_fragment >
+ {
+ static const class_kind kind = class_object;
+ };
+
+ template <>
+ class access::object_traits< ::bpkg::repository_fragment >
+ {
+ public:
+ typedef ::bpkg::repository_fragment object_type;
+ typedef ::std::shared_ptr< ::bpkg::repository_fragment > pointer_type;
+ typedef odb::pointer_traits<pointer_type> pointer_traits;
+
+ static const bool polymorphic = false;
+
+ typedef ::std::string id_type;
+
+ static const bool auto_id = false;
+
+ static const bool abstract = false;
+
+ static id_type
+ id (const object_type&);
+
+ typedef
+ odb::pointer_cache_traits<
+ pointer_type,
+ odb::session >
+ pointer_cache_traits;
+
+ typedef
+ odb::reference_cache_traits<
+ object_type,
+ odb::session >
+ reference_cache_traits;
+
+ static void
+ callback (database&, object_type&, callback_event);
+
+ static void
+ callback (database&, const object_type&, callback_event);
+ };
+
+ // repository_fragment_count
+ //
+ template <>
+ struct class_traits< ::bpkg::repository_fragment_count >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::repository_fragment_count >
+ {
+ public:
+ typedef ::bpkg::repository_fragment_count view_type;
+ typedef ::bpkg::repository_fragment_count* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+
+ // repository
+ //
+ template <>
+ struct class_traits< ::bpkg::repository >
+ {
+ static const class_kind kind = class_object;
+ };
+
+ template <>
+ class access::object_traits< ::bpkg::repository >
+ {
+ public:
+ typedef ::bpkg::repository object_type;
+ typedef ::std::shared_ptr< ::bpkg::repository > pointer_type;
+ typedef odb::pointer_traits<pointer_type> pointer_traits;
+
+ static const bool polymorphic = false;
+
+ typedef ::std::string id_type;
+
+ static const bool auto_id = false;
+
+ static const bool abstract = false;
+
+ static id_type
+ id (const object_type&);
+
+ typedef
+ odb::pointer_cache_traits<
+ pointer_type,
+ odb::session >
+ pointer_cache_traits;
+
+ typedef
+ odb::reference_cache_traits<
+ object_type,
+ odb::session >
+ reference_cache_traits;
+
+ static void
+ callback (database&, object_type&, callback_event);
+
+ static void
+ callback (database&, const object_type&, callback_event);
+ };
+
+ // repository_count
+ //
+ template <>
+ struct class_traits< ::bpkg::repository_count >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::repository_count >
+ {
+ public:
+ typedef ::bpkg::repository_count view_type;
+ typedef ::bpkg::repository_count* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+
+ // available_package
+ //
+ template <>
+ struct class_traits< ::bpkg::available_package >
+ {
+ static const class_kind kind = class_object;
+ };
+
+ template <>
+ class access::object_traits< ::bpkg::available_package >
+ {
+ public:
+ typedef ::bpkg::available_package object_type;
+ typedef ::std::shared_ptr< ::bpkg::available_package > pointer_type;
+ typedef odb::pointer_traits<pointer_type> pointer_traits;
+
+ static const bool polymorphic = false;
+
+ typedef ::bpkg::available_package_id id_type;
+
+ static const bool auto_id = false;
+
+ static const bool abstract = false;
+
+ static id_type
+ id (const object_type&);
+
+ typedef
+ odb::pointer_cache_traits<
+ pointer_type,
+ odb::session >
+ pointer_cache_traits;
+
+ typedef
+ odb::reference_cache_traits<
+ object_type,
+ odb::session >
+ reference_cache_traits;
+
+ static void
+ callback (database&, object_type&, callback_event);
+
+ static void
+ callback (database&, const object_type&, callback_event);
+ };
+
+ // available_package_count
+ //
+ template <>
+ struct class_traits< ::bpkg::available_package_count >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::available_package_count >
+ {
+ public:
+ typedef ::bpkg::available_package_count view_type;
+ typedef ::bpkg::available_package_count* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+
+ // available_test
+ //
+ template <>
+ struct class_traits< ::bpkg::available_test >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::available_test >
+ {
+ public:
+ typedef ::bpkg::available_test view_type;
+ typedef ::bpkg::available_test* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+
+ // available_main
+ //
+ template <>
+ struct class_traits< ::bpkg::available_main >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::available_main >
+ {
+ public:
+ typedef ::bpkg::available_main view_type;
+ typedef ::bpkg::available_main* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+
+ // selected_package
+ //
+ template <>
+ struct class_traits< ::bpkg::selected_package >
+ {
+ static const class_kind kind = class_object;
+ };
+
+ template <>
+ class access::object_traits< ::bpkg::selected_package >
+ {
+ public:
+ typedef ::bpkg::selected_package object_type;
+ typedef ::std::shared_ptr< ::bpkg::selected_package > pointer_type;
+ typedef odb::pointer_traits<pointer_type> pointer_traits;
+
+ static const bool polymorphic = false;
+
+ typedef ::bpkg::package_name id_type;
+
+ static const bool auto_id = false;
+
+ static const bool abstract = false;
+
+ static id_type
+ id (const object_type&);
+
+ typedef
+ odb::pointer_cache_traits<
+ pointer_type,
+ odb::session >
+ pointer_cache_traits;
+
+ typedef
+ odb::reference_cache_traits<
+ object_type,
+ odb::session >
+ reference_cache_traits;
+
+ static void
+ callback (database&, object_type&, callback_event);
+
+ static void
+ callback (database&, const object_type&, callback_event);
+ };
+
+ // certificate
+ //
+ template <>
+ struct class_traits< ::bpkg::certificate >
+ {
+ static const class_kind kind = class_object;
+ };
+
+ template <>
+ class access::object_traits< ::bpkg::certificate >
+ {
+ public:
+ typedef ::bpkg::certificate object_type;
+ typedef ::std::shared_ptr< ::bpkg::certificate > pointer_type;
+ typedef odb::pointer_traits<pointer_type> pointer_traits;
+
+ static const bool polymorphic = false;
+
+ typedef ::std::string id_type;
+
+ static const bool auto_id = false;
+
+ static const bool abstract = false;
+
+ static id_type
+ id (const object_type&);
+
+ typedef
+ odb::pointer_cache_traits<
+ pointer_type,
+ odb::session >
+ pointer_cache_traits;
+
+ typedef
+ odb::reference_cache_traits<
+ object_type,
+ odb::session >
+ reference_cache_traits;
+
+ static void
+ callback (database&, object_type&, callback_event);
+
+ static void
+ callback (database&, const object_type&, callback_event);
+ };
+
+ // package_dependent
+ //
+ template <>
+ struct class_traits< ::bpkg::package_dependent >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::package_dependent >
+ {
+ public:
+ typedef ::bpkg::package_dependent view_type;
+ typedef ::bpkg::package_dependent* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+
+ // fragment_repository_count
+ //
+ template <>
+ struct class_traits< ::bpkg::fragment_repository_count >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::fragment_repository_count >
+ {
+ public:
+ typedef ::bpkg::fragment_repository_count view_type;
+ typedef ::bpkg::fragment_repository_count* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+
+ // fragment_repository
+ //
+ template <>
+ struct class_traits< ::bpkg::fragment_repository >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::fragment_repository >
+ {
+ public:
+ typedef ::bpkg::fragment_repository view_type;
+ typedef ::bpkg::fragment_repository* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+
+ // repository_complement_dependent
+ //
+ template <>
+ struct class_traits< ::bpkg::repository_complement_dependent >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::repository_complement_dependent >
+ {
+ public:
+ typedef ::bpkg::repository_complement_dependent view_type;
+ typedef ::bpkg::repository_complement_dependent* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+
+ // repository_prerequisite_dependent
+ //
+ template <>
+ struct class_traits< ::bpkg::repository_prerequisite_dependent >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::repository_prerequisite_dependent >
+ {
+ public:
+ typedef ::bpkg::repository_prerequisite_dependent view_type;
+ typedef ::bpkg::repository_prerequisite_dependent* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+
+ // repository_fragment_package
+ //
+ template <>
+ struct class_traits< ::bpkg::repository_fragment_package >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::repository_fragment_package >
+ {
+ public:
+ typedef ::bpkg::repository_fragment_package view_type;
+ typedef ::bpkg::repository_fragment_package* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+
+ // package_repository_fragment
+ //
+ template <>
+ struct class_traits< ::bpkg::package_repository_fragment >
+ {
+ static const class_kind kind = class_view;
+ };
+
+ template <>
+ class access::view_traits< ::bpkg::package_repository_fragment >
+ {
+ public:
+ typedef ::bpkg::package_repository_fragment view_type;
+ typedef ::bpkg::package_repository_fragment* pointer_type;
+
+ static void
+ callback (database&, view_type&, callback_event);
+ };
+}
+
+#include <odb/details/buffer.hxx>
+
+#include <odb/sqlite/version.hxx>
+#include <odb/sqlite/forward.hxx>
+#include <odb/sqlite/binding.hxx>
+#include <odb/sqlite/sqlite-types.hxx>
+#include <odb/sqlite/query.hxx>
+
+namespace odb
+{
+ // _version
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::_version, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::_version value_type;
+
+ struct image_type
+ {
+ // epoch
+ //
+ long long epoch_value;
+ bool epoch_null;
+
+ // canonical_upstream
+ //
+ details::buffer canonical_upstream_value;
+ std::size_t canonical_upstream_size;
+ bool canonical_upstream_null;
+
+ // canonical_release
+ //
+ details::buffer canonical_release_value;
+ std::size_t canonical_release_size;
+ bool canonical_release_null;
+
+ // revision
+ //
+ long long revision_value;
+ bool revision_null;
+
+ // iteration
+ //
+ long long iteration_value;
+ bool iteration_null;
+
+ // upstream
+ //
+ details::buffer upstream_value;
+ std::size_t upstream_size;
+ bool upstream_null;
+
+ // release
+ //
+ details::buffer release_value;
+ std::size_t release_size;
+ bool release_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 7UL;
+ };
+
+ // language
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::language, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::language value_type;
+
+ struct image_type
+ {
+ // name
+ //
+ details::buffer name_value;
+ std::size_t name_size;
+ bool name_null;
+
+ // impl
+ //
+ long long impl_value;
+ bool impl_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 2UL;
+ };
+
+ // version_constraint
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::version_constraint, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::version_constraint value_type;
+
+ struct image_type
+ {
+ // min_version
+ //
+ composite_value_traits< ::bpkg::_version, id_sqlite >::image_type min_version_value;
+
+ // max_version
+ //
+ composite_value_traits< ::bpkg::_version, id_sqlite >::image_type max_version_value;
+
+ // min_open
+ //
+ long long min_open_value;
+ bool min_open_null;
+
+ // max_open
+ //
+ long long max_open_value;
+ bool max_open_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 16UL;
+ };
+
+ // dependency
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::dependency, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::dependency value_type;
+
+ struct image_type
+ {
+ // name
+ //
+ details::buffer name_value;
+ std::size_t name_size;
+ bool name_null;
+
+ // constraint
+ //
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::image_type constraint_value;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 17UL;
+ };
+
+ // dependency_alternative
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::dependency_alternative, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::dependency_alternative value_type;
+
+ struct image_type
+ {
+ // enable
+ //
+ details::buffer enable_value;
+ std::size_t enable_size;
+ bool enable_null;
+
+ // reflect
+ //
+ details::buffer reflect_value;
+ std::size_t reflect_size;
+ bool reflect_null;
+
+ // prefer
+ //
+ details::buffer prefer_value;
+ std::size_t prefer_size;
+ bool prefer_null;
+
+ // accept
+ //
+ details::buffer accept_value;
+ std::size_t accept_size;
+ bool accept_null;
+
+ // require
+ //
+ details::buffer require_value;
+ std::size_t require_size;
+ bool require_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 5UL;
+ };
+
+ // dependency_alternatives
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::dependency_alternatives value_type;
+
+ struct image_type
+ {
+ // buildtime
+ //
+ long long buildtime_value;
+ bool buildtime_null;
+
+ // comment
+ //
+ details::buffer comment_value;
+ std::size_t comment_size;
+ bool comment_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 2UL;
+ };
+
+ // test_dependency
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::test_dependency, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::test_dependency value_type;
+
+ struct image_type: composite_value_traits< ::bpkg::dependency, id_sqlite >::image_type
+ {
+ // type
+ //
+ details::buffer type_value;
+ std::size_t type_size;
+ bool type_null;
+
+ // buildtime
+ //
+ long long buildtime_value;
+ bool buildtime_null;
+
+ // enable
+ //
+ details::buffer enable_value;
+ std::size_t enable_size;
+ bool enable_null;
+
+ // reflect
+ //
+ details::buffer reflect_value;
+ std::size_t reflect_size;
+ bool reflect_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 21UL;
+ };
+
+ // buildfile
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::buildfile, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::buildfile value_type;
+
+ struct image_type
+ {
+ // path
+ //
+ details::buffer path_value;
+ std::size_t path_size;
+ bool path_null;
+
+ // content
+ //
+ details::buffer content_value;
+ std::size_t content_size;
+ bool content_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 2UL;
+ };
+
+ // distribution_name_value
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::distribution_name_value, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::distribution_name_value value_type;
+
+ struct image_type
+ {
+ // name
+ //
+ details::buffer name_value;
+ std::size_t name_size;
+ bool name_null;
+
+ // value
+ //
+ details::buffer value_value;
+ std::size_t value_size;
+ bool value_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 2UL;
+ };
+
+ // configuration
+ //
+ template <typename A>
+ struct query_columns< ::bpkg::configuration, id_sqlite, A >
+ {
+ // id
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ long unsigned int,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ id_type_;
+
+ static const id_type_ id;
+
+ // uuid
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ uuid_type_;
+
+ static const uuid_type_ uuid;
+
+ // name
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ name_type_;
+
+ static const name_type_ name;
+
+ // type
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ type_type_;
+
+ static const type_type_ type;
+
+ // path
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ path_type_;
+
+ static const path_type_ path;
+
+ // expl
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ expl_type_;
+
+ static const expl_type_ expl;
+ };
+
+ template <typename A>
+ const typename query_columns< ::bpkg::configuration, id_sqlite, A >::id_type_
+ query_columns< ::bpkg::configuration, id_sqlite, A >::
+ id (A::table_name, "\"id\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::configuration, id_sqlite, A >::uuid_type_
+ query_columns< ::bpkg::configuration, id_sqlite, A >::
+ uuid (A::table_name, "\"uuid\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::configuration, id_sqlite, A >::name_type_
+ query_columns< ::bpkg::configuration, id_sqlite, A >::
+ name (A::table_name, "\"name\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::configuration, id_sqlite, A >::type_type_
+ query_columns< ::bpkg::configuration, id_sqlite, A >::
+ type (A::table_name, "\"type\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::configuration, id_sqlite, A >::path_type_
+ query_columns< ::bpkg::configuration, id_sqlite, A >::
+ path (A::table_name, "\"path\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::configuration, id_sqlite, A >::expl_type_
+ query_columns< ::bpkg::configuration, id_sqlite, A >::
+ expl (A::table_name, "\"explicit\"", 0);
+
+ template <typename A>
+ struct pointer_query_columns< ::bpkg::configuration, id_sqlite, A >:
+ query_columns< ::bpkg::configuration, id_sqlite, A >
+ {
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::configuration, id_sqlite >:
+ public access::object_traits< ::bpkg::configuration >
+ {
+ public:
+ struct id_image_type
+ {
+ long long id_value;
+ bool id_null;
+
+ std::size_t version;
+ };
+
+ struct image_type
+ {
+ // id
+ //
+ long long id_value;
+ bool id_null;
+
+ // uuid
+ //
+ details::buffer uuid_value;
+ std::size_t uuid_size;
+ bool uuid_null;
+
+ // name
+ //
+ details::buffer name_value;
+ std::size_t name_size;
+ bool name_null;
+
+ // type
+ //
+ details::buffer type_value;
+ std::size_t type_size;
+ bool type_null;
+
+ // path
+ //
+ details::buffer path_value;
+ std::size_t path_size;
+ bool path_null;
+
+ // expl
+ //
+ long long expl_value;
+ bool expl_null;
+
+ std::size_t version;
+ };
+
+ struct extra_statement_cache_type;
+
+ using object_traits<object_type>::id;
+
+ static id_type
+ id (const id_image_type&);
+
+ static id_type
+ id (const image_type&);
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static void
+ bind (sqlite::bind*, id_image_type&);
+
+ static bool
+ init (image_type&,
+ const object_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (object_type&,
+ const image_type&,
+ database*);
+
+ static void
+ init (id_image_type&, const id_type&);
+
+ typedef sqlite::object_statements<object_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+
+ static const std::size_t column_count = 6UL;
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t inverse_column_count = 0UL;
+ static const std::size_t readonly_column_count = 0UL;
+ static const std::size_t managed_optimistic_column_count = 0UL;
+
+ static const std::size_t separate_load_column_count = 0UL;
+ static const std::size_t separate_update_column_count = 0UL;
+
+ static const bool versioned = false;
+
+ static const char persist_statement[];
+ static const char find_statement[];
+ static const char update_statement[];
+ static const char erase_statement[];
+ static const char query_statement[];
+ static const char erase_query_statement[];
+
+ static const char table_name[];
+
+ static void
+ persist (database&, object_type&);
+
+ static pointer_type
+ find (database&, const id_type&);
+
+ static bool
+ find (database&, const id_type&, object_type&);
+
+ static bool
+ reload (database&, object_type&);
+
+ static void
+ update (database&, const object_type&);
+
+ static void
+ erase (database&, const id_type&);
+
+ static void
+ erase (database&, const object_type&);
+
+ static result<object_type>
+ query (database&, const query_base_type&);
+
+ static unsigned long long
+ erase_query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+
+ public:
+ static bool
+ find_ (statements_type&,
+ const id_type*);
+
+ static void
+ load_ (statements_type&,
+ object_type&,
+ bool reload);
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::configuration, id_common >:
+ public access::object_traits_impl< ::bpkg::configuration, id_sqlite >
+ {
+ };
+
+ // canonical_version
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::canonical_version, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::canonical_version value_type;
+
+ struct image_type
+ {
+ // epoch
+ //
+ long long epoch_value;
+ bool epoch_null;
+
+ // canonical_upstream
+ //
+ details::buffer canonical_upstream_value;
+ std::size_t canonical_upstream_size;
+ bool canonical_upstream_null;
+
+ // canonical_release
+ //
+ details::buffer canonical_release_value;
+ std::size_t canonical_release_size;
+ bool canonical_release_null;
+
+ // revision
+ //
+ long long revision_value;
+ bool revision_null;
+
+ // iteration
+ //
+ long long iteration_value;
+ bool iteration_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 5UL;
+ };
+
+ // upstream_version
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::upstream_version, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::upstream_version value_type;
+
+ struct image_type
+ {
+ // upstream_
+ //
+ details::buffer upstream_value;
+ std::size_t upstream_size;
+ bool upstream_null;
+
+ // release_
+ //
+ details::buffer release_value;
+ std::size_t release_size;
+ bool release_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 2UL;
+ };
+
+ // _repository_location
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::_repository_location, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::_repository_location value_type;
+
+ struct image_type
+ {
+ // url
+ //
+ details::buffer url_value;
+ std::size_t url_size;
+ bool url_null;
+
+ // type
+ //
+ details::buffer type_value;
+ std::size_t type_size;
+ bool type_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 2UL;
+ };
+
+ // repository_fragment
+ //
+ template <typename A>
+ struct query_columns< ::bpkg::repository_fragment, id_sqlite, A >
+ {
+ // name
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ name_type_;
+
+ static const name_type_ name;
+
+ // location
+ //
+ struct location_class_
+ {
+ location_class_ ()
+ {
+ }
+
+ // url
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ url_type_;
+
+ static const url_type_ url;
+
+ // type
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ type_type_;
+
+ static const type_type_ type;
+ };
+
+ static const location_class_ location;
+ };
+
+ template <typename A>
+ const typename query_columns< ::bpkg::repository_fragment, id_sqlite, A >::name_type_
+ query_columns< ::bpkg::repository_fragment, id_sqlite, A >::
+ name (A::table_name, "\"name\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::repository_fragment, id_sqlite, A >::location_class_::url_type_
+ query_columns< ::bpkg::repository_fragment, id_sqlite, A >::location_class_::
+ url (A::table_name, "\"url\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::repository_fragment, id_sqlite, A >::location_class_::type_type_
+ query_columns< ::bpkg::repository_fragment, id_sqlite, A >::location_class_::
+ type (A::table_name, "\"type\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::repository_fragment, id_sqlite, A >::location_class_
+ query_columns< ::bpkg::repository_fragment, id_sqlite, A >::location;
+
+ template <typename A>
+ struct pointer_query_columns< ::bpkg::repository_fragment, id_sqlite, A >:
+ query_columns< ::bpkg::repository_fragment, id_sqlite, A >
+ {
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >:
+ public access::object_traits< ::bpkg::repository_fragment >
+ {
+ public:
+ struct id_image_type
+ {
+ details::buffer id_value;
+ std::size_t id_size;
+ bool id_null;
+
+ std::size_t version;
+ };
+
+ struct image_type
+ {
+ // name
+ //
+ details::buffer name_value;
+ std::size_t name_size;
+ bool name_null;
+
+ // location
+ //
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::image_type location_value;
+
+ std::size_t version;
+ };
+
+ struct extra_statement_cache_type;
+
+ // complements
+ //
+ struct complements_traits
+ {
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t data_column_count = 2UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::bpkg::repository_fragment::dependencies container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef set_functions<value_type> functions_type;
+ typedef sqlite::container_statements< complements_traits > statements_type;
+
+ struct data_image_type
+ {
+ // value
+ //
+ details::buffer value_value;
+ std::size_t value_size;
+ bool value_null;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ const value_type&);
+
+ static void
+ init (value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (const value_type&, void*);
+
+ static bool
+ select (value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // prerequisites
+ //
+ struct prerequisites_traits
+ {
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t data_column_count = 2UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::bpkg::repository_fragment::dependencies container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef set_functions<value_type> functions_type;
+ typedef sqlite::container_statements< prerequisites_traits > statements_type;
+
+ struct data_image_type
+ {
+ // value
+ //
+ details::buffer value_value;
+ std::size_t value_size;
+ bool value_null;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ const value_type&);
+
+ static void
+ init (value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (const value_type&, void*);
+
+ static bool
+ select (value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ using object_traits<object_type>::id;
+
+ static id_type
+ id (const image_type&);
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static void
+ bind (sqlite::bind*, id_image_type&);
+
+ static bool
+ init (image_type&,
+ const object_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (object_type&,
+ const image_type&,
+ database*);
+
+ static void
+ init (id_image_type&, const id_type&);
+
+ typedef sqlite::object_statements<object_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+
+ static const std::size_t column_count = 3UL;
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t inverse_column_count = 0UL;
+ static const std::size_t readonly_column_count = 0UL;
+ static const std::size_t managed_optimistic_column_count = 0UL;
+
+ static const std::size_t separate_load_column_count = 0UL;
+ static const std::size_t separate_update_column_count = 0UL;
+
+ static const bool versioned = false;
+
+ static const char persist_statement[];
+ static const char find_statement[];
+ static const char update_statement[];
+ static const char erase_statement[];
+ static const char query_statement[];
+ static const char erase_query_statement[];
+
+ static const char table_name[];
+
+ static void
+ persist (database&, const object_type&);
+
+ static pointer_type
+ find (database&, const id_type&);
+
+ static bool
+ find (database&, const id_type&, object_type&);
+
+ static bool
+ reload (database&, object_type&);
+
+ static void
+ update (database&, const object_type&);
+
+ static void
+ erase (database&, const id_type&);
+
+ static void
+ erase (database&, const object_type&);
+
+ static result<object_type>
+ query (database&, const query_base_type&);
+
+ static unsigned long long
+ erase_query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+
+ public:
+ static bool
+ find_ (statements_type&,
+ const id_type*);
+
+ static void
+ load_ (statements_type&,
+ object_type&,
+ bool reload);
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::repository_fragment, id_common >:
+ public access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >
+ {
+ };
+
+ // repository_fragment_count
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >:
+ public access::view_traits< ::bpkg::repository_fragment_count >
+ {
+ public:
+ struct image_type
+ {
+ // result
+ //
+ long long result_value;
+ bool result_null;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns;
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 1UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::repository_fragment_count, id_common >:
+ public access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >
+ {
+ };
+
+ // fragment_type
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::repository::fragment_type, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::repository::fragment_type value_type;
+
+ struct image_type
+ {
+ // friendly_name
+ //
+ details::buffer friendly_name_value;
+ std::size_t friendly_name_size;
+ bool friendly_name_null;
+
+ // fragment
+ //
+ details::buffer fragment_value;
+ std::size_t fragment_size;
+ bool fragment_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 2UL;
+ };
+
+ // repository
+ //
+ template <typename A>
+ struct query_columns< ::bpkg::repository, id_sqlite, A >
+ {
+ // name
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ name_type_;
+
+ static const name_type_ name;
+
+ // location
+ //
+ struct location_class_
+ {
+ location_class_ ()
+ {
+ }
+
+ // url
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ url_type_;
+
+ static const url_type_ url;
+
+ // type
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ type_type_;
+
+ static const type_type_ type;
+ };
+
+ static const location_class_ location;
+
+ // certificate
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ certificate_type_;
+
+ static const certificate_type_ certificate;
+
+ // local
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ local_type_;
+
+ static const local_type_ local;
+ };
+
+ template <typename A>
+ const typename query_columns< ::bpkg::repository, id_sqlite, A >::name_type_
+ query_columns< ::bpkg::repository, id_sqlite, A >::
+ name (A::table_name, "\"name\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::repository, id_sqlite, A >::location_class_::url_type_
+ query_columns< ::bpkg::repository, id_sqlite, A >::location_class_::
+ url (A::table_name, "\"url\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::repository, id_sqlite, A >::location_class_::type_type_
+ query_columns< ::bpkg::repository, id_sqlite, A >::location_class_::
+ type (A::table_name, "\"type\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::repository, id_sqlite, A >::location_class_
+ query_columns< ::bpkg::repository, id_sqlite, A >::location;
+
+ template <typename A>
+ const typename query_columns< ::bpkg::repository, id_sqlite, A >::certificate_type_
+ query_columns< ::bpkg::repository, id_sqlite, A >::
+ certificate (A::table_name, "\"certificate\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::repository, id_sqlite, A >::local_type_
+ query_columns< ::bpkg::repository, id_sqlite, A >::
+ local (A::table_name, "\"local\"", 0);
+
+ template <typename A>
+ struct pointer_query_columns< ::bpkg::repository, id_sqlite, A >:
+ query_columns< ::bpkg::repository, id_sqlite, A >
+ {
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::repository, id_sqlite >:
+ public access::object_traits< ::bpkg::repository >
+ {
+ public:
+ struct id_image_type
+ {
+ details::buffer id_value;
+ std::size_t id_size;
+ bool id_null;
+
+ std::size_t version;
+ };
+
+ struct image_type
+ {
+ // name
+ //
+ details::buffer name_value;
+ std::size_t name_size;
+ bool name_null;
+
+ // location
+ //
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::image_type location_value;
+
+ // certificate
+ //
+ details::buffer certificate_value;
+ std::size_t certificate_size;
+ bool certificate_null;
+
+ // local
+ //
+ long long local_value;
+ bool local_null;
+
+ std::size_t version;
+ };
+
+ struct extra_statement_cache_type;
+
+ // fragments
+ //
+ struct fragments_traits
+ {
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t data_column_count = 4UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::bpkg::repository::fragments_type container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::index_type index_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef ordered_functions<index_type, value_type> functions_type;
+ typedef sqlite::container_statements< fragments_traits > statements_type;
+
+ struct data_image_type
+ {
+ // index
+ //
+ long long index_value;
+ bool index_null;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::image_type value_value;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ index_type*,
+ const value_type&);
+
+ static void
+ init (index_type&,
+ value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (index_type, const value_type&, void*);
+
+ static bool
+ select (index_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ using object_traits<object_type>::id;
+
+ static id_type
+ id (const image_type&);
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static void
+ bind (sqlite::bind*, id_image_type&);
+
+ static bool
+ init (image_type&,
+ const object_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (object_type&,
+ const image_type&,
+ database*);
+
+ static void
+ init (id_image_type&, const id_type&);
+
+ typedef sqlite::object_statements<object_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+
+ static const std::size_t column_count = 5UL;
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t inverse_column_count = 0UL;
+ static const std::size_t readonly_column_count = 0UL;
+ static const std::size_t managed_optimistic_column_count = 0UL;
+
+ static const std::size_t separate_load_column_count = 0UL;
+ static const std::size_t separate_update_column_count = 0UL;
+
+ static const bool versioned = false;
+
+ static const char persist_statement[];
+ static const char find_statement[];
+ static const char update_statement[];
+ static const char erase_statement[];
+ static const char query_statement[];
+ static const char erase_query_statement[];
+
+ static const char table_name[];
+
+ static void
+ persist (database&, const object_type&);
+
+ static pointer_type
+ find (database&, const id_type&);
+
+ static bool
+ find (database&, const id_type&, object_type&);
+
+ static bool
+ reload (database&, object_type&);
+
+ static void
+ update (database&, const object_type&);
+
+ static void
+ erase (database&, const id_type&);
+
+ static void
+ erase (database&, const object_type&);
+
+ static result<object_type>
+ query (database&, const query_base_type&);
+
+ static unsigned long long
+ erase_query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+
+ public:
+ static bool
+ find_ (statements_type&,
+ const id_type*);
+
+ static void
+ load_ (statements_type&,
+ object_type&,
+ bool reload);
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::repository, id_common >:
+ public access::object_traits_impl< ::bpkg::repository, id_sqlite >
+ {
+ };
+
+ // repository_count
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::repository_count, id_sqlite >:
+ public access::view_traits< ::bpkg::repository_count >
+ {
+ public:
+ struct image_type
+ {
+ // result
+ //
+ long long result_value;
+ bool result_null;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns;
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 1UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::repository_count, id_common >:
+ public access::view_traits_impl< ::bpkg::repository_count, id_sqlite >
+ {
+ };
+
+ // package_location
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::package_location, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::package_location value_type;
+
+ struct image_type
+ {
+ // repository_fragment
+ //
+ details::buffer repository_fragment_value;
+ std::size_t repository_fragment_size;
+ bool repository_fragment_null;
+
+ // location
+ //
+ details::buffer location_value;
+ std::size_t location_size;
+ bool location_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 2UL;
+ };
+
+ // dependency_alternatives_ex
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::dependency_alternatives_ex, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::dependency_alternatives_ex value_type;
+
+ struct image_type: composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::image_type
+ {
+ // type
+ //
+ details::buffer type_value;
+ std::size_t type_size;
+ bool type_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 3UL;
+ };
+
+ // available_package_id
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::available_package_id, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::available_package_id value_type;
+
+ struct image_type
+ {
+ // name
+ //
+ details::buffer name_value;
+ std::size_t name_size;
+ bool name_null;
+
+ // version
+ //
+ composite_value_traits< ::bpkg::canonical_version, id_sqlite >::image_type version_value;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 6UL;
+ };
+
+ // _dependency_alternative_key
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::available_package::_dependency_alternative_key, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::available_package::_dependency_alternative_key value_type;
+
+ struct image_type
+ {
+ // outer
+ //
+ long long outer_value;
+ bool outer_null;
+
+ // inner
+ //
+ long long inner_value;
+ bool inner_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 2UL;
+ };
+
+ // _dependency_key
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::available_package::_dependency_key, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::available_package::_dependency_key value_type;
+
+ struct image_type
+ {
+ // outer
+ //
+ long long outer_value;
+ bool outer_null;
+
+ // middle
+ //
+ long long middle_value;
+ bool middle_null;
+
+ // inner
+ //
+ long long inner_value;
+ bool inner_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 3UL;
+ };
+
+ // available_package
+ //
+ template <typename A>
+ struct query_columns< ::bpkg::available_package, id_sqlite, A >
+ {
+ // id
+ //
+ struct id_class_
+ {
+ id_class_ ()
+ {
+ }
+
+ // name
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ name_type_;
+
+ static const name_type_ name;
+
+ // version
+ //
+ struct version_class_1_
+ {
+ version_class_1_ ()
+ {
+ }
+
+ // epoch
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::uint16_t,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ epoch_type_;
+
+ static const epoch_type_ epoch;
+
+ // canonical_upstream
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ canonical_upstream_type_;
+
+ static const canonical_upstream_type_ canonical_upstream;
+
+ // canonical_release
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ canonical_release_type_;
+
+ static const canonical_release_type_ canonical_release;
+
+ // revision
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::uint16_t,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ revision_type_;
+
+ static const revision_type_ revision;
+
+ // iteration
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::uint32_t,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ iteration_type_;
+
+ static const iteration_type_ iteration;
+ };
+
+ static const version_class_1_ version;
+ };
+
+ static const id_class_ id;
+
+ // version
+ //
+ struct version_class_
+ {
+ version_class_ ()
+ {
+ }
+
+ // upstream
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ upstream_type_;
+
+ static const upstream_type_ upstream;
+
+ // release
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ release_type_;
+
+ static const release_type_ release;
+ };
+
+ static const version_class_ version;
+
+ // upstream_version
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ upstream_version_type_;
+
+ static const upstream_version_type_ upstream_version;
+
+ // type
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ type_type_;
+
+ static const type_type_ type;
+
+ // project
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::butl::project_name,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ project_type_;
+
+ static const project_type_ project;
+
+ // alt_naming
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ alt_naming_type_;
+
+ static const alt_naming_type_ alt_naming;
+
+ // bootstrap_build
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ bootstrap_build_type_;
+
+ static const bootstrap_build_type_ bootstrap_build;
+
+ // root_build
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ root_build_type_;
+
+ static const root_build_type_ root_build;
+
+ // sha256sum
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ sha256sum_type_;
+
+ static const sha256sum_type_ sha256sum;
+ };
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::name_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::
+ name (A::table_name, "\"name\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version_class_1_::epoch_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version_class_1_::
+ epoch (A::table_name, "\"version_epoch\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version_class_1_::canonical_upstream_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version_class_1_::
+ canonical_upstream (A::table_name, "\"version_canonical_upstream\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version_class_1_::canonical_release_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version_class_1_::
+ canonical_release (A::table_name, "\"version_canonical_release\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version_class_1_::revision_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version_class_1_::
+ revision (A::table_name, "\"version_revision\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version_class_1_::iteration_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version_class_1_::
+ iteration (A::table_name, "\"version_iteration\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version_class_1_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_::version;
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::id_class_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::id;
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::version_class_::upstream_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::version_class_::
+ upstream (A::table_name, "\"version_upstream\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::version_class_::release_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::version_class_::
+ release (A::table_name, "\"version_release\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::version_class_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::version;
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::upstream_version_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::
+ upstream_version (A::table_name, "\"upstream_version\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::type_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::
+ type (A::table_name, "\"type\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::project_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::
+ project (A::table_name, "\"project\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::alt_naming_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::
+ alt_naming (A::table_name, "\"alt_naming\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::bootstrap_build_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::
+ bootstrap_build (A::table_name, "\"bootstrap_build\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::root_build_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::
+ root_build (A::table_name, "\"root_build\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::available_package, id_sqlite, A >::sha256sum_type_
+ query_columns< ::bpkg::available_package, id_sqlite, A >::
+ sha256sum (A::table_name, "\"sha256sum\"", 0);
+
+ template <typename A>
+ struct pointer_query_columns< ::bpkg::available_package, id_sqlite, A >:
+ query_columns< ::bpkg::available_package, id_sqlite, A >
+ {
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::available_package, id_sqlite >:
+ public access::object_traits< ::bpkg::available_package >
+ {
+ public:
+ struct id_image_type
+ {
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::image_type id_value;
+
+ std::size_t version;
+ };
+
+ struct image_type
+ {
+ // id
+ //
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::image_type id_value;
+
+ // version
+ //
+ composite_value_traits< ::bpkg::available_package::upstream_version_type, id_sqlite >::image_type version_value;
+
+ // upstream_version
+ //
+ details::buffer upstream_version_value;
+ std::size_t upstream_version_size;
+ bool upstream_version_null;
+
+ // type
+ //
+ details::buffer type_value;
+ std::size_t type_size;
+ bool type_null;
+
+ // project
+ //
+ details::buffer project_value;
+ std::size_t project_size;
+ bool project_null;
+
+ // alt_naming
+ //
+ long long alt_naming_value;
+ bool alt_naming_null;
+
+ // bootstrap_build
+ //
+ details::buffer bootstrap_build_value;
+ std::size_t bootstrap_build_size;
+ bool bootstrap_build_null;
+
+ // root_build
+ //
+ details::buffer root_build_value;
+ std::size_t root_build_size;
+ bool root_build_null;
+
+ // sha256sum
+ //
+ details::buffer sha256sum_value;
+ std::size_t sha256sum_size;
+ bool sha256sum_null;
+
+ std::size_t version;
+ };
+
+ struct extra_statement_cache_type;
+
+ // languages
+ //
+ struct languages_traits
+ {
+ static const std::size_t id_column_count = 6UL;
+ static const std::size_t data_column_count = 9UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::butl::small_vector< ::bpkg::language, 1 > container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::index_type index_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef ordered_functions<index_type, value_type> functions_type;
+ typedef sqlite::container_statements< languages_traits > statements_type;
+
+ struct data_image_type
+ {
+ // index
+ //
+ long long index_value;
+ bool index_null;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::image_type value_value;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ index_type*,
+ const value_type&);
+
+ static void
+ init (index_type&,
+ value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (index_type, const value_type&, void*);
+
+ static bool
+ select (index_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // locations
+ //
+ struct locations_traits
+ {
+ static const std::size_t id_column_count = 6UL;
+ static const std::size_t data_column_count = 8UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::butl::small_vector< ::bpkg::package_location, 1 > container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::index_type index_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef ordered_functions<index_type, value_type> functions_type;
+ typedef sqlite::container_statements< locations_traits > statements_type;
+
+ struct data_image_type
+ {
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::image_type value_value;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ const value_type&);
+
+ static void
+ init (value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (index_type, const value_type&, void*);
+
+ static bool
+ select (index_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // dependencies
+ //
+ struct dependencies_traits
+ {
+ static const std::size_t id_column_count = 6UL;
+ static const std::size_t data_column_count = 10UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::bpkg::available_package::dependencies_type container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::index_type index_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef ordered_functions<index_type, value_type> functions_type;
+ typedef sqlite::container_statements< dependencies_traits > statements_type;
+
+ struct data_image_type
+ {
+ // index
+ //
+ long long index_value;
+ bool index_null;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::image_type value_value;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ index_type*,
+ const value_type&);
+
+ static void
+ init (index_type&,
+ value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (index_type, const value_type&, void*);
+
+ static bool
+ select (index_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // dependency_alternatives
+ //
+ struct dependency_alternatives_traits
+ {
+ static const std::size_t id_column_count = 6UL;
+ static const std::size_t data_column_count = 13UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::std::map< ::odb::nested_key< ::bpkg::dependency_alternatives_ex >, ::bpkg::dependency_alternative > container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::key_type key_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef map_functions<key_type, value_type> functions_type;
+ typedef sqlite::container_statements< dependency_alternatives_traits > statements_type;
+
+ struct data_image_type
+ {
+ // key
+ //
+ composite_value_traits< key_type, id_sqlite >::image_type key_value;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::image_type value_value;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ const key_type*,
+ const value_type&);
+
+ static void
+ init (key_type&,
+ value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (const key_type&, const value_type&, void*);
+
+ static bool
+ select (key_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // dependency_alternative_dependencies
+ //
+ struct dependency_alternative_dependencies_traits
+ {
+ static const std::size_t id_column_count = 6UL;
+ static const std::size_t data_column_count = 26UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::std::map< ::odb::nested2_key< ::bpkg::dependency_alternatives_ex >, ::bpkg::dependency > container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::key_type key_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef map_functions<key_type, value_type> functions_type;
+ typedef sqlite::container_statements< dependency_alternative_dependencies_traits > statements_type;
+
+ struct data_image_type
+ {
+ // key
+ //
+ composite_value_traits< key_type, id_sqlite >::image_type key_value;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::image_type value_value;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ const key_type*,
+ const value_type&);
+
+ static void
+ init (key_type&,
+ value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (const key_type&, const value_type&, void*);
+
+ static bool
+ select (key_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // tests
+ //
+ struct tests_traits
+ {
+ static const std::size_t id_column_count = 6UL;
+ static const std::size_t data_column_count = 28UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::butl::small_vector< ::bpkg::test_dependency, 1 > container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::index_type index_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef ordered_functions<index_type, value_type> functions_type;
+ typedef sqlite::container_statements< tests_traits > statements_type;
+
+ struct data_image_type
+ {
+ // index
+ //
+ long long index_value;
+ bool index_null;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::image_type value_value;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ index_type*,
+ const value_type&);
+
+ static void
+ init (index_type&,
+ value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (index_type, const value_type&, void*);
+
+ static bool
+ select (index_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // buildfiles
+ //
+ struct buildfiles_traits
+ {
+ static const std::size_t id_column_count = 6UL;
+ static const std::size_t data_column_count = 9UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::std::vector< ::bpkg::buildfile > container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::index_type index_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef ordered_functions<index_type, value_type> functions_type;
+ typedef sqlite::container_statements< buildfiles_traits > statements_type;
+
+ struct data_image_type
+ {
+ // index
+ //
+ long long index_value;
+ bool index_null;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::image_type value_value;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ index_type*,
+ const value_type&);
+
+ static void
+ init (index_type&,
+ value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (index_type, const value_type&, void*);
+
+ static bool
+ select (index_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // distribution_values
+ //
+ struct distribution_values_traits
+ {
+ static const std::size_t id_column_count = 6UL;
+ static const std::size_t data_column_count = 9UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::std::vector< ::bpkg::distribution_name_value > container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::index_type index_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef ordered_functions<index_type, value_type> functions_type;
+ typedef sqlite::container_statements< distribution_values_traits > statements_type;
+
+ struct data_image_type
+ {
+ // index
+ //
+ long long index_value;
+ bool index_null;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::image_type value_value;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ index_type*,
+ const value_type&);
+
+ static void
+ init (index_type&,
+ value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (index_type, const value_type&, void*);
+
+ static bool
+ select (index_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // languages_section
+ //
+ struct languages_section_traits
+ {
+ typedef object_traits_impl<object_type, id_sqlite>::image_type image_type;
+ typedef object_traits_impl<object_type, id_sqlite>::id_image_type id_image_type;
+
+ static const std::size_t id_column_count = 6UL;
+ static const std::size_t managed_optimistic_load_column_count = 0UL;
+ static const std::size_t load_column_count = 0UL;
+ static const std::size_t managed_optimistic_update_column_count = 0UL;
+ static const std::size_t update_column_count = 0UL;
+
+ static const bool versioned = false;
+
+ static void
+ load (extra_statement_cache_type&, object_type&);
+
+ static void
+ update (extra_statement_cache_type&, const object_type&);
+ };
+
+ using object_traits<object_type>::id;
+
+ static id_type
+ id (const image_type&);
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static void
+ bind (sqlite::bind*, id_image_type&);
+
+ static bool
+ init (image_type&,
+ const object_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (object_type&,
+ const image_type&,
+ database*);
+
+ static void
+ init (id_image_type&, const id_type&);
+
+ typedef sqlite::object_statements<object_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+
+ static const std::size_t column_count = 15UL;
+ static const std::size_t id_column_count = 6UL;
+ static const std::size_t inverse_column_count = 0UL;
+ static const std::size_t readonly_column_count = 0UL;
+ static const std::size_t managed_optimistic_column_count = 0UL;
+
+ static const std::size_t separate_load_column_count = 0UL;
+ static const std::size_t separate_update_column_count = 0UL;
+
+ static const bool versioned = false;
+
+ static const char persist_statement[];
+ static const char find_statement[];
+ static const char update_statement[];
+ static const char erase_statement[];
+ static const char query_statement[];
+ static const char erase_query_statement[];
+
+ static const char table_name[];
+
+ static void
+ persist (database&, const object_type&);
+
+ static pointer_type
+ find (database&, const id_type&);
+
+ static bool
+ find (database&, const id_type&, object_type&);
+
+ static bool
+ reload (database&, object_type&);
+
+ static void
+ update (database&, const object_type&);
+
+ static void
+ erase (database&, const id_type&);
+
+ static void
+ erase (database&, const object_type&);
+
+ static bool
+ load (connection&, object_type&, section&);
+
+ static bool
+ update (connection&, const object_type&, const section&);
+
+ static result<object_type>
+ query (database&, const query_base_type&);
+
+ static unsigned long long
+ erase_query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+
+ public:
+ static bool
+ find_ (statements_type&,
+ const id_type*);
+
+ static void
+ load_ (statements_type&,
+ object_type&,
+ bool reload);
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::available_package, id_common >:
+ public access::object_traits_impl< ::bpkg::available_package, id_sqlite >
+ {
+ };
+
+ // available_package_count
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >:
+ public access::view_traits< ::bpkg::available_package_count >
+ {
+ public:
+ struct image_type
+ {
+ // result
+ //
+ long long result_value;
+ bool result_null;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns;
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 1UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::available_package_count, id_common >:
+ public access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >
+ {
+ };
+
+ // available_test
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::available_test, id_sqlite >:
+ public access::view_traits< ::bpkg::available_test >
+ {
+ public:
+ struct image_type
+ {
+ // package
+ //
+ object_traits_impl< ::bpkg::available_package, id_sqlite >::image_type package_value;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ struct package_tag;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns;
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 15UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::available_test, id_common >:
+ public access::view_traits_impl< ::bpkg::available_test, id_sqlite >
+ {
+ };
+
+ // available_main
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::available_main, id_sqlite >:
+ public access::view_traits< ::bpkg::available_main >
+ {
+ public:
+ struct image_type
+ {
+ // package
+ //
+ object_traits_impl< ::bpkg::available_package, id_sqlite >::image_type package_value;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ struct package_tag;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns;
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 15UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::available_main, id_common >:
+ public access::view_traits_impl< ::bpkg::available_main, id_sqlite >
+ {
+ };
+
+ // prerequisite_info
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::prerequisite_info, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::prerequisite_info value_type;
+
+ struct image_type
+ {
+ // constraint
+ //
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::image_type constraint_value;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 16UL;
+ };
+
+ // _selected_package_ref
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::_selected_package_ref value_type;
+
+ struct image_type
+ {
+ // configuration
+ //
+ details::buffer configuration_value;
+ std::size_t configuration_size;
+ bool configuration_null;
+
+ // prerequisite
+ //
+ details::buffer prerequisite_value;
+ std::size_t prerequisite_size;
+ bool prerequisite_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 2UL;
+ };
+
+ // config_variable
+ //
+ template <>
+ class access::composite_value_traits< ::bpkg::config_variable, id_sqlite >
+ {
+ public:
+ typedef ::bpkg::config_variable value_type;
+
+ struct image_type
+ {
+ // name
+ //
+ details::buffer name_value;
+ std::size_t name_size;
+ bool name_null;
+
+ // source
+ //
+ details::buffer source_value;
+ std::size_t source_size;
+ bool source_null;
+ };
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static bool
+ init (image_type&,
+ const value_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (value_type&,
+ const image_type&,
+ database*);
+
+ static bool
+ get_null (const image_type&);
+
+ static void
+ set_null (image_type&,
+ sqlite::statement_kind);
+
+ static const std::size_t column_count = 2UL;
+ };
+
+ // selected_package
+ //
+ template <typename A>
+ struct query_columns< ::bpkg::selected_package, id_sqlite, A >
+ {
+ // name
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ name_type_;
+
+ static const name_type_ name;
+
+ // version
+ //
+ struct version_class_
+ {
+ version_class_ ()
+ {
+ }
+
+ // epoch
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::uint16_t,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ epoch_type_;
+
+ static const epoch_type_ epoch;
+
+ // canonical_upstream
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ canonical_upstream_type_;
+
+ static const canonical_upstream_type_ canonical_upstream;
+
+ // canonical_release
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ canonical_release_type_;
+
+ static const canonical_release_type_ canonical_release;
+
+ // revision
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ short unsigned int,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ revision_type_;
+
+ static const revision_type_ revision;
+
+ // iteration
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::uint32_t,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ iteration_type_;
+
+ static const iteration_type_ iteration;
+
+ // upstream
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ upstream_type_;
+
+ static const upstream_type_ upstream;
+
+ // release
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ release_type_;
+
+ static const release_type_ release;
+ };
+
+ static const version_class_ version;
+
+ // state
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ state_type_;
+
+ static const state_type_ state;
+
+ // substate
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ substate_type_;
+
+ static const substate_type_ substate;
+
+ // hold_package
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ hold_package_type_;
+
+ static const hold_package_type_ hold_package;
+
+ // hold_version
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ hold_version_type_;
+
+ static const hold_version_type_ hold_version;
+
+ // repository_fragment
+ //
+ struct repository_fragment_class_
+ {
+ repository_fragment_class_ ()
+ {
+ }
+
+ // url
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ url_type_;
+
+ static const url_type_ url;
+
+ // type
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ type_type_;
+
+ static const type_type_ type;
+ };
+
+ static const repository_fragment_class_ repository_fragment;
+
+ // archive
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ archive_type_;
+
+ static const archive_type_ archive;
+
+ // purge_archive
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ purge_archive_type_;
+
+ static const purge_archive_type_ purge_archive;
+
+ // src_root
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ src_root_type_;
+
+ static const src_root_type_ src_root;
+
+ // purge_src
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ purge_src_type_;
+
+ static const purge_src_type_ purge_src;
+
+ // manifest_checksum
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ manifest_checksum_type_;
+
+ static const manifest_checksum_type_ manifest_checksum;
+
+ // buildfiles_checksum
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ buildfiles_checksum_type_;
+
+ static const buildfiles_checksum_type_ buildfiles_checksum;
+
+ // out_root
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::basic_string< char >,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ out_root_type_;
+
+ static const out_root_type_ out_root;
+
+ // config_checksum
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ config_checksum_type_;
+
+ static const config_checksum_type_ config_checksum;
+ };
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::name_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ name (A::table_name, "\"name\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::epoch_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::
+ epoch (A::table_name, "\"version_epoch\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::canonical_upstream_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::
+ canonical_upstream (A::table_name, "\"version_canonical_upstream\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::canonical_release_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::
+ canonical_release (A::table_name, "\"version_canonical_release\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::revision_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::
+ revision (A::table_name, "\"version_revision\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::iteration_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::
+ iteration (A::table_name, "\"version_iteration\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::upstream_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::
+ upstream (A::table_name, "\"version_upstream\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::release_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_::
+ release (A::table_name, "\"version_release\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::version_class_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::version;
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::state_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ state (A::table_name, "\"state\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::substate_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ substate (A::table_name, "\"substate\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::hold_package_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ hold_package (A::table_name, "\"hold_package\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::hold_version_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ hold_version (A::table_name, "\"hold_version\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::repository_fragment_class_::url_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::repository_fragment_class_::
+ url (A::table_name, "\"repository_fragment_url\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::repository_fragment_class_::type_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::repository_fragment_class_::
+ type (A::table_name, "\"repository_fragment_type\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::repository_fragment_class_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::repository_fragment;
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::archive_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ archive (A::table_name, "\"archive\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::purge_archive_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ purge_archive (A::table_name, "\"purge_archive\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::src_root_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ src_root (A::table_name, "\"src_root\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::purge_src_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ purge_src (A::table_name, "\"purge_src\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::manifest_checksum_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ manifest_checksum (A::table_name, "\"manifest_checksum\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::buildfiles_checksum_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ buildfiles_checksum (A::table_name, "\"buildfiles_checksum\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::out_root_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ out_root (A::table_name, "\"out_root\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::selected_package, id_sqlite, A >::config_checksum_type_
+ query_columns< ::bpkg::selected_package, id_sqlite, A >::
+ config_checksum (A::table_name, "\"config_checksum\"", 0);
+
+ template <typename A>
+ struct pointer_query_columns< ::bpkg::selected_package, id_sqlite, A >:
+ query_columns< ::bpkg::selected_package, id_sqlite, A >
+ {
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::selected_package, id_sqlite >:
+ public access::object_traits< ::bpkg::selected_package >
+ {
+ public:
+ struct id_image_type
+ {
+ details::buffer id_value;
+ std::size_t id_size;
+ bool id_null;
+
+ std::size_t version;
+ };
+
+ struct image_type
+ {
+ // name
+ //
+ details::buffer name_value;
+ std::size_t name_size;
+ bool name_null;
+
+ // version
+ //
+ composite_value_traits< ::bpkg::_version, id_sqlite >::image_type version_value;
+
+ // state
+ //
+ details::buffer state_value;
+ std::size_t state_size;
+ bool state_null;
+
+ // substate
+ //
+ details::buffer substate_value;
+ std::size_t substate_size;
+ bool substate_null;
+
+ // hold_package
+ //
+ long long hold_package_value;
+ bool hold_package_null;
+
+ // hold_version
+ //
+ long long hold_version_value;
+ bool hold_version_null;
+
+ // repository_fragment
+ //
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::image_type repository_fragment_value;
+
+ // archive
+ //
+ details::buffer archive_value;
+ std::size_t archive_size;
+ bool archive_null;
+
+ // purge_archive
+ //
+ long long purge_archive_value;
+ bool purge_archive_null;
+
+ // src_root
+ //
+ details::buffer src_root_value;
+ std::size_t src_root_size;
+ bool src_root_null;
+
+ // purge_src
+ //
+ long long purge_src_value;
+ bool purge_src_null;
+
+ // manifest_checksum
+ //
+ details::buffer manifest_checksum_value;
+ std::size_t manifest_checksum_size;
+ bool manifest_checksum_null;
+
+ // buildfiles_checksum
+ //
+ details::buffer buildfiles_checksum_value;
+ std::size_t buildfiles_checksum_size;
+ bool buildfiles_checksum_null;
+
+ // out_root
+ //
+ details::buffer out_root_value;
+ std::size_t out_root_size;
+ bool out_root_null;
+
+ // config_checksum
+ //
+ details::buffer config_checksum_value;
+ std::size_t config_checksum_size;
+ bool config_checksum_null;
+
+ std::size_t version;
+ };
+
+ struct extra_statement_cache_type;
+
+ // prerequisites
+ //
+ struct prerequisites_traits
+ {
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t data_column_count = 19UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::bpkg::package_prerequisites container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::key_type key_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef map_functions<key_type, value_type> functions_type;
+ typedef sqlite::container_statements< prerequisites_traits > statements_type;
+
+ struct data_image_type
+ {
+ // key
+ //
+ composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >::image_type key_value;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::image_type value_value;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ const key_type*,
+ const value_type&);
+
+ static void
+ init (key_type&,
+ value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (const key_type&, const value_type&, void*);
+
+ static bool
+ select (key_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // dependency_alternatives
+ //
+ struct dependency_alternatives_traits
+ {
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t data_column_count = 3UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::bpkg::selected_package::indexes_type container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::index_type index_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef ordered_functions<index_type, value_type> functions_type;
+ typedef sqlite::container_statements< dependency_alternatives_traits > statements_type;
+
+ struct data_image_type
+ {
+ // index
+ //
+ long long index_value;
+ bool index_null;
+
+ // value
+ //
+ long long value_value;
+ bool value_null;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ index_type*,
+ const value_type&);
+
+ static void
+ init (index_type&,
+ value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (index_type, const value_type&, void*);
+
+ static bool
+ select (index_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // config_variables
+ //
+ struct config_variables_traits
+ {
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t data_column_count = 4UL;
+
+ static const bool versioned = false;
+
+ static const char insert_statement[];
+ static const char select_statement[];
+ static const char delete_statement[];
+
+ typedef ::std::vector< ::bpkg::config_variable > container_type;
+ typedef
+ odb::access::container_traits<container_type>
+ container_traits_type;
+ typedef container_traits_type::index_type index_type;
+ typedef container_traits_type::value_type value_type;
+
+ typedef ordered_functions<index_type, value_type> functions_type;
+ typedef sqlite::container_statements< config_variables_traits > statements_type;
+
+ struct data_image_type
+ {
+ // index
+ //
+ long long index_value;
+ bool index_null;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::image_type value_value;
+
+ std::size_t version;
+ };
+
+ static void
+ bind (sqlite::bind*,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type&);
+
+ static void
+ grow (data_image_type&,
+ bool*);
+
+ static void
+ init (data_image_type&,
+ index_type*,
+ const value_type&);
+
+ static void
+ init (index_type&,
+ value_type&,
+ const data_image_type&,
+ database*);
+
+ static void
+ insert (index_type, const value_type&, void*);
+
+ static bool
+ select (index_type&, value_type&, void*);
+
+ static void
+ delete_ (void*);
+
+ static void
+ persist (const container_type&,
+ statements_type&);
+
+ static void
+ load (container_type&,
+ statements_type&);
+
+ static void
+ update (const container_type&,
+ statements_type&);
+
+ static void
+ erase (statements_type&);
+ };
+
+ // dependency_alternatives_section
+ //
+ struct dependency_alternatives_section_traits
+ {
+ typedef object_traits_impl<object_type, id_sqlite>::image_type image_type;
+ typedef object_traits_impl<object_type, id_sqlite>::id_image_type id_image_type;
+
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t managed_optimistic_load_column_count = 0UL;
+ static const std::size_t load_column_count = 0UL;
+ static const std::size_t managed_optimistic_update_column_count = 0UL;
+ static const std::size_t update_column_count = 0UL;
+
+ static const bool versioned = false;
+
+ static void
+ load (extra_statement_cache_type&, object_type&);
+
+ static void
+ update (extra_statement_cache_type&, const object_type&);
+ };
+
+ using object_traits<object_type>::id;
+
+ static id_type
+ id (const image_type&);
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static void
+ bind (sqlite::bind*, id_image_type&);
+
+ static bool
+ init (image_type&,
+ const object_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (object_type&,
+ const image_type&,
+ database*);
+
+ static void
+ init (id_image_type&, const id_type&);
+
+ typedef sqlite::object_statements<object_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+
+ static const std::size_t column_count = 22UL;
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t inverse_column_count = 0UL;
+ static const std::size_t readonly_column_count = 0UL;
+ static const std::size_t managed_optimistic_column_count = 0UL;
+
+ static const std::size_t separate_load_column_count = 0UL;
+ static const std::size_t separate_update_column_count = 0UL;
+
+ static const bool versioned = false;
+
+ static const char persist_statement[];
+ static const char find_statement[];
+ static const char update_statement[];
+ static const char erase_statement[];
+ static const char query_statement[];
+ static const char erase_query_statement[];
+
+ static const char table_name[];
+
+ static void
+ persist (database&, const object_type&);
+
+ static pointer_type
+ find (database&, const id_type&);
+
+ static bool
+ find (database&, const id_type&, object_type&);
+
+ static bool
+ reload (database&, object_type&);
+
+ static void
+ update (database&, const object_type&);
+
+ static void
+ erase (database&, const id_type&);
+
+ static void
+ erase (database&, const object_type&);
+
+ static bool
+ load (connection&, object_type&, section&);
+
+ static bool
+ update (connection&, const object_type&, const section&);
+
+ static result<object_type>
+ query (database&, const query_base_type&);
+
+ static unsigned long long
+ erase_query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+
+ public:
+ static bool
+ find_ (statements_type&,
+ const id_type*);
+
+ static void
+ load_ (statements_type&,
+ object_type&,
+ bool reload);
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::selected_package, id_common >:
+ public access::object_traits_impl< ::bpkg::selected_package, id_sqlite >
+ {
+ };
+
+ // certificate
+ //
+ template <typename A>
+ struct query_columns< ::bpkg::certificate, id_sqlite, A >
+ {
+ // id
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ id_type_;
+
+ static const id_type_ id;
+
+ // fingerprint
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ fingerprint_type_;
+
+ static const fingerprint_type_ fingerprint;
+
+ // name
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ name_type_;
+
+ static const name_type_ name;
+
+ // organization
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ organization_type_;
+
+ static const organization_type_ organization;
+
+ // email
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::query_type,
+ sqlite::id_text >
+ email_type_;
+
+ static const email_type_ email;
+
+ // start_date
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::uint64_t,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ start_date_type_;
+
+ static const start_date_type_ start_date;
+
+ // end_date
+ //
+ typedef
+ sqlite::query_column<
+ sqlite::value_traits<
+ ::uint64_t,
+ sqlite::id_integer >::query_type,
+ sqlite::id_integer >
+ end_date_type_;
+
+ static const end_date_type_ end_date;
+ };
+
+ template <typename A>
+ const typename query_columns< ::bpkg::certificate, id_sqlite, A >::id_type_
+ query_columns< ::bpkg::certificate, id_sqlite, A >::
+ id (A::table_name, "\"id\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::certificate, id_sqlite, A >::fingerprint_type_
+ query_columns< ::bpkg::certificate, id_sqlite, A >::
+ fingerprint (A::table_name, "\"fingerprint\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::certificate, id_sqlite, A >::name_type_
+ query_columns< ::bpkg::certificate, id_sqlite, A >::
+ name (A::table_name, "\"name\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::certificate, id_sqlite, A >::organization_type_
+ query_columns< ::bpkg::certificate, id_sqlite, A >::
+ organization (A::table_name, "\"organization\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::certificate, id_sqlite, A >::email_type_
+ query_columns< ::bpkg::certificate, id_sqlite, A >::
+ email (A::table_name, "\"email\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::certificate, id_sqlite, A >::start_date_type_
+ query_columns< ::bpkg::certificate, id_sqlite, A >::
+ start_date (A::table_name, "\"start_date\"", 0);
+
+ template <typename A>
+ const typename query_columns< ::bpkg::certificate, id_sqlite, A >::end_date_type_
+ query_columns< ::bpkg::certificate, id_sqlite, A >::
+ end_date (A::table_name, "\"end_date\"", 0);
+
+ template <typename A>
+ struct pointer_query_columns< ::bpkg::certificate, id_sqlite, A >:
+ query_columns< ::bpkg::certificate, id_sqlite, A >
+ {
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::certificate, id_sqlite >:
+ public access::object_traits< ::bpkg::certificate >
+ {
+ public:
+ struct id_image_type
+ {
+ details::buffer id_value;
+ std::size_t id_size;
+ bool id_null;
+
+ std::size_t version;
+ };
+
+ struct image_type
+ {
+ // id
+ //
+ details::buffer id_value;
+ std::size_t id_size;
+ bool id_null;
+
+ // fingerprint
+ //
+ details::buffer fingerprint_value;
+ std::size_t fingerprint_size;
+ bool fingerprint_null;
+
+ // name
+ //
+ details::buffer name_value;
+ std::size_t name_size;
+ bool name_null;
+
+ // organization
+ //
+ details::buffer organization_value;
+ std::size_t organization_size;
+ bool organization_null;
+
+ // email
+ //
+ details::buffer email_value;
+ std::size_t email_size;
+ bool email_null;
+
+ // start_date
+ //
+ long long start_date_value;
+ bool start_date_null;
+
+ // end_date
+ //
+ long long end_date_value;
+ bool end_date_null;
+
+ std::size_t version;
+ };
+
+ struct extra_statement_cache_type;
+
+ using object_traits<object_type>::id;
+
+ static id_type
+ id (const image_type&);
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&,
+ sqlite::statement_kind);
+
+ static void
+ bind (sqlite::bind*, id_image_type&);
+
+ static bool
+ init (image_type&,
+ const object_type&,
+ sqlite::statement_kind);
+
+ static void
+ init (object_type&,
+ const image_type&,
+ database*);
+
+ static void
+ init (id_image_type&, const id_type&);
+
+ typedef sqlite::object_statements<object_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+
+ static const std::size_t column_count = 7UL;
+ static const std::size_t id_column_count = 1UL;
+ static const std::size_t inverse_column_count = 0UL;
+ static const std::size_t readonly_column_count = 0UL;
+ static const std::size_t managed_optimistic_column_count = 0UL;
+
+ static const std::size_t separate_load_column_count = 0UL;
+ static const std::size_t separate_update_column_count = 0UL;
+
+ static const bool versioned = false;
+
+ static const char persist_statement[];
+ static const char find_statement[];
+ static const char update_statement[];
+ static const char erase_statement[];
+ static const char query_statement[];
+ static const char erase_query_statement[];
+
+ static const char table_name[];
+
+ static void
+ persist (database&, const object_type&);
+
+ static pointer_type
+ find (database&, const id_type&);
+
+ static bool
+ find (database&, const id_type&, object_type&);
+
+ static bool
+ reload (database&, object_type&);
+
+ static void
+ update (database&, const object_type&);
+
+ static void
+ erase (database&, const id_type&);
+
+ static void
+ erase (database&, const object_type&);
+
+ static result<object_type>
+ query (database&, const query_base_type&);
+
+ static unsigned long long
+ erase_query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+
+ public:
+ static bool
+ find_ (statements_type&,
+ const id_type*);
+
+ static void
+ load_ (statements_type&,
+ object_type&,
+ bool reload);
+ };
+
+ template <>
+ class access::object_traits_impl< ::bpkg::certificate, id_common >:
+ public access::object_traits_impl< ::bpkg::certificate, id_sqlite >
+ {
+ };
+
+ // package_dependent
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >:
+ public access::view_traits< ::bpkg::package_dependent >
+ {
+ public:
+ struct image_type
+ {
+ // name
+ //
+ details::buffer name_value;
+ std::size_t name_size;
+ bool name_null;
+
+ // constraint
+ //
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::image_type constraint_value;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns
+ {
+ };
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 17UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::package_dependent, id_common >:
+ public access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >
+ {
+ };
+
+ // fragment_repository_count
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >:
+ public access::view_traits< ::bpkg::fragment_repository_count >
+ {
+ public:
+ struct image_type
+ {
+ // result
+ //
+ long long result_value;
+ bool result_null;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns
+ {
+ };
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 1UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::fragment_repository_count, id_common >:
+ public access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >
+ {
+ };
+
+ // fragment_repository
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >:
+ public access::view_traits< ::bpkg::fragment_repository >
+ {
+ public:
+ struct image_type
+ {
+ // object
+ //
+ object_traits_impl< ::bpkg::repository, id_sqlite >::image_type object_value;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns;
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 5UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::fragment_repository, id_common >:
+ public access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >
+ {
+ };
+
+ // repository_complement_dependent
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >:
+ public access::view_traits< ::bpkg::repository_complement_dependent >
+ {
+ public:
+ struct image_type
+ {
+ // object
+ //
+ object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::image_type object_value;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ struct complement_tag;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns;
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 3UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::repository_complement_dependent, id_common >:
+ public access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >
+ {
+ };
+
+ // repository_prerequisite_dependent
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >:
+ public access::view_traits< ::bpkg::repository_prerequisite_dependent >
+ {
+ public:
+ struct image_type
+ {
+ // object
+ //
+ object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::image_type object_value;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ struct prerequisite_tag;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns;
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 3UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_common >:
+ public access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >
+ {
+ };
+
+ // repository_fragment_package
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >:
+ public access::view_traits< ::bpkg::repository_fragment_package >
+ {
+ public:
+ struct image_type
+ {
+ // package
+ //
+ object_traits_impl< ::bpkg::available_package, id_sqlite >::image_type package_value;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ struct package_tag;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns;
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 15UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::repository_fragment_package, id_common >:
+ public access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >
+ {
+ };
+
+ // package_repository_fragment
+ //
+ template <>
+ class access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >:
+ public access::view_traits< ::bpkg::package_repository_fragment >
+ {
+ public:
+ struct image_type
+ {
+ // package_id
+ //
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::image_type package_id_value;
+
+ // repository_fragment
+ //
+ object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::image_type repository_fragment_value;
+
+ std::size_t version;
+ };
+
+ typedef sqlite::view_statements<view_type> statements_type;
+
+ struct package_tag;
+
+ typedef sqlite::query_base query_base_type;
+ struct query_columns;
+
+ static const bool versioned = false;
+
+ static bool
+ grow (image_type&,
+ bool*);
+
+ static void
+ bind (sqlite::bind*,
+ image_type&);
+
+ static void
+ init (view_type&,
+ const image_type&,
+ database*);
+
+ static const std::size_t column_count = 9UL;
+
+ static query_base_type
+ query_statement (const query_base_type&);
+
+ static result<view_type>
+ query (database&, const query_base_type&);
+
+ static odb::details::shared_ptr<prepared_query_impl>
+ prepare_query (connection&, const char*, const query_base_type&);
+
+ static odb::details::shared_ptr<result_impl>
+ execute_query (prepared_query_impl&);
+ };
+
+ template <>
+ class access::view_traits_impl< ::bpkg::package_repository_fragment, id_common >:
+ public access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >
+ {
+ };
+
+ // configuration
+ //
+ // repository_fragment
+ //
+ // repository_fragment_count
+ //
+ struct access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::query_columns:
+ odb::pointer_query_columns<
+ ::bpkg::repository_fragment,
+ id_sqlite,
+ odb::access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite > >
+ {
+ };
+
+ // repository
+ //
+ // repository_count
+ //
+ struct access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::query_columns:
+ odb::pointer_query_columns<
+ ::bpkg::repository,
+ id_sqlite,
+ odb::access::object_traits_impl< ::bpkg::repository, id_sqlite > >
+ {
+ };
+
+ // available_package
+ //
+ // available_package_count
+ //
+ struct access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::query_columns:
+ odb::pointer_query_columns<
+ ::bpkg::available_package,
+ id_sqlite,
+ odb::access::object_traits_impl< ::bpkg::available_package, id_sqlite > >
+ {
+ };
+
+ // available_test
+ //
+ template <>
+ struct alias_traits<
+ ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::package_tag>
+ {
+ static const char table_name[];
+ };
+
+ struct access::view_traits_impl< ::bpkg::available_test, id_sqlite >::query_columns:
+ odb::pointer_query_columns<
+ ::bpkg::available_package,
+ id_sqlite,
+ odb::alias_traits<
+ ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::package_tag> >
+ {
+ };
+
+ // available_main
+ //
+ template <>
+ struct alias_traits<
+ ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::package_tag>
+ {
+ static const char table_name[];
+ };
+
+ struct access::view_traits_impl< ::bpkg::available_main, id_sqlite >::query_columns:
+ odb::pointer_query_columns<
+ ::bpkg::available_package,
+ id_sqlite,
+ odb::alias_traits<
+ ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::package_tag> >
+ {
+ };
+
+ // selected_package
+ //
+ // certificate
+ //
+ // fragment_repository
+ //
+ struct access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::query_columns
+ {
+ // repository
+ //
+ typedef
+ odb::pointer_query_columns<
+ ::bpkg::repository,
+ id_sqlite,
+ odb::access::object_traits_impl< ::bpkg::repository, id_sqlite > >
+ repository;
+
+ // repository_fragment
+ //
+ typedef
+ odb::pointer_query_columns<
+ ::bpkg::repository_fragment,
+ id_sqlite,
+ odb::access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite > >
+ repository_fragment;
+ };
+
+ // repository_complement_dependent
+ //
+ template <>
+ struct alias_traits<
+ ::bpkg::repository,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::complement_tag>
+ {
+ static const char table_name[];
+ };
+
+ struct access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::query_columns
+ {
+ // complement
+ //
+ typedef
+ odb::pointer_query_columns<
+ ::bpkg::repository,
+ id_sqlite,
+ odb::alias_traits< ::bpkg::repository,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::complement_tag> >
+ complement;
+
+ // repository_fragment
+ //
+ typedef
+ odb::pointer_query_columns<
+ ::bpkg::repository_fragment,
+ id_sqlite,
+ odb::access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite > >
+ repository_fragment;
+ };
+
+ // repository_prerequisite_dependent
+ //
+ template <>
+ struct alias_traits<
+ ::bpkg::repository,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::prerequisite_tag>
+ {
+ static const char table_name[];
+ };
+
+ struct access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::query_columns
+ {
+ // prerequisite
+ //
+ typedef
+ odb::pointer_query_columns<
+ ::bpkg::repository,
+ id_sqlite,
+ odb::alias_traits< ::bpkg::repository,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::prerequisite_tag> >
+ prerequisite;
+
+ // repository_fragment
+ //
+ typedef
+ odb::pointer_query_columns<
+ ::bpkg::repository_fragment,
+ id_sqlite,
+ odb::access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite > >
+ repository_fragment;
+ };
+
+ // repository_fragment_package
+ //
+ template <>
+ struct alias_traits<
+ ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::package_tag>
+ {
+ static const char table_name[];
+ };
+
+ struct access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::query_columns
+ {
+ // repository_fragment
+ //
+ typedef
+ odb::pointer_query_columns<
+ ::bpkg::repository_fragment,
+ id_sqlite,
+ odb::access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite > >
+ repository_fragment;
+
+ // package
+ //
+ typedef
+ odb::pointer_query_columns<
+ ::bpkg::available_package,
+ id_sqlite,
+ odb::alias_traits< ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::package_tag> >
+ package;
+ };
+
+ // package_repository_fragment
+ //
+ template <>
+ struct alias_traits<
+ ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::package_tag>
+ {
+ static const char table_name[];
+ };
+
+ struct access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::query_columns
+ {
+ // repository_fragment
+ //
+ typedef
+ odb::pointer_query_columns<
+ ::bpkg::repository_fragment,
+ id_sqlite,
+ odb::access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite > >
+ repository_fragment;
+
+ // package
+ //
+ typedef
+ odb::pointer_query_columns<
+ ::bpkg::available_package,
+ id_sqlite,
+ odb::alias_traits< ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::package_tag> >
+ package;
+ };
+}
+
+#include <bpkg/package-odb.ixx>
+
+#include <odb/post.hxx>
+
+#endif // BPKG_PACKAGE_ODB_HXX
diff --git a/bpkg/package-odb.ixx b/bpkg/package-odb.ixx
new file mode 100644
index 0000000..a831734
--- /dev/null
+++ b/bpkg/package-odb.ixx
@@ -0,0 +1,1038 @@
+// -*- C++ -*-
+//
+// This file was generated by ODB, object-relational mapping (ORM)
+// compiler for C++.
+//
+
+namespace odb
+{
+ // configuration
+ //
+
+ inline
+ access::object_traits< ::bpkg::configuration >::id_type
+ access::object_traits< ::bpkg::configuration >::
+ id (const object_type& o)
+ {
+ return o.id;
+ }
+
+ inline
+ void access::object_traits< ::bpkg::configuration >::
+ callback (database& db, object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ inline
+ void access::object_traits< ::bpkg::configuration >::
+ callback (database& db, const object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // repository_fragment
+ //
+
+ inline
+ access::object_traits< ::bpkg::repository_fragment >::id_type
+ access::object_traits< ::bpkg::repository_fragment >::
+ id (const object_type& o)
+ {
+ return o.name;
+ }
+
+ inline
+ void access::object_traits< ::bpkg::repository_fragment >::
+ callback (database& db, object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ inline
+ void access::object_traits< ::bpkg::repository_fragment >::
+ callback (database& db, const object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // repository_fragment_count
+ //
+
+ inline
+ void access::view_traits< ::bpkg::repository_fragment_count >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // repository
+ //
+
+ inline
+ access::object_traits< ::bpkg::repository >::id_type
+ access::object_traits< ::bpkg::repository >::
+ id (const object_type& o)
+ {
+ return o.name;
+ }
+
+ inline
+ void access::object_traits< ::bpkg::repository >::
+ callback (database& db, object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ inline
+ void access::object_traits< ::bpkg::repository >::
+ callback (database& db, const object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // repository_count
+ //
+
+ inline
+ void access::view_traits< ::bpkg::repository_count >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // available_package
+ //
+
+ inline
+ access::object_traits< ::bpkg::available_package >::id_type
+ access::object_traits< ::bpkg::available_package >::
+ id (const object_type& o)
+ {
+ return o.id;
+ }
+
+ inline
+ void access::object_traits< ::bpkg::available_package >::
+ callback (database& db, object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ inline
+ void access::object_traits< ::bpkg::available_package >::
+ callback (database& db, const object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // available_package_count
+ //
+
+ inline
+ void access::view_traits< ::bpkg::available_package_count >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // available_test
+ //
+
+ inline
+ void access::view_traits< ::bpkg::available_test >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // available_main
+ //
+
+ inline
+ void access::view_traits< ::bpkg::available_main >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // selected_package
+ //
+
+ inline
+ access::object_traits< ::bpkg::selected_package >::id_type
+ access::object_traits< ::bpkg::selected_package >::
+ id (const object_type& o)
+ {
+ return o.name;
+ }
+
+ inline
+ void access::object_traits< ::bpkg::selected_package >::
+ callback (database& db, object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ inline
+ void access::object_traits< ::bpkg::selected_package >::
+ callback (database& db, const object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // certificate
+ //
+
+ inline
+ access::object_traits< ::bpkg::certificate >::id_type
+ access::object_traits< ::bpkg::certificate >::
+ id (const object_type& o)
+ {
+ return o.id;
+ }
+
+ inline
+ void access::object_traits< ::bpkg::certificate >::
+ callback (database& db, object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ inline
+ void access::object_traits< ::bpkg::certificate >::
+ callback (database& db, const object_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // package_dependent
+ //
+
+ inline
+ void access::view_traits< ::bpkg::package_dependent >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // fragment_repository_count
+ //
+
+ inline
+ void access::view_traits< ::bpkg::fragment_repository_count >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // fragment_repository
+ //
+
+ inline
+ void access::view_traits< ::bpkg::fragment_repository >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // repository_complement_dependent
+ //
+
+ inline
+ void access::view_traits< ::bpkg::repository_complement_dependent >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // repository_prerequisite_dependent
+ //
+
+ inline
+ void access::view_traits< ::bpkg::repository_prerequisite_dependent >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // repository_fragment_package
+ //
+
+ inline
+ void access::view_traits< ::bpkg::repository_fragment_package >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+
+ // package_repository_fragment
+ //
+
+ inline
+ void access::view_traits< ::bpkg::package_repository_fragment >::
+ callback (database& db, view_type& x, callback_event e)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (x);
+ ODB_POTENTIALLY_UNUSED (e);
+ }
+}
+
+#include <odb/schema-version.hxx>
+
+namespace odb
+{
+ // _version
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::_version, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.epoch_null;
+ r = r && i.canonical_upstream_null;
+ r = r && i.canonical_release_null;
+ r = r && i.revision_null;
+ r = r && i.iteration_null;
+ r = r && i.upstream_null;
+ r = r && i.release_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::_version, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.epoch_null = true;
+ i.canonical_upstream_null = true;
+ i.canonical_release_null = true;
+ i.revision_null = true;
+ i.iteration_null = true;
+ i.upstream_null = true;
+ i.release_null = true;
+ }
+
+ // language
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::language, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.name_null;
+ r = r && i.impl_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::language, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.name_null = true;
+ i.impl_null = true;
+ }
+
+ // version_constraint
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::version_constraint, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && composite_value_traits< ::bpkg::_version, id_sqlite >::get_null (i.min_version_value);
+ r = r && composite_value_traits< ::bpkg::_version, id_sqlite >::get_null (i.max_version_value);
+ r = r && i.min_open_null;
+ r = r && i.max_open_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::version_constraint, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ composite_value_traits< ::bpkg::_version, id_sqlite >::set_null (i.min_version_value, sk);
+ composite_value_traits< ::bpkg::_version, id_sqlite >::set_null (i.max_version_value, sk);
+ i.min_open_null = true;
+ i.max_open_null = true;
+ }
+
+ // dependency
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::dependency, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.name_null;
+ r = r && composite_value_traits< ::bpkg::version_constraint, id_sqlite >::get_null (i.constraint_value);
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::dependency, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.name_null = true;
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::set_null (i.constraint_value, sk);
+ }
+
+ // dependency_alternative
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::dependency_alternative, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.enable_null;
+ r = r && i.reflect_null;
+ r = r && i.prefer_null;
+ r = r && i.accept_null;
+ r = r && i.require_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::dependency_alternative, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.enable_null = true;
+ i.reflect_null = true;
+ i.prefer_null = true;
+ i.accept_null = true;
+ i.require_null = true;
+ }
+
+ // dependency_alternatives
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.buildtime_null;
+ r = r && i.comment_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.buildtime_null = true;
+ i.comment_null = true;
+ }
+
+ // test_dependency
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::test_dependency, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && composite_value_traits< ::bpkg::dependency, id_sqlite >::get_null (i);
+ r = r && i.type_null;
+ r = r && i.buildtime_null;
+ r = r && i.enable_null;
+ r = r && i.reflect_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::test_dependency, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ composite_value_traits< ::bpkg::dependency, id_sqlite >::set_null (i, sk);
+ i.type_null = true;
+ i.buildtime_null = true;
+ i.enable_null = true;
+ i.reflect_null = true;
+ }
+
+ // buildfile
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::buildfile, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.path_null;
+ r = r && i.content_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::buildfile, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.path_null = true;
+ i.content_null = true;
+ }
+
+ // distribution_name_value
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::distribution_name_value, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.name_null;
+ r = r && i.value_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::distribution_name_value, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.name_null = true;
+ i.value_null = true;
+ }
+
+ // configuration
+ //
+
+ inline
+ void access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ erase (database& db, const object_type& obj)
+ {
+ callback (db, obj, callback_event::pre_erase);
+ erase (db, id (obj));
+ callback (db, obj, callback_event::post_erase);
+ }
+
+ inline
+ void access::object_traits_impl< ::bpkg::configuration, id_sqlite >::
+ load_ (statements_type& sts,
+ object_type& obj,
+ bool)
+ {
+ ODB_POTENTIALLY_UNUSED (sts);
+ ODB_POTENTIALLY_UNUSED (obj);
+ }
+
+ // canonical_version
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::canonical_version, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.epoch_null;
+ r = r && i.canonical_upstream_null;
+ r = r && i.canonical_release_null;
+ r = r && i.revision_null;
+ r = r && i.iteration_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::canonical_version, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.epoch_null = true;
+ i.canonical_upstream_null = true;
+ i.canonical_release_null = true;
+ i.revision_null = true;
+ i.iteration_null = true;
+ }
+
+ // upstream_version
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::upstream_version, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.upstream_null;
+ r = r && i.release_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::upstream_version, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.upstream_null = true;
+ i.release_null = true;
+ }
+
+ // _repository_location
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::_repository_location, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.url_null;
+ r = r && i.type_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::_repository_location, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.url_null = true;
+ i.type_null = true;
+ }
+
+ // repository_fragment
+ //
+
+ inline
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ erase (database& db, const object_type& obj)
+ {
+ callback (db, obj, callback_event::pre_erase);
+ erase (db, id (obj));
+ callback (db, obj, callback_event::post_erase);
+ }
+
+ // repository_fragment_count
+ //
+
+ // fragment_type
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::repository::fragment_type, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.friendly_name_null;
+ r = r && i.fragment_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::repository::fragment_type, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.friendly_name_null = true;
+ i.fragment_null = true;
+ }
+
+ // repository
+ //
+
+ inline
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ erase (database& db, const object_type& obj)
+ {
+ callback (db, obj, callback_event::pre_erase);
+ erase (db, id (obj));
+ callback (db, obj, callback_event::post_erase);
+ }
+
+ // repository_count
+ //
+
+ // package_location
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::package_location, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.repository_fragment_null;
+ r = r && i.location_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::package_location, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.repository_fragment_null = true;
+ i.location_null = true;
+ }
+
+ // dependency_alternatives_ex
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::dependency_alternatives_ex, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::get_null (i);
+ r = r && i.type_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::dependency_alternatives_ex, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::set_null (i, sk);
+ i.type_null = true;
+ }
+
+ // available_package_id
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::available_package_id, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.name_null;
+ r = r && composite_value_traits< ::bpkg::canonical_version, id_sqlite >::get_null (i.version_value);
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::available_package_id, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.name_null = true;
+ composite_value_traits< ::bpkg::canonical_version, id_sqlite >::set_null (i.version_value, sk);
+ }
+
+ // _dependency_alternative_key
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::available_package::_dependency_alternative_key, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.outer_null;
+ r = r && i.inner_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::available_package::_dependency_alternative_key, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.outer_null = true;
+ i.inner_null = true;
+ }
+
+ // _dependency_key
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::available_package::_dependency_key, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.outer_null;
+ r = r && i.middle_null;
+ r = r && i.inner_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::available_package::_dependency_key, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.outer_null = true;
+ i.middle_null = true;
+ i.inner_null = true;
+ }
+
+ // available_package
+ //
+
+ inline
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ erase (database& db, const object_type& obj)
+ {
+ callback (db, obj, callback_event::pre_erase);
+ erase (db, id (obj));
+ callback (db, obj, callback_event::post_erase);
+ }
+
+ // available_package_count
+ //
+
+ // available_test
+ //
+
+ // available_main
+ //
+
+ // prerequisite_info
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::prerequisite_info, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && composite_value_traits< ::bpkg::version_constraint, id_sqlite >::get_null (i.constraint_value);
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::prerequisite_info, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::set_null (i.constraint_value, sk);
+ }
+
+ // _selected_package_ref
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.configuration_null;
+ r = r && i.prerequisite_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::_selected_package_ref, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.configuration_null = true;
+ i.prerequisite_null = true;
+ }
+
+ // config_variable
+ //
+
+ inline
+ bool access::composite_value_traits< ::bpkg::config_variable, id_sqlite >::
+ get_null (const image_type& i)
+ {
+ bool r (true);
+ r = r && i.name_null;
+ r = r && i.source_null;
+ return r;
+ }
+
+ inline
+ void access::composite_value_traits< ::bpkg::config_variable, id_sqlite >::
+ set_null (image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ i.name_null = true;
+ i.source_null = true;
+ }
+
+ // selected_package
+ //
+
+ inline
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ erase (database& db, const object_type& obj)
+ {
+ callback (db, obj, callback_event::pre_erase);
+ erase (db, id (obj));
+ callback (db, obj, callback_event::post_erase);
+ }
+
+ // certificate
+ //
+
+ inline
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ erase (database& db, const object_type& obj)
+ {
+ callback (db, obj, callback_event::pre_erase);
+ erase (db, id (obj));
+ callback (db, obj, callback_event::post_erase);
+ }
+
+ inline
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ load_ (statements_type& sts,
+ object_type& obj,
+ bool)
+ {
+ ODB_POTENTIALLY_UNUSED (sts);
+ ODB_POTENTIALLY_UNUSED (obj);
+ }
+
+ // package_dependent
+ //
+
+ // fragment_repository_count
+ //
+
+ // fragment_repository
+ //
+
+ // repository_complement_dependent
+ //
+
+ // repository_prerequisite_dependent
+ //
+
+ // repository_fragment_package
+ //
+
+ // package_repository_fragment
+ //
+}
+
diff --git a/bpkg/pkg-bindist-options.cxx b/bpkg/pkg-bindist-options.cxx
new file mode 100644
index 0000000..cceb8b7
--- /dev/null
+++ b/bpkg/pkg-bindist-options.cxx
@@ -0,0 +1,3081 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-bindist-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_bindist_common_options
+ //
+
+ pkg_bindist_common_options::
+ pkg_bindist_common_options ()
+ : distribution_ (),
+ distribution_specified_ (false),
+ architecture_ (),
+ architecture_specified_ (false),
+ recursive_ ("none"),
+ recursive_specified_ (false),
+ private__ (),
+ output_root_ (),
+ output_root_specified_ (false),
+ wipe_output_ (),
+ keep_output_ (),
+ allow_dependent_config_ (),
+ os_release_id_ (),
+ os_release_id_specified_ (false),
+ os_release_version_id_ (),
+ os_release_version_id_specified_ (false),
+ os_release_name_ (),
+ os_release_name_specified_ (false)
+ {
+ }
+
+ bool pkg_bindist_common_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_bindist_common_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_bindist_common_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_bindist_common_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_bindist_common_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_bindist_common_options::
+ merge (const pkg_bindist_common_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.distribution_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->distribution_, a.distribution_);
+ this->distribution_specified_ = true;
+ }
+
+ if (a.architecture_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->architecture_, a.architecture_);
+ this->architecture_specified_ = true;
+ }
+
+ if (a.recursive_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->recursive_, a.recursive_);
+ this->recursive_specified_ = true;
+ }
+
+ if (a.private__)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->private__, a.private__);
+ }
+
+ if (a.output_root_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->output_root_, a.output_root_);
+ this->output_root_specified_ = true;
+ }
+
+ if (a.wipe_output_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->wipe_output_, a.wipe_output_);
+ }
+
+ if (a.keep_output_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->keep_output_, a.keep_output_);
+ }
+
+ if (a.allow_dependent_config_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->allow_dependent_config_, a.allow_dependent_config_);
+ }
+
+ if (a.os_release_id_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->os_release_id_, a.os_release_id_);
+ this->os_release_id_specified_ = true;
+ }
+
+ if (a.os_release_version_id_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->os_release_version_id_, a.os_release_version_id_);
+ this->os_release_version_id_specified_ = true;
+ }
+
+ if (a.os_release_name_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->os_release_name_, a.os_release_name_);
+ this->os_release_name_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_bindist_common_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-BINDIST OPTIONS\033[0m" << ::std::endl
+ << ::std::endl
+ << "See the following sections below for distribution-specific options:" << ::std::endl
+ << ::std::endl
+ << "PKG-BINDIST DEBIAN OPTIONS" << ::std::endl
+ << ::std::endl
+ << "PKG-BINDIST FEDORA OPTIONS" << ::std::endl
+ << ::std::endl
+ << "PKG-BINDIST ARCHIVE OPTIONS" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--distribution\033[0m \033[4mname\033[0m Alternative system/distribution package manager to" << ::std::endl
+ << " generate the binary package for. The valid \033[4mname\033[0m" << ::std::endl
+ << " values are \033[1mdebian\033[0m (Debian and alike, such as Ubuntu," << ::std::endl
+ << " etc), \033[1mfedora\033[0m (Fedora and alike, such as RHEL, CentOS," << ::std::endl
+ << " etc), and \033[1marchive\033[0m (installation archive on any" << ::std::endl
+ << " operating system). Note that some package managers" << ::std::endl
+ << " may only be supported when running on certain host" << ::std::endl
+ << " operating systems." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--architecture\033[0m \033[4mname\033[0m Alternative architecture to generate the binary" << ::std::endl
+ << " package for. The valid \033[4mname\033[0m values are" << ::std::endl
+ << " system/distribution package manager-specific. If" << ::std::endl
+ << " unspecified, the host architecture is used." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--recursive\033[0m \033[4mmode\033[0m Bundle or generate dependencies of the specified" << ::std::endl
+ << " packages. The \033[4mmode\033[0m value can be either \033[1mauto\033[0m, in which" << ::std::endl
+ << " case only the required files from each dependency" << ::std::endl
+ << " package are bundled, \033[1mfull\033[0m, in which case all the" << ::std::endl
+ << " files are bundled, or \033[1mseparate\033[0m, in which case a" << ::std::endl
+ << " separate binary package is generated for each" << ::std::endl
+ << " non-system dependency. It can also be \033[1mnone\033[0m which is" << ::std::endl
+ << " equivalent to not specifying this option (primarily" << ::std::endl
+ << " useful for overriding a previously-specified value)." << ::std::endl
+ << ::std::endl
+ << " Specifically, in the \033[1mauto\033[0m mode any required files," << ::std::endl
+ << " such as shared libraries, are pulled implicitly by" << ::std::endl
+ << " the \033[1minstall\033[0m build system operation, for example, as" << ::std::endl
+ << " part of installing an executable from one of the" << ::std::endl
+ << " specified packages. In contrast, in the \033[1mfull\033[0m mode," << ::std::endl
+ << " each dependency package is installed explicitly and" << ::std::endl
+ << " completely, as if they were specified as additional" << ::std::endl
+ << " package on the command line. The \033[1mseparate\033[0m mode is" << ::std::endl
+ << " equivalent to invoking the \033[1mpkg-bindist\033[0m command on" << ::std::endl
+ << " each dependency package. See also the \033[1m--private\033[0m" << ::std::endl
+ << " option." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--private\033[0m Enable the private installation subdirectory" << ::std::endl
+ << " functionality using the package name as the private" << ::std::endl
+ << " subdirectory. This is primarily useful when bundling" << ::std::endl
+ << " dependencies, such as shared libraries, of an" << ::std::endl
+ << " executable that is being installed into a shared" << ::std::endl
+ << " location, such as \033[1m/usr/\033[0m. See the" << ::std::endl
+ << " \033[1mconfig.install.private\033[0m configuration variable" << ::std::endl
+ << " documentation in the build system manual for details." << ::std::endl
+ << " This option only makes sense together with the" << ::std::endl
+ << " \033[1m--recursive\033[0m option \033[1mauto\033[0m and \033[1mfull\033[0m modes." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--output-root\033[0m|\033[1m-o\033[0m \033[4mdir\033[0m Directory for intermediate files and subdirectories" << ::std::endl
+ << " as well as the resulting binary package. Note that" << ::std::endl
+ << " this option may be required for some system package" << ::std::endl
+ << " managers and may not be specified for others." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--wipe-output\033[0m Wipe the output root directory (either specified with" << ::std::endl
+ << " \033[4m--output-root\033[0m or system package manager-specific)" << ::std::endl
+ << " clean before using it to generate the binary package." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--keep-output\033[0m Keep intermediate files in the output root directory" << ::std::endl
+ << " (either specified with \033[4m--output-root\033[0m or system" << ::std::endl
+ << " package manager-specific) that were used to generate" << ::std::endl
+ << " the binary package. This is primarily useful for" << ::std::endl
+ << " troubleshooting." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--allow-dependent-config\033[0m Allow configuration that is imposed by dependent" << ::std::endl
+ << " packages. Normally this is undesirable because the" << ::std::endl
+ << " resulting binary packages become configured" << ::std::endl
+ << " specificaly for particular dependent packages." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--os-release-id\033[0m \033[4mv\033[0m Override the \033[1mID\033[0m component in \033[1mos-release(5)\033[0m or" << ::std::endl
+ << " equivalent. Note that unlike the rest of the" << ::std::endl
+ << " \033[1m--os-release-*\033[0m options, this option suppresses" << ::std::endl
+ << " automatic detection of the host operating system" << ::std::endl
+ << " information." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--os-release-version-id\033[0m \033[4mv\033[0m Override the \033[1mVERSION_ID\033[0m component in \033[1mos-release(5)\033[0m or" << ::std::endl
+ << " equivalent." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--os-release-name\033[0m \033[4mv\033[0m Override the \033[1mNAME\033[0m component in \033[1mos-release(5)\033[0m or" << ::std::endl
+ << " equivalent." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_bindist_common_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_bindist_common_options_map;
+
+ static _cli_pkg_bindist_common_options_map _cli_pkg_bindist_common_options_map_;
+
+ struct _cli_pkg_bindist_common_options_map_init
+ {
+ _cli_pkg_bindist_common_options_map_init ()
+ {
+ _cli_pkg_bindist_common_options_map_["--distribution"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, string, &pkg_bindist_common_options::distribution_,
+ &pkg_bindist_common_options::distribution_specified_ >;
+ _cli_pkg_bindist_common_options_map_["--architecture"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, string, &pkg_bindist_common_options::architecture_,
+ &pkg_bindist_common_options::architecture_specified_ >;
+ _cli_pkg_bindist_common_options_map_["--recursive"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, string, &pkg_bindist_common_options::recursive_,
+ &pkg_bindist_common_options::recursive_specified_ >;
+ _cli_pkg_bindist_common_options_map_["--private"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, &pkg_bindist_common_options::private__ >;
+ _cli_pkg_bindist_common_options_map_["--output-root"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, dir_path, &pkg_bindist_common_options::output_root_,
+ &pkg_bindist_common_options::output_root_specified_ >;
+ _cli_pkg_bindist_common_options_map_["-o"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, dir_path, &pkg_bindist_common_options::output_root_,
+ &pkg_bindist_common_options::output_root_specified_ >;
+ _cli_pkg_bindist_common_options_map_["--wipe-output"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, &pkg_bindist_common_options::wipe_output_ >;
+ _cli_pkg_bindist_common_options_map_["--keep-output"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, &pkg_bindist_common_options::keep_output_ >;
+ _cli_pkg_bindist_common_options_map_["--allow-dependent-config"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, &pkg_bindist_common_options::allow_dependent_config_ >;
+ _cli_pkg_bindist_common_options_map_["--os-release-id"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, string, &pkg_bindist_common_options::os_release_id_,
+ &pkg_bindist_common_options::os_release_id_specified_ >;
+ _cli_pkg_bindist_common_options_map_["--os-release-version-id"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, string, &pkg_bindist_common_options::os_release_version_id_,
+ &pkg_bindist_common_options::os_release_version_id_specified_ >;
+ _cli_pkg_bindist_common_options_map_["--os-release-name"] =
+ &::bpkg::cli::thunk< pkg_bindist_common_options, string, &pkg_bindist_common_options::os_release_name_,
+ &pkg_bindist_common_options::os_release_name_specified_ >;
+ }
+ };
+
+ static _cli_pkg_bindist_common_options_map_init _cli_pkg_bindist_common_options_map_init_;
+
+ bool pkg_bindist_common_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_bindist_common_options_map::const_iterator i (_cli_pkg_bindist_common_options_map_.find (o));
+
+ if (i != _cli_pkg_bindist_common_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_bindist_common_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+
+ // pkg_bindist_debian_options
+ //
+
+ pkg_bindist_debian_options::
+ pkg_bindist_debian_options ()
+ : debian_prepare_only_ (),
+ debian_buildflags_ ("assign"),
+ debian_buildflags_specified_ (false),
+ debian_maint_option_ (),
+ debian_maint_option_specified_ (false),
+ debian_build_option_ (),
+ debian_build_option_specified_ (false),
+ debian_build_meta_ (),
+ debian_build_meta_specified_ (false),
+ debian_section_ (),
+ debian_section_specified_ (false),
+ debian_priority_ (),
+ debian_priority_specified_ (false),
+ debian_maintainer_ (),
+ debian_maintainer_specified_ (false),
+ debian_architecture_ (),
+ debian_architecture_specified_ (false),
+ debian_main_langdep_ (),
+ debian_main_langdep_specified_ (false),
+ debian_dev_langdep_ (),
+ debian_dev_langdep_specified_ (false),
+ debian_main_extradep_ (),
+ debian_main_extradep_specified_ (false),
+ debian_dev_extradep_ (),
+ debian_dev_extradep_specified_ (false)
+ {
+ }
+
+ bool pkg_bindist_debian_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_bindist_debian_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_bindist_debian_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_bindist_debian_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_bindist_debian_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_bindist_debian_options::
+ merge (const pkg_bindist_debian_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ if (a.debian_prepare_only_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->debian_prepare_only_, a.debian_prepare_only_);
+ }
+
+ if (a.debian_buildflags_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->debian_buildflags_, a.debian_buildflags_);
+ this->debian_buildflags_specified_ = true;
+ }
+
+ if (a.debian_maint_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->debian_maint_option_, a.debian_maint_option_);
+ this->debian_maint_option_specified_ = true;
+ }
+
+ if (a.debian_build_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->debian_build_option_, a.debian_build_option_);
+ this->debian_build_option_specified_ = true;
+ }
+
+ if (a.debian_build_meta_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->debian_build_meta_, a.debian_build_meta_);
+ this->debian_build_meta_specified_ = true;
+ }
+
+ if (a.debian_section_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->debian_section_, a.debian_section_);
+ this->debian_section_specified_ = true;
+ }
+
+ if (a.debian_priority_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->debian_priority_, a.debian_priority_);
+ this->debian_priority_specified_ = true;
+ }
+
+ if (a.debian_maintainer_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->debian_maintainer_, a.debian_maintainer_);
+ this->debian_maintainer_specified_ = true;
+ }
+
+ if (a.debian_architecture_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->debian_architecture_, a.debian_architecture_);
+ this->debian_architecture_specified_ = true;
+ }
+
+ if (a.debian_main_langdep_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->debian_main_langdep_, a.debian_main_langdep_);
+ this->debian_main_langdep_specified_ = true;
+ }
+
+ if (a.debian_dev_langdep_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->debian_dev_langdep_, a.debian_dev_langdep_);
+ this->debian_dev_langdep_specified_ = true;
+ }
+
+ if (a.debian_main_extradep_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->debian_main_extradep_, a.debian_main_extradep_);
+ this->debian_main_extradep_specified_ = true;
+ }
+
+ if (a.debian_dev_extradep_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->debian_dev_extradep_, a.debian_dev_extradep_);
+ this->debian_dev_extradep_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_bindist_debian_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEBIAN DESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The Debian binary packages are generated by producing the standard" << ::std::endl
+ << "\033[1mdebian/control\033[0m, \033[1mdebian/rules\033[0m, and other package metadata files and then" << ::std::endl
+ << "invoking \033[1mdpkg-buildpackage(1)\033[0m to build the binary package from that. In" << ::std::endl
+ << "particular, the \033[1mdebian/rules\033[0m implemenation is based on the \033[1mdh(1)\033[0m command" << ::std::endl
+ << "sequencer. While this approach is normally used to build packages from source," << ::std::endl
+ << "this implementation \"pretends\" that this is what's happening by overriding a" << ::std::endl
+ << "number of \033[1mdh\033[0m targets to invoke the \033[1mbuild2\033[0m build system on the required packages" << ::std::endl
+ << "directly in their \033[1mbpkg\033[0m configuration locations." << ::std::endl
+ << ::std::endl
+ << "The \033[1mdpkg-dev\033[0m (or \033[1mbuild-essential\033[0m) and \033[1mdebhelper\033[0m Debian packages must be" << ::std::endl
+ << "installed before invocation. Typical invocation:" << ::std::endl
+ << ::std::endl
+ << "bpkg build libhello" << ::std::endl
+ << "bpkg test libhello" << ::std::endl
+ << "bpkg bindist -o /tmp/output/ libhello" << ::std::endl
+ << ::std::endl
+ << "Unless the \033[1m--recursive\033[0m option \033[1mauto\033[0m or \033[1mfull\033[0m modes are specified, dependencies of" << ::std::endl
+ << "the specified package are translated to dependencies in the resulting binary" << ::std::endl
+ << "package using names and versions that refer to packages that would be generated" << ::std::endl
+ << "by the \033[1mpkg-bindist\033[0m command (called \"non-native\" packages). If instead you would" << ::std::endl
+ << "like certain dependencies to refer to binary packages provided by the" << ::std::endl
+ << "distribution (called \"native\" packages), then you need to arrange for them to" << ::std::endl
+ << "be built as system (see \033[1mbpkg-pkg-build(1)\033[0m for details). For example, if our" << ::std::endl
+ << "\033[1mlibhello\033[0m has a dependency on \033[1mlibsqlite3\033[0m and we would like the binary package" << ::std::endl
+ << "for \033[1mlibhello\033[0m to refer to \033[1mlibsqlite3\033[0m from Debian (or alike), then the \033[1mpkg-build\033[0m" << ::std::endl
+ << "command would need to be (\033[1m--sys-install\033[0m is optional):" << ::std::endl
+ << ::std::endl
+ << "bpkg build --sys-install libhello ?sys:libsqlite3" << ::std::endl
+ << ::std::endl
+ << "Such a package with native dependencies can then be installed (including any" << ::std::endl
+ << "missing native dependencies) using the \033[1mapt\033[0m or \033[1mapt-get\033[0m \033[1minstall\033[0m command. Note" << ::std::endl
+ << "that the specified \033[1m.deb\033[0m file must include a directory separator (/\033[0m) in order to" << ::std::endl
+ << "be recognized as a file rather than a package name. For example:" << ::std::endl
+ << ::std::endl
+ << "sudo apt-get install ./libhello_1.2.3-0~debian11_amd64.deb \\" << ::std::endl
+ << " ./libhello-dev_1.2.3-0~debian11_amd64.deb" << ::std::endl
+ << ::std::endl
+ << "See Debian Package Mapping for Production (bpkg#bindist-mapping-debian-produce)" << ::std::endl
+ << "for details on \033[1mbpkg\033[0m to Debian package name and version mapping." << ::std::endl;
+
+ os << std::endl
+ << "\033[1mPKG-BINDIST DEBIAN OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-prepare-only\033[0m Prepare all the package metadata files (\033[1mcontrol\033[0m," << ::std::endl
+ << " \033[1mrules\033[0m, etc) but do not invoke \033[1mdpkg-buildpackage\033[0m to" << ::std::endl
+ << " generate the binary package, printing its command" << ::std::endl
+ << " line instead unless requested to be quiet. Implies" << ::std::endl
+ << " \033[1m--keep-output\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-buildflags\033[0m \033[4mmode\033[0m Package build flags (\033[1mdpkg-buildflags\033[0m) usage mode." << ::std::endl
+ << " Valid \033[4mmode\033[0m values are \033[1massign\033[0m (use the build flags" << ::std::endl
+ << " instead of configured), \033[1mappend\033[0m (use the build flags" << ::std::endl
+ << " in addition to configured, putting them last)," << ::std::endl
+ << " \033[1mprepend\033[0m (use the build flags in addition to" << ::std::endl
+ << " configured, putting them first), and \033[1mignore\033[0m (ignore" << ::std::endl
+ << " build flags). The default mode is \033[1massign\033[0m. Note that" << ::std::endl
+ << " compiler mode options, if any, are used as" << ::std::endl
+ << " configured." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-maint-option\033[0m \033[4mo\033[0m Alternative options to specify in the" << ::std::endl
+ << " \033[1mDEB_BUILD_MAINT_OPTIONS\033[0m variable of the \033[1mrules\033[0m file." << ::std::endl
+ << " To specify multiple maintainer options repeat this" << ::std::endl
+ << " option and/or specify them as a single value" << ::std::endl
+ << " separated with spaces." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-build-option\033[0m \033[4mo\033[0m Additional option to pass to the \033[1mdpkg-buildpackage\033[0m" << ::std::endl
+ << " program. Repeat this option to specify multiple build" << ::std::endl
+ << " options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-build-meta\033[0m \033[4mdata\033[0m Alternative or additional build metadata to include" << ::std::endl
+ << " in the binary package version. If the specified value" << ::std::endl
+ << " starts/ends with \033[1m+\033[0m then the value (with \033[1m+\033[0m removed) is" << ::std::endl
+ << " added after/before the default metadata. Otherwise it" << ::std::endl
+ << " is used as is instead of the default metadata. If" << ::std::endl
+ << " empty value is specified, then no build metadata is" << ::std::endl
+ << " included. By default, the build metadata is the \033[1mID\033[0m" << ::std::endl
+ << " and \033[1mVERSION_ID\033[0m components from \033[1mos-release(5)\033[0m, for" << ::std::endl
+ << " example, \033[1mdebian10\033[0m in version \033[1m1.2.3-0~debian10\033[0m. See" << ::std::endl
+ << " also \033[1m--os-release-*\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-section\033[0m \033[4mv\033[0m Alternative \033[1mSection\033[0m \033[1mcontrol\033[0m file field value for the" << ::std::endl
+ << " main binary package. The default is either \033[1mlibs\033[0m or" << ::std::endl
+ << " \033[1mdevel\033[0m, depending on the package type." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-priority\033[0m \033[4mv\033[0m Alternative \033[1mPriority\033[0m \033[1mcontrol\033[0m file field value. The" << ::std::endl
+ << " default is \033[1moptional\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-maintainer\033[0m \033[4mv\033[0m Alternative \033[1mMaintainer\033[0m \033[1mcontrol\033[0m file field value. The" << ::std::endl
+ << " default is the \033[1mpackage-email\033[0m value from package" << ::std::endl
+ << " \033[1mmanifest\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-architecture\033[0m \033[4mv\033[0m Alternative \033[1mArchitecture\033[0m \033[1mcontrol\033[0m file field value for" << ::std::endl
+ << " the main binary package, normally \033[1mall\033[0m" << ::std::endl
+ << " (architecture-independent). The default is \033[1many\033[0m" << ::std::endl
+ << " (architecture-dependent)." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-main-langdep\033[0m \033[4mv\033[0m Override the language runtime dependencies (such as" << ::std::endl
+ << " \033[1mlibc6\033[0m, \033[1mlibstdc++6\033[0m, etc) in the \033[1mDepends\033[0m \033[1mcontrol\033[0m file" << ::std::endl
+ << " field value of the main binary package." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-dev-langdep\033[0m \033[4mv\033[0m Override the language runtime dependencies (such as" << ::std::endl
+ << " \033[1mlibc-dev\033[0m, \033[1mlibstdc++-dev\033[0m, etc) in the \033[1mDepends\033[0m \033[1mcontrol\033[0m" << ::std::endl
+ << " file field value of the development (\033[1m-dev\033[0m) binary" << ::std::endl
+ << " package." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-main-extradep\033[0m \033[4mv\033[0m Extra dependencies to add to the \033[1mDepends\033[0m \033[1mcontrol\033[0m file" << ::std::endl
+ << " field value of the main binary package." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--debian-dev-extradep\033[0m \033[4mv\033[0m Extra dependencies to add to the \033[1mDepends\033[0m \033[1mcontrol\033[0m file" << ::std::endl
+ << " field value of the development (\033[1m-dev\033[0m) binary package." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_bindist_debian_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_bindist_debian_options_map;
+
+ static _cli_pkg_bindist_debian_options_map _cli_pkg_bindist_debian_options_map_;
+
+ struct _cli_pkg_bindist_debian_options_map_init
+ {
+ _cli_pkg_bindist_debian_options_map_init ()
+ {
+ _cli_pkg_bindist_debian_options_map_["--debian-prepare-only"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, &pkg_bindist_debian_options::debian_prepare_only_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-buildflags"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, string, &pkg_bindist_debian_options::debian_buildflags_,
+ &pkg_bindist_debian_options::debian_buildflags_specified_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-maint-option"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, strings, &pkg_bindist_debian_options::debian_maint_option_,
+ &pkg_bindist_debian_options::debian_maint_option_specified_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-build-option"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, strings, &pkg_bindist_debian_options::debian_build_option_,
+ &pkg_bindist_debian_options::debian_build_option_specified_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-build-meta"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, string, &pkg_bindist_debian_options::debian_build_meta_,
+ &pkg_bindist_debian_options::debian_build_meta_specified_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-section"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, string, &pkg_bindist_debian_options::debian_section_,
+ &pkg_bindist_debian_options::debian_section_specified_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-priority"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, string, &pkg_bindist_debian_options::debian_priority_,
+ &pkg_bindist_debian_options::debian_priority_specified_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-maintainer"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, string, &pkg_bindist_debian_options::debian_maintainer_,
+ &pkg_bindist_debian_options::debian_maintainer_specified_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-architecture"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, string, &pkg_bindist_debian_options::debian_architecture_,
+ &pkg_bindist_debian_options::debian_architecture_specified_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-main-langdep"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, string, &pkg_bindist_debian_options::debian_main_langdep_,
+ &pkg_bindist_debian_options::debian_main_langdep_specified_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-dev-langdep"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, string, &pkg_bindist_debian_options::debian_dev_langdep_,
+ &pkg_bindist_debian_options::debian_dev_langdep_specified_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-main-extradep"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, string, &pkg_bindist_debian_options::debian_main_extradep_,
+ &pkg_bindist_debian_options::debian_main_extradep_specified_ >;
+ _cli_pkg_bindist_debian_options_map_["--debian-dev-extradep"] =
+ &::bpkg::cli::thunk< pkg_bindist_debian_options, string, &pkg_bindist_debian_options::debian_dev_extradep_,
+ &pkg_bindist_debian_options::debian_dev_extradep_specified_ >;
+ }
+ };
+
+ static _cli_pkg_bindist_debian_options_map_init _cli_pkg_bindist_debian_options_map_init_;
+
+ bool pkg_bindist_debian_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_bindist_debian_options_map::const_iterator i (_cli_pkg_bindist_debian_options_map_.find (o));
+
+ if (i != _cli_pkg_bindist_debian_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool pkg_bindist_debian_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+
+ // pkg_bindist_fedora_options
+ //
+
+ pkg_bindist_fedora_options::
+ pkg_bindist_fedora_options ()
+ : fedora_prepare_only_ (),
+ fedora_buildflags_ ("assign"),
+ fedora_buildflags_specified_ (false),
+ fedora_build_option_ (),
+ fedora_build_option_specified_ (false),
+ fedora_query_option_ (),
+ fedora_query_option_specified_ (false),
+ fedora_dist_tag_ (),
+ fedora_dist_tag_specified_ (false),
+ fedora_packager_ (),
+ fedora_packager_specified_ (false),
+ fedora_build_arch_ (),
+ fedora_build_arch_specified_ (false),
+ fedora_main_langreq_ (),
+ fedora_main_langreq_specified_ (false),
+ fedora_devel_langreq_ (),
+ fedora_devel_langreq_specified_ (false),
+ fedora_stat_langreq_ (),
+ fedora_stat_langreq_specified_ (false),
+ fedora_main_extrareq_ (),
+ fedora_main_extrareq_specified_ (false),
+ fedora_devel_extrareq_ (),
+ fedora_devel_extrareq_specified_ (false),
+ fedora_stat_extrareq_ (),
+ fedora_stat_extrareq_specified_ (false)
+ {
+ }
+
+ bool pkg_bindist_fedora_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_bindist_fedora_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_bindist_fedora_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_bindist_fedora_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_bindist_fedora_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_bindist_fedora_options::
+ merge (const pkg_bindist_fedora_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ if (a.fedora_prepare_only_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->fedora_prepare_only_, a.fedora_prepare_only_);
+ }
+
+ if (a.fedora_buildflags_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->fedora_buildflags_, a.fedora_buildflags_);
+ this->fedora_buildflags_specified_ = true;
+ }
+
+ if (a.fedora_build_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->fedora_build_option_, a.fedora_build_option_);
+ this->fedora_build_option_specified_ = true;
+ }
+
+ if (a.fedora_query_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->fedora_query_option_, a.fedora_query_option_);
+ this->fedora_query_option_specified_ = true;
+ }
+
+ if (a.fedora_dist_tag_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->fedora_dist_tag_, a.fedora_dist_tag_);
+ this->fedora_dist_tag_specified_ = true;
+ }
+
+ if (a.fedora_packager_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->fedora_packager_, a.fedora_packager_);
+ this->fedora_packager_specified_ = true;
+ }
+
+ if (a.fedora_build_arch_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->fedora_build_arch_, a.fedora_build_arch_);
+ this->fedora_build_arch_specified_ = true;
+ }
+
+ if (a.fedora_main_langreq_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->fedora_main_langreq_, a.fedora_main_langreq_);
+ this->fedora_main_langreq_specified_ = true;
+ }
+
+ if (a.fedora_devel_langreq_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->fedora_devel_langreq_, a.fedora_devel_langreq_);
+ this->fedora_devel_langreq_specified_ = true;
+ }
+
+ if (a.fedora_stat_langreq_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->fedora_stat_langreq_, a.fedora_stat_langreq_);
+ this->fedora_stat_langreq_specified_ = true;
+ }
+
+ if (a.fedora_main_extrareq_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->fedora_main_extrareq_, a.fedora_main_extrareq_);
+ this->fedora_main_extrareq_specified_ = true;
+ }
+
+ if (a.fedora_devel_extrareq_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->fedora_devel_extrareq_, a.fedora_devel_extrareq_);
+ this->fedora_devel_extrareq_specified_ = true;
+ }
+
+ if (a.fedora_stat_extrareq_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->fedora_stat_extrareq_, a.fedora_stat_extrareq_);
+ this->fedora_stat_extrareq_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_bindist_fedora_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mFEDORA DESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The Fedora binary packages are generated by producing the standard RPM spec" << ::std::endl
+ << "file and then invoking \033[1mrpmbuild(8)\033[0m to build the binary package from that. While" << ::std::endl
+ << "this approach is normally used to build packages from source, this" << ::std::endl
+ << "implementation \"pretends\" that this is what's happening by overriding a number" << ::std::endl
+ << "of RPM spec file sections to invoke the \033[1mbuild2\033[0m build system on the required" << ::std::endl
+ << "packages directly in their \033[1mbpkg\033[0m configuration locations." << ::std::endl
+ << ::std::endl
+ << "The \033[1mrpmdevtools\033[0m Fedora package must be installed before invocation. Typical" << ::std::endl
+ << "invocation:" << ::std::endl
+ << ::std::endl
+ << "bpkg build libhello" << ::std::endl
+ << "bpkg test libhello" << ::std::endl
+ << "bpkg bindist libhello" << ::std::endl
+ << ::std::endl
+ << "The resulting binary packages are placed into the standard \033[1mrpmbuild\033[0m output" << ::std::endl
+ << "directory (normally \033[1m~/rpmbuild/RPMS/\033[0m\033[4march\033[0m\033[1m/\033[0m\033[0m)." << ::std::endl
+ << ::std::endl
+ << "Unless the \033[1m--recursive\033[0m option \033[1mauto\033[0m or \033[1mfull\033[0m modes are specified, dependencies of" << ::std::endl
+ << "the specified package are translated to dependencies in the resulting binary" << ::std::endl
+ << "package using names and versions that refer to packages that would be generated" << ::std::endl
+ << "by the \033[1mpkg-bindist\033[0m command (called \"non-native\" packages). If instead you would" << ::std::endl
+ << "like certain dependencies to refer to binary packages provided by the" << ::std::endl
+ << "distribution (called \"native\" packages), then you need to arrange for them to" << ::std::endl
+ << "be built as system (see \033[1mbpkg-pkg-build(1)\033[0m for details). For example, if our" << ::std::endl
+ << "\033[1mlibhello\033[0m has a dependency on \033[1mlibsqlite3\033[0m and we would like the binary package" << ::std::endl
+ << "for \033[1mlibhello\033[0m to refer to \033[1msqlite-libs\033[0m from Fedora (or alike), then the" << ::std::endl
+ << "\033[1mpkg-build\033[0m command would need to be (\033[1m--sys-install\033[0m is optional):" << ::std::endl
+ << ::std::endl
+ << "bpkg build --sys-install libhello ?sys:libsqlite3" << ::std::endl
+ << ::std::endl
+ << "Such a package with native dependencies can then be installed (including any" << ::std::endl
+ << "missing native dependencies) using the \033[1mdnf install\033[0m command. For example:" << ::std::endl
+ << ::std::endl
+ << "sudo dnf install libhello-1.2.3-1.fc35.x86_64.rpm \\" << ::std::endl
+ << " libhello-devel-1.2.3-1.fc35.x86_64.rpm" << ::std::endl
+ << ::std::endl
+ << "See Fedora Package Mapping for Production (bpkg#bindist-mapping-fedora-produce)" << ::std::endl
+ << "for details on \033[1mbpkg\033[0m to Fedora package name and version mapping." << ::std::endl;
+
+ os << std::endl
+ << "\033[1mPKG-BINDIST FEDORA OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-prepare-only\033[0m Prepare the RPM spec file but do not invoke \033[1mrpmbuild\033[0m" << ::std::endl
+ << " to generate the binary package, printing its command" << ::std::endl
+ << " line instead unless requested to be quiet." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-buildflags\033[0m \033[4mmode\033[0m Package build flags (\033[1m%{build_*flags}\033[0m macros) usage" << ::std::endl
+ << " mode. Valid \033[4mmode\033[0m values are \033[1massign\033[0m (use the build" << ::std::endl
+ << " flags instead of configured), \033[1mappend\033[0m (use the build" << ::std::endl
+ << " flags in addition to configured, putting them last)," << ::std::endl
+ << " \033[1mprepend\033[0m (use the build flags in addition to" << ::std::endl
+ << " configured, putting them first), and \033[1mignore\033[0m (ignore" << ::std::endl
+ << " build flags). The default mode is \033[1massign\033[0m. Note that" << ::std::endl
+ << " compiler mode options, if any, are used as" << ::std::endl
+ << " configured." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-build-option\033[0m \033[4mo\033[0m Additional option to pass to the \033[1mrpmbuild\033[0m program. If" << ::std::endl
+ << " specified, these options must be consistent with the" << ::std::endl
+ << " query options (\033[1m--fedora-query-option\033[0m) to result in" << ::std::endl
+ << " identical macro expansions. Repeat this option to" << ::std::endl
+ << " specify multiple build options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-query-option\033[0m \033[4mo\033[0m Additional option to pass to the \033[1mrpm\033[0m program. This" << ::std::endl
+ << " program is used to query RPM macro values which" << ::std::endl
+ << " affect the binary package. If specified, these" << ::std::endl
+ << " options must be consistent with the build options" << ::std::endl
+ << " (\033[1m--fedora-build-option\033[0m) to result in identical macro" << ::std::endl
+ << " expansions. Repeat this option to specify multiple" << ::std::endl
+ << " query options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-dist-tag\033[0m \033[4mtag\033[0m Alternative or additional distribution tag to use in" << ::std::endl
+ << " the binary package release. If the specified value" << ::std::endl
+ << " starts/ends with \033[1m+\033[0m then the value (with \033[1m+\033[0m removed) is" << ::std::endl
+ << " added after/before the default distribution tag." << ::std::endl
+ << " Otherwise it is used as is instead of the default" << ::std::endl
+ << " tag. If empty value is specified, then no" << ::std::endl
+ << " distribution tag is included. The default is a value" << ::std::endl
+ << " that identifies the distribution being used to build" << ::std::endl
+ << " the package, for example, \033[1mfc35\033[0m for Fedora 35 or \033[1mel8\033[0m" << ::std::endl
+ << " for RHEL 8." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-packager\033[0m \033[4mv\033[0m Alternative \033[1mPackager\033[0m RPM spec file directive value." << ::std::endl
+ << " The default is the \033[1mpackage-email\033[0m value from package" << ::std::endl
+ << " \033[1mmanifest\033[0m. If empty value is specified, then the" << ::std::endl
+ << " \033[1mPackager\033[0m directive is omitted from the spec file." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-build-arch\033[0m \033[4mv\033[0m \033[1mBuildArch\033[0m RPM spec file directive value for the main" << ::std::endl
+ << " binary package, normally \033[1mnoarch\033[0m" << ::std::endl
+ << " (architecture-independent). By default the directive" << ::std::endl
+ << " is omitted, assuming that the package is" << ::std::endl
+ << " architecture-dependent." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-main-langreq\033[0m \033[4mv\033[0m Override the language runtime dependencies (such as" << ::std::endl
+ << " \033[1mglibc\033[0m, \033[1mlibstdc++\033[0m, etc) of the main binary package by" << ::std::endl
+ << " replacing the corresponding \033[1mRequires\033[0m RPM spec file" << ::std::endl
+ << " directives. If empty value is specified then no" << ::std::endl
+ << " language runtime dependencies are specified. Repeat" << ::std::endl
+ << " this option to specify multiple language runtime" << ::std::endl
+ << " dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-devel-langreq\033[0m \033[4mv\033[0m Override the language runtime dependencies (such as" << ::std::endl
+ << " \033[1mglibc-devel\033[0m, \033[1mlibstdc++-devel\033[0m, etc) of the development" << ::std::endl
+ << " (\033[1m-devel\033[0m) binary package by replacing the" << ::std::endl
+ << " corresponding \033[1mRequires\033[0m RPM spec file directives. If" << ::std::endl
+ << " empty value is specified then no language runtime" << ::std::endl
+ << " dependencies are specified. Repeat this option to" << ::std::endl
+ << " specify multiple language runtime dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-stat-langreq\033[0m \033[4mv\033[0m Override the language runtime dependencies (such as" << ::std::endl
+ << " \033[1mglibc-static\033[0m, \033[1mlibstdc++-static\033[0m, etc) of the static" << ::std::endl
+ << " libraries (\033[1m-static\033[0m) binary package by replacing the" << ::std::endl
+ << " corresponding \033[1mRequires\033[0m RPM spec file directives. If" << ::std::endl
+ << " empty value is specified then no language runtime" << ::std::endl
+ << " dependencies are specified. Repeat this option to" << ::std::endl
+ << " specify multiple language runtime dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-main-extrareq\033[0m \033[4mv\033[0m Extra dependency to add to the main binary package as" << ::std::endl
+ << " an additional \033[1mRequires\033[0m RPM spec file directive." << ::std::endl
+ << " Repeat this option to specify multiple extra" << ::std::endl
+ << " dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-devel-extrareq\033[0m \033[4mv\033[0m Extra dependency to add to the development (\033[1m-devel\033[0m)" << ::std::endl
+ << " binary package as an additional \033[1mRequires\033[0m RPM spec" << ::std::endl
+ << " file directive. Repeat this option to specify" << ::std::endl
+ << " multiple extra dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fedora-stat-extrareq\033[0m \033[4mv\033[0m Extra dependency to add to the static libraries" << ::std::endl
+ << " (\033[1m-static\033[0m) binary package as an additional \033[1mRequires\033[0m" << ::std::endl
+ << " RPM spec file directive. Repeat this option to" << ::std::endl
+ << " specify multiple extra dependencies." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_bindist_fedora_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_bindist_fedora_options_map;
+
+ static _cli_pkg_bindist_fedora_options_map _cli_pkg_bindist_fedora_options_map_;
+
+ struct _cli_pkg_bindist_fedora_options_map_init
+ {
+ _cli_pkg_bindist_fedora_options_map_init ()
+ {
+ _cli_pkg_bindist_fedora_options_map_["--fedora-prepare-only"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, &pkg_bindist_fedora_options::fedora_prepare_only_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-buildflags"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, string, &pkg_bindist_fedora_options::fedora_buildflags_,
+ &pkg_bindist_fedora_options::fedora_buildflags_specified_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-build-option"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, strings, &pkg_bindist_fedora_options::fedora_build_option_,
+ &pkg_bindist_fedora_options::fedora_build_option_specified_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-query-option"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, strings, &pkg_bindist_fedora_options::fedora_query_option_,
+ &pkg_bindist_fedora_options::fedora_query_option_specified_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-dist-tag"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, string, &pkg_bindist_fedora_options::fedora_dist_tag_,
+ &pkg_bindist_fedora_options::fedora_dist_tag_specified_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-packager"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, string, &pkg_bindist_fedora_options::fedora_packager_,
+ &pkg_bindist_fedora_options::fedora_packager_specified_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-build-arch"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, string, &pkg_bindist_fedora_options::fedora_build_arch_,
+ &pkg_bindist_fedora_options::fedora_build_arch_specified_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-main-langreq"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, strings, &pkg_bindist_fedora_options::fedora_main_langreq_,
+ &pkg_bindist_fedora_options::fedora_main_langreq_specified_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-devel-langreq"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, strings, &pkg_bindist_fedora_options::fedora_devel_langreq_,
+ &pkg_bindist_fedora_options::fedora_devel_langreq_specified_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-stat-langreq"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, strings, &pkg_bindist_fedora_options::fedora_stat_langreq_,
+ &pkg_bindist_fedora_options::fedora_stat_langreq_specified_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-main-extrareq"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, strings, &pkg_bindist_fedora_options::fedora_main_extrareq_,
+ &pkg_bindist_fedora_options::fedora_main_extrareq_specified_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-devel-extrareq"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, strings, &pkg_bindist_fedora_options::fedora_devel_extrareq_,
+ &pkg_bindist_fedora_options::fedora_devel_extrareq_specified_ >;
+ _cli_pkg_bindist_fedora_options_map_["--fedora-stat-extrareq"] =
+ &::bpkg::cli::thunk< pkg_bindist_fedora_options, strings, &pkg_bindist_fedora_options::fedora_stat_extrareq_,
+ &pkg_bindist_fedora_options::fedora_stat_extrareq_specified_ >;
+ }
+ };
+
+ static _cli_pkg_bindist_fedora_options_map_init _cli_pkg_bindist_fedora_options_map_init_;
+
+ bool pkg_bindist_fedora_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_bindist_fedora_options_map::const_iterator i (_cli_pkg_bindist_fedora_options_map_.find (o));
+
+ if (i != _cli_pkg_bindist_fedora_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool pkg_bindist_fedora_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+
+ // pkg_bindist_archive_options
+ //
+
+ pkg_bindist_archive_options::
+ pkg_bindist_archive_options ()
+ : archive_prepare_only_ (),
+ archive_type_ (),
+ archive_type_specified_ (false),
+ archive_lang_ (),
+ archive_lang_specified_ (false),
+ archive_lang_impl_ (),
+ archive_lang_impl_specified_ (false),
+ archive_no_cpu_ (),
+ archive_no_os_ (),
+ archive_build_meta_ (),
+ archive_build_meta_specified_ (false),
+ archive_install_root_ (),
+ archive_install_root_specified_ (false),
+ archive_install_config_ (),
+ archive_split_ (),
+ archive_split_specified_ (false)
+ {
+ }
+
+ bool pkg_bindist_archive_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_bindist_archive_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_bindist_archive_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_bindist_archive_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_bindist_archive_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_bindist_archive_options::
+ merge (const pkg_bindist_archive_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ if (a.archive_prepare_only_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->archive_prepare_only_, a.archive_prepare_only_);
+ }
+
+ if (a.archive_type_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->archive_type_, a.archive_type_);
+ this->archive_type_specified_ = true;
+ }
+
+ if (a.archive_lang_specified_)
+ {
+ ::bpkg::cli::parser< std::multimap<string, string>>::merge (
+ this->archive_lang_, a.archive_lang_);
+ this->archive_lang_specified_ = true;
+ }
+
+ if (a.archive_lang_impl_specified_)
+ {
+ ::bpkg::cli::parser< std::multimap<string, string>>::merge (
+ this->archive_lang_impl_, a.archive_lang_impl_);
+ this->archive_lang_impl_specified_ = true;
+ }
+
+ if (a.archive_no_cpu_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->archive_no_cpu_, a.archive_no_cpu_);
+ }
+
+ if (a.archive_no_os_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->archive_no_os_, a.archive_no_os_);
+ }
+
+ if (a.archive_build_meta_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->archive_build_meta_, a.archive_build_meta_);
+ this->archive_build_meta_specified_ = true;
+ }
+
+ if (a.archive_install_root_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->archive_install_root_, a.archive_install_root_);
+ this->archive_install_root_specified_ = true;
+ }
+
+ if (a.archive_install_config_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->archive_install_config_, a.archive_install_config_);
+ }
+
+ if (a.archive_split_specified_)
+ {
+ ::bpkg::cli::parser< std::map<string, string>>::merge (
+ this->archive_split_, a.archive_split_);
+ this->archive_split_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_bindist_archive_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mARCHIVE DESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The installation archive binary packages are generated by invoking the \033[1mbuild2\033[0m" << ::std::endl
+ << "build system on the required packages directly in their \033[1mbpkg\033[0m configuration" << ::std::endl
+ << "locations and installing them into the binary package directory using the" << ::std::endl
+ << "\033[1mconfig.install.chroot\033[0m mechanism. Then this directory is packaged with \033[1mtar\033[0m or" << ::std::endl
+ << "\033[1mzip\033[0m to produce one or more binary package archives." << ::std::endl
+ << ::std::endl
+ << "The generation of installation archive packages is never the default and should" << ::std::endl
+ << "be requested explicitly with the \033[1m--distribution=archive\033[0m option. The" << ::std::endl
+ << "installation directory layout and the package archives to generate can be" << ::std::endl
+ << "specified with the \033[1m--archive-install-*\033[0m and \033[1m--archive-type\033[0m options (refer to" << ::std::endl
+ << "their documentation for defaults)." << ::std::endl
+ << ::std::endl
+ << "The binary package directory (the top-level directory inside the archive) as" << ::std::endl
+ << "well as the archive file base (the file name without the extension) are the" << ::std::endl
+ << "same and have the following form:" << ::std::endl
+ << ::std::endl
+ << "\033[4mpackage\033[0m-\033[4mversion\033[0m-\033[4mbuild_metadata\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "Where \033[4mpackage\033[0m is the package name and \033[4mversion\033[0m is the \033[1mbpkg\033[0m package version." << ::std::endl
+ << "Unless overridden with the \033[1m--archive-build-meta\033[0m option, \033[4mbuild_metadata\033[0m has the" << ::std::endl
+ << "following form:" << ::std::endl
+ << ::std::endl
+ << "\033[4mcpu\033[0m-\033[4mos\033[0m[-\033[4mlangrt\033[0m...]\033[0m" << ::std::endl
+ << ::std::endl
+ << "Where \033[4mcpu\033[0m is the target CPU (for example, \033[1mx86_64\033[0m or \033[1maarch64\033[0m; omitted if" << ::std::endl
+ << "\033[1m--archive-no-cpu\033[0m is specified), \033[4mos\033[0m is the \033[1mID\033[0m and \033[1mVERSION_ID\033[0m components from" << ::std::endl
+ << "\033[1mos-release(5)\033[0m (or equivalent, for example, \033[1mdebian11\033[0m or \033[1mwindows10\033[0m; omitted if" << ::std::endl
+ << "\033[1m--archive-no-os\033[0m is specified), and \033[4mlangrt\033[0m are the language runtimes as mapped" << ::std::endl
+ << "by the \033[1m--archive-lang*\033[0m options (for example, \033[1mgcc12\033[0m or \033[1mmsvc17.4\033[0m)." << ::std::endl
+ << ::std::endl
+ << "For example, given the following invocation on Debian 11 running on \033[1mx86_64\033[0m:" << ::std::endl
+ << ::std::endl
+ << "bpkg build libhello" << ::std::endl
+ << "bpkg test libhello" << ::std::endl
+ << "bpkg bindist \\" << ::std::endl
+ << " -o /tmp/output/ \\" << ::std::endl
+ << " --distribution=archive \\" << ::std::endl
+ << " --archive-lang cc=gcc12 \\" << ::std::endl
+ << " libhello" << ::std::endl
+ << ::std::endl
+ << "We will end up with the package archive in the following form:" << ::std::endl
+ << ::std::endl
+ << "libhello-1.2.3-x86_64-debian11-gcc12.tar.xz" << ::std::endl
+ << ::std::endl
+ << "The recommended language runtime id format is the runtime name followed by the" << ::std::endl
+ << "version, for example, \033[1mgcc12\033[0m or \033[1mmsvc17.4\033[0m. Note that its purpose is not to" << ::std::endl
+ << "provide a precise specification of requirements but rather to help the user of" << ::std::endl
+ << "a binary package to pick the appropriate variant. Refer to the \033[1m--archive-lang*\033[0m" << ::std::endl
+ << "options documentation for details on the mapping semantics." << ::std::endl
+ << ::std::endl
+ << "Instead of mapping languages individually you can specify entire build metadata" << ::std::endl
+ << "as a single value with the \033[1m--archive-build-meta\033[0m (it is also possible to add" << ::std::endl
+ << "additional metadata; see the option documentation for details). For example:" << ::std::endl
+ << ::std::endl
+ << "bpkg bindist \\" << ::std::endl
+ << " -o /tmp/output/ \\" << ::std::endl
+ << " --distribution=archive \\" << ::std::endl
+ << " --archive-build-meta=x86_64-linux-glibc" << ::std::endl
+ << " libhello" << ::std::endl
+ << ::std::endl
+ << "This will produce the package archive in the following form:" << ::std::endl
+ << ::std::endl
+ << "libhello-1.2.3-x86_64-linux-glibc.tar.xz" << ::std::endl
+ << ::std::endl
+ << "To install the binary package from archive simply unpack it using \033[1mtar\033[0m or \033[1mzip\033[0m." << ::std::endl
+ << "You can use the \033[1m--strip-components\033[0m \033[1mtar\033[0m option to remove the top-level package" << ::std::endl
+ << "directory (the same can be achieved for \033[1mzip\033[0m archives by using \033[1mbsdtar\033[0m on" << ::std::endl
+ << "Windows). For example, to unpack the package contents so that they end up in" << ::std::endl
+ << "\033[1m/usr/local/\033[0m:" << ::std::endl
+ << ::std::endl
+ << "sudo tar -xf libhello-1.2.3-x86_64-debian11-gcc12.tar.xz \\" << ::std::endl
+ << " -C / --strip-components=1" << ::std::endl
+ << ::std::endl
+ << "If you expect the binary package to be unpacked into a directory other than its" << ::std::endl
+ << "original installation directory (\033[1m--archive-install-root\033[0m), then it's recommended" << ::std::endl
+ << "to make it relocatable by specifying the \033[1mconfig.install.relocatable=true\033[0m" << ::std::endl
+ << "configuration variable. For example:" << ::std::endl
+ << ::std::endl
+ << "bpkg bindist \\" << ::std::endl
+ << " ... \\" << ::std::endl
+ << " config.install.relocatable=true \\" << ::std::endl
+ << " libhello" << ::std::endl
+ << ::std::endl
+ << "Note that not all source packages support relocatable installation (see" << ::std::endl
+ << "Rolocatable Installation (b#install-reloc) for details)." << ::std::endl
+ << ::std::endl
+ << "Another mechanism that can useful when generating archive packages is the" << ::std::endl
+ << "ability to filter the files being installed. This, for example, can be used to" << ::std::endl
+ << "create binary packages that don't contain any development-related files. See" << ::std::endl
+ << "Installation Filtering (b#install-filter) for details. See also the" << ::std::endl
+ << "\033[1m--archive-split\033[0m option." << ::std::endl
+ << ::std::endl
+ << "The installation archive package can be generated for a target other than the" << ::std::endl
+ << "host by specifying the target triplet with the \033[1m--architecture\033[0m option. In this" << ::std::endl
+ << "case the \033[1mbpkg\033[0m configuration is assumed to be appropriately configured for" << ::std::endl
+ << "cross-compiling to the specified target. You will also need to explicitly" << ::std::endl
+ << "specify the \033[1m--archive-install-root\033[0m option (or \033[1m--archive-install-config\033[0m) as well" << ::std::endl
+ << "as the \033[1m--os-release-id\033[0m option (and likely want to specify other \033[1m--os-release-*\033[0m" << ::std::endl
+ << "options). For example, for cross-compiling from Linux to Windows using the" << ::std::endl
+ << "MinGW GCC toolchain:" << ::std::endl
+ << ::std::endl
+ << "bpkg bindist \\" << ::std::endl
+ << " --distribution=archive \\" << ::std::endl
+ << " --architecture=x86_64-w64-mingw32 \\" << ::std::endl
+ << " --os-release-id=windows \\" << ::std::endl
+ << " --os-release-name=Windows \\" << ::std::endl
+ << " --os-release-version-id=10 \\" << ::std::endl
+ << " --archive-install-root / \\" << ::std::endl
+ << " --archive-lang cc=mingw_w64_gcc12 \\" << ::std::endl
+ << " ..." << ::std::endl;
+
+ os << std::endl
+ << "\033[1mPKG-BINDIST ARCHIVE OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--archive-prepare-only\033[0m Prepare all the package contents but do not create" << ::std::endl
+ << " the binary package archive, printing its directory" << ::std::endl
+ << " instead unless requested to be quiet. Implies" << ::std::endl
+ << " \033[1m--keep-output\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--archive-type\033[0m \033[4mext\033[0m Archive type to create specified as a file extension," << ::std::endl
+ << " for example, \033[1mtar.xz\033[0m, \033[1mtar.gz\033[0m, \033[1mtar\033[0m, \033[1mzip\033[0m. Repeat this" << ::std::endl
+ << " option to generate multiple archive types. If" << ::std::endl
+ << " unspecified, then a default type appropriate for the" << ::std::endl
+ << " target operating system is used, currently \033[1mzip\033[0m for" << ::std::endl
+ << " Windows and \033[1mtar.xz\033[0m for POSIX. Note, however, that" << ::std::endl
+ << " these defaults may change in the future." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--archive-lang\033[0m \033[4mln\033[0m=\033[4mrt\033[0m Map interface language name \033[4mln\033[0m to runtime id \033[4mrt\033[0m. If" << ::std::endl
+ << " no mapping is found for an interface language in this" << ::std::endl
+ << " map, then fallback to the \033[1m--archive-lang-impl\033[0m map. If" << ::std::endl
+ << " still no mapping is found, then fail. If the" << ::std::endl
+ << " information about an interface language is" << ::std::endl
+ << " unimportant and should be ignored, then empty runtime" << ::std::endl
+ << " id can be specified. Note that the mapping specified" << ::std::endl
+ << " with this option is only considered if the package" << ::std::endl
+ << " type is a library (for other package types all" << ::std::endl
+ << " languages used are implementation). Note also that" << ::std::endl
+ << " multiple runtime ids specified for the same language" << ::std::endl
+ << " are combined except for an empty id, which is treated" << ::std::endl
+ << " as a request to clear previous entries." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--archive-lang-impl\033[0m \033[4mln\033[0m=\033[4mrt\033[0m Map implementation language name \033[4mln\033[0m to runtime id \033[4mrt\033[0m." << ::std::endl
+ << " If no mapping is found for an implementation language" << ::std::endl
+ << " in this map, then assume the information about this" << ::std::endl
+ << " implementation language is unimportant and ignore it" << ::std::endl
+ << " (examples of such cases include static linking as" << ::std::endl
+ << " well as a language runtime that is always present)." << ::std::endl
+ << " See \033[1m--archive-lang\033[0m for background." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--archive-no-cpu\033[0m Assume the package is CPU architecture-independent" << ::std::endl
+ << " and omit it from the binary package directory name" << ::std::endl
+ << " and archive file base." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--archive-no-os\033[0m Assume the package is operating system-independent" << ::std::endl
+ << " and omit it from the binary package directory name" << ::std::endl
+ << " and archive file base." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--archive-build-meta\033[0m \033[4mdata\033[0m Alternative or additional build metadata to include" << ::std::endl
+ << " after the version in the binary package directory and" << ::std::endl
+ << " file names. If the specified value starts/ends with" << ::std::endl
+ << " \033[1m+\033[0m then the value (with \033[1m+\033[0m removed) is added" << ::std::endl
+ << " after/before the default metadata. Otherwise it is" << ::std::endl
+ << " used as is instead of the default metadata. If empty" << ::std::endl
+ << " value is specified, then no build metadata is" << ::std::endl
+ << " included." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--archive-install-root\033[0m \033[4md\033[0m Alternative installation root directory. The default" << ::std::endl
+ << " is \033[1m/usr/local/\033[0m on POSIX and \033[1mC:\\\033[0m\033[4mproject\033[0m\033[1m\\\033[0m\033[0m on Windows," << ::std::endl
+ << " where \033[4mproject\033[0m is the \033[1mproject\033[0m" << ::std::endl
+ << " (bpkg#manifest-package-project) package manifest" << ::std::endl
+ << " value." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--archive-install-config\033[0m Use the installation directory layout" << ::std::endl
+ << " (\033[1mconfig.install.*\033[0m variables) as configured instead of" << ::std::endl
+ << " overriding them with defaults appropriate for the" << ::std::endl
+ << " target operating system. Note that this includes" << ::std::endl
+ << " \033[1mconfig.install.private\033[0m and \033[1mconfig.bin.rpath\033[0m if needed" << ::std::endl
+ << " for a private installation. Note also that the" << ::std::endl
+ << " \033[1mconfig.install.root\033[0m value is still overridden with" << ::std::endl
+ << " the \033[1m--archive-install-root\033[0m option value if specified." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--archive-split\033[0m \033[4mkey\033[0m=\033[4mfilt\033[0m Split the installation into multiple binary packages." << ::std::endl
+ << " Specifically, for each \033[4mkey\033[0m=\033[4mfilt\033[0m pair, perform the" << ::std::endl
+ << " \033[1minstall\033[0m operation with \033[1mconfig.install.filter=\033[0m\033[4mfilt\033[0m\033[0m and" << ::std::endl
+ << " package the resulting files as" << ::std::endl
+ << " \033[4mpackage-key-version-build_metadata\033[0m omitting the \033[4m-key\033[0m" << ::std::endl
+ << " part if \033[4mkey\033[0m is empty. Note that wildcard patterns in" << ::std::endl
+ << " \033[4mfilt\033[0m must be quoted. See Installation Filtering" << ::std::endl
+ << " (b#install-filter) for background." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_bindist_archive_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_bindist_archive_options_map;
+
+ static _cli_pkg_bindist_archive_options_map _cli_pkg_bindist_archive_options_map_;
+
+ struct _cli_pkg_bindist_archive_options_map_init
+ {
+ _cli_pkg_bindist_archive_options_map_init ()
+ {
+ _cli_pkg_bindist_archive_options_map_["--archive-prepare-only"] =
+ &::bpkg::cli::thunk< pkg_bindist_archive_options, &pkg_bindist_archive_options::archive_prepare_only_ >;
+ _cli_pkg_bindist_archive_options_map_["--archive-type"] =
+ &::bpkg::cli::thunk< pkg_bindist_archive_options, strings, &pkg_bindist_archive_options::archive_type_,
+ &pkg_bindist_archive_options::archive_type_specified_ >;
+ _cli_pkg_bindist_archive_options_map_["--archive-lang"] =
+ &::bpkg::cli::thunk< pkg_bindist_archive_options, std::multimap<string, string>, &pkg_bindist_archive_options::archive_lang_,
+ &pkg_bindist_archive_options::archive_lang_specified_ >;
+ _cli_pkg_bindist_archive_options_map_["--archive-lang-impl"] =
+ &::bpkg::cli::thunk< pkg_bindist_archive_options, std::multimap<string, string>, &pkg_bindist_archive_options::archive_lang_impl_,
+ &pkg_bindist_archive_options::archive_lang_impl_specified_ >;
+ _cli_pkg_bindist_archive_options_map_["--archive-no-cpu"] =
+ &::bpkg::cli::thunk< pkg_bindist_archive_options, &pkg_bindist_archive_options::archive_no_cpu_ >;
+ _cli_pkg_bindist_archive_options_map_["--archive-no-os"] =
+ &::bpkg::cli::thunk< pkg_bindist_archive_options, &pkg_bindist_archive_options::archive_no_os_ >;
+ _cli_pkg_bindist_archive_options_map_["--archive-build-meta"] =
+ &::bpkg::cli::thunk< pkg_bindist_archive_options, string, &pkg_bindist_archive_options::archive_build_meta_,
+ &pkg_bindist_archive_options::archive_build_meta_specified_ >;
+ _cli_pkg_bindist_archive_options_map_["--archive-install-root"] =
+ &::bpkg::cli::thunk< pkg_bindist_archive_options, dir_path, &pkg_bindist_archive_options::archive_install_root_,
+ &pkg_bindist_archive_options::archive_install_root_specified_ >;
+ _cli_pkg_bindist_archive_options_map_["--archive-install-config"] =
+ &::bpkg::cli::thunk< pkg_bindist_archive_options, &pkg_bindist_archive_options::archive_install_config_ >;
+ _cli_pkg_bindist_archive_options_map_["--archive-split"] =
+ &::bpkg::cli::thunk< pkg_bindist_archive_options, std::map<string, string>, &pkg_bindist_archive_options::archive_split_,
+ &pkg_bindist_archive_options::archive_split_specified_ >;
+ }
+ };
+
+ static _cli_pkg_bindist_archive_options_map_init _cli_pkg_bindist_archive_options_map_init_;
+
+ bool pkg_bindist_archive_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_bindist_archive_options_map::const_iterator i (_cli_pkg_bindist_archive_options_map_.find (o));
+
+ if (i != _cli_pkg_bindist_archive_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool pkg_bindist_archive_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+
+ // pkg_bindist_options
+ //
+
+ pkg_bindist_options::
+ pkg_bindist_options ()
+ {
+ }
+
+ bool pkg_bindist_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_bindist_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_bindist_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_bindist_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_bindist_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_bindist_options::
+ merge (const pkg_bindist_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // pkg_bindist_common_options base
+ //
+ ::bpkg::pkg_bindist_common_options::merge (a);
+
+ // pkg_bindist_debian_options base
+ //
+ ::bpkg::pkg_bindist_debian_options::merge (a);
+
+ // pkg_bindist_fedora_options base
+ //
+ ::bpkg::pkg_bindist_fedora_options::merge (a);
+
+ // pkg_bindist_archive_options base
+ //
+ ::bpkg::pkg_bindist_archive_options::merge (a);
+ }
+
+ ::bpkg::cli::usage_para pkg_bindist_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_bindist_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_bindist_options_map;
+
+ static _cli_pkg_bindist_options_map _cli_pkg_bindist_options_map_;
+
+ struct _cli_pkg_bindist_options_map_init
+ {
+ _cli_pkg_bindist_options_map_init ()
+ {
+ }
+ };
+
+ static _cli_pkg_bindist_options_map_init _cli_pkg_bindist_options_map_init_;
+
+ bool pkg_bindist_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_bindist_options_map::const_iterator i (_cli_pkg_bindist_options_map_.find (o));
+
+ if (i != _cli_pkg_bindist_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // pkg_bindist_common_options base
+ //
+ if (::bpkg::pkg_bindist_common_options::_parse (o, s))
+ return true;
+
+ // pkg_bindist_debian_options base
+ //
+ if (::bpkg::pkg_bindist_debian_options::_parse (o, s))
+ return true;
+
+ // pkg_bindist_fedora_options base
+ //
+ if (::bpkg::pkg_bindist_fedora_options::_parse (o, s))
+ return true;
+
+ // pkg_bindist_archive_options base
+ //
+ if (::bpkg::pkg_bindist_archive_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_bindist_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_bindist_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-bindist\033[0m|\033[1mbindist\033[0m [\033[1m--output-root\033[0m|\033[1m-o\033[0m \033[4mdir\033[0m] [\033[4moptions\033[0m] [\033[4mvars\033[0m] \033[4mpkg\033[0m...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-bindist\033[0m command generates a binary distribution package for the" << ::std::endl
+ << "specified package. If additional packages are specified, then they are bundled" << ::std::endl
+ << "in the same distribution package. All the specified packages must have been" << ::std::endl
+ << "previously configured with \033[1mbpkg-pkg-build(1)\033[0m or \033[1mbpkg-pkg-configure(1)\033[0m. For some" << ::std::endl
+ << "system package managers a directory for intermediate files and subdirectories" << ::std::endl
+ << "as well as the resulting binary package may have to be specified explicitly" << ::std::endl
+ << "with the \033[1m--output-root\033[0m|\033[1m-o\033[0m\033[0m option." << ::std::endl
+ << ::std::endl
+ << "Underneath, this command roughly performs the following steps: First it" << ::std::endl
+ << "installs the specified packages similar to the \033[1mbpkg-pkg-install(1)\033[0m command" << ::std::endl
+ << "except that it may override the installation locations (via the" << ::std::endl
+ << "\033[1mconfig.install.*\033[0m variables) to match the distribution's layout. Then it" << ::std::endl
+ << "generates any necessary distribution package metadata files based on the" << ::std::endl
+ << "information from the package \033[1mmanifest\033[0m files. Finally, it invokes the" << ::std::endl
+ << "distribution-specific command to produce the binary package. Unless overridden" << ::std::endl
+ << "with the \033[1m--architecture\033[0m and \033[1m--distribution\033[0m options, the binary package is" << ::std::endl
+ << "generated for the host architecture using the host's standard system package" << ::std::endl
+ << "manager. Additional command line variables (\033[4mvars\033[0m, normally \033[1mconfig.*\033[0m) can be" << ::std::endl
+ << "passed to the build system during the installation step. See the following" << ::std::endl
+ << "distribution-specific description sections below for details and invocation" << ::std::endl
+ << "examples:" << ::std::endl
+ << ::std::endl
+ << "DEBIAN DESCRIPTION" << ::std::endl
+ << ::std::endl
+ << "FEDORA DESCRIPTION" << ::std::endl
+ << ::std::endl
+ << "ARCHIVE DESCRIPTION" << ::std::endl
+ << ::std::endl
+ << "The specified packages may have dependencies and the default behavior is to not" << ::std::endl
+ << "bundle them but rather to specify them as dependencies in the corresponding" << ::std::endl
+ << "distribution package metadata, if applicable. This default behavior can be" << ::std::endl
+ << "overridden with the \033[1m--recursive\033[0m option (see the option description for the" << ::std::endl
+ << "available modes). Note, however, that dependencies that are satisfied by system" << ::std::endl
+ << "packages are always specified as dependencies in the distribution package" << ::std::endl
+ << "metadata (if applicable)." << ::std::endl;
+
+ p = ::bpkg::pkg_bindist_common_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ p = ::bpkg::pkg_bindist_debian_options::print_usage (os, p);
+
+ p = ::bpkg::pkg_bindist_fedora_options::print_usage (os, p);
+
+ p = ::bpkg::pkg_bindist_archive_options::print_usage (os, p);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSTRUCTURED RESULT\033[0m" << ::std::endl
+ << ::std::endl
+ << "Instead of printing to \033[1mstderr\033[0m the list of generated binary packages in a format" << ::std::endl
+ << "more suitable for human consumption, the \033[1mpkg-bindist\033[0m command can be instructed" << ::std::endl
+ << "to write it to \033[1mstdout\033[0m in a machine-readable form by specifying the" << ::std::endl
+ << "\033[1m--structured-result\033[0m option. Currently, the only recognized format value for" << ::std::endl
+ << "this option is \033[1mjson\033[0m with the output being a JSON object that is a serialized" << ::std::endl
+ << "representation of the following C++ struct \033[1mbindist_result\033[0m:" << ::std::endl
+ << ::std::endl
+ << "struct os_release" << ::std::endl
+ << "{" << ::std::endl
+ << " string name_id; // ID" << ::std::endl
+ << " vector<string> like_ids; // ID_LIKE" << ::std::endl
+ << " optional<string> version_id; // VERSION_ID" << ::std::endl
+ << " optional<string> variant_id; // VARIANT_ID" << ::std::endl
+ << ::std::endl
+ << " optional<string> name; // NAME" << ::std::endl
+ << " optional<string> version_codename; // VERSION_CODENAME" << ::std::endl
+ << " optional<string> variant; // VARIANT" << ::std::endl
+ << "};" << ::std::endl
+ << ::std::endl
+ << "struct file" << ::std::endl
+ << "{" << ::std::endl
+ << " string type;" << ::std::endl
+ << " string path;" << ::std::endl
+ << " optional<string> system_name;" << ::std::endl
+ << "};" << ::std::endl
+ << ::std::endl
+ << "struct package" << ::std::endl
+ << "{" << ::std::endl
+ << " string name;" << ::std::endl
+ << " string version;" << ::std::endl
+ << " optional<string> system_version;" << ::std::endl
+ << " vector<file> files;" << ::std::endl
+ << "};" << ::std::endl
+ << ::std::endl
+ << "struct bindist_result" << ::std::endl
+ << "{" << ::std::endl
+ << " string distribution; // --distribution or auto-detected" << ::std::endl
+ << " string architecture; // --architecture or auto-detected" << ::std::endl
+ << " os_release os_release; // --os-release-* or auto-detected" << ::std::endl
+ << " optional<string> recursive; // --recursive" << ::std::endl
+ << " bool private; // --private" << ::std::endl
+ << " bool dependent_config; // See --allow-dependent-config" << ::std::endl
+ << ::std::endl
+ << " package package;" << ::std::endl
+ << " vector<package> dependencies; // Only in --recursive=separate" << ::std::endl
+ << "};" << ::std::endl
+ << ::std::endl
+ << "For example:" << ::std::endl
+ << ::std::endl
+ << "{" << ::std::endl
+ << " \"distribution\": \"debian\"," << ::std::endl
+ << " \"architecture\": \"amd64\"," << ::std::endl
+ << " \"os_release\": {" << ::std::endl
+ << " \"name_id\": \"debian\"," << ::std::endl
+ << " \"version_id\": \"11\"," << ::std::endl
+ << " \"name\": \"Debian GNU/Linux\"" << ::std::endl
+ << " }," << ::std::endl
+ << " \"package\": {" << ::std::endl
+ << " \"name\": \"libfoo\"," << ::std::endl
+ << " \"version\": \"2.5.0-b.23\"," << ::std::endl
+ << " \"system_version\": \"2.5.0~b.23-0~debian11\"," << ::std::endl
+ << " \"files\": [" << ::std::endl
+ << " {" << ::std::endl
+ << " \"type\": \"main.deb\"," << ::std::endl
+ << " \"path\": \"/tmp/libfoo_2.5.0~b.23-0~debian11_amd64.deb\"," << ::std::endl
+ << " \"system_name\": \"libfoo\"" << ::std::endl
+ << " }," << ::std::endl
+ << " {" << ::std::endl
+ << " \"type\": \"dev.deb\"," << ::std::endl
+ << " \"path\": \"/tmp/libfoo-dev_2.5.0~b.23-0~debian11_amd64.deb\"," << ::std::endl
+ << " \"system_name\": \"libfoo-dev\"" << ::std::endl
+ << " }," << ::std::endl
+ << " ..." << ::std::endl
+ << " ]" << ::std::endl
+ << " }" << ::std::endl
+ << "}" << ::std::endl
+ << ::std::endl
+ << "See the JSON OUTPUT section in \033[1mbpkg-common-options(1)\033[0m for details on the" << ::std::endl
+ << "overall properties of this format and the semantics of the \033[1mstruct\033[0m" << ::std::endl
+ << "serialization." << ::std::endl
+ << ::std::endl
+ << "The \033[1mfile::type\033[0m member is a distribution-specific value that classifies the" << ::std::endl
+ << "file. For the \033[1mdebian\033[0m distribution the possible values are \033[1mmain.deb\033[0m, \033[1mdev.deb\033[0m," << ::std::endl
+ << "\033[1mdoc.deb\033[0m, \033[1mcommon.deb\033[0m, \033[1mdbgsym.deb\033[0m, \033[1mchanges\033[0m (\033[1m.changes\033[0m file), and \033[1mbuildid\033[0m" << ::std::endl
+ << "(\033[1m.buildid\033[0m file); see Debian Package Mapping for Production" << ::std::endl
+ << "(bpkg#bindist-mapping-debian-produce) for background. For the \033[1mfedora\033[0m" << ::std::endl
+ << "distribution the possible values are \033[1mmain.rpm\033[0m, \033[1mdevel.rpm\033[0m, \033[1mstatic.rpm\033[0m, \033[1mdoc.rpm\033[0m," << ::std::endl
+ << "\033[1mcommon.rpm\033[0m, and \033[1mdebuginfo.rpm\033[0m; see Fedora Package Mapping for Production" << ::std::endl
+ << "(bpkg#bindist-mapping-fedora-produce) for background. For the \033[1marchive\033[0m" << ::std::endl
+ << "distribution this is the archive type (\033[1m--archive-type\033[0m), for example, \033[1mtar.xz\033[0m or" << ::std::endl
+ << "\033[1mzip\033[0m, potentially prefixed with \033[4mkey\033[0m if the \033[1m--archive-split\033[0m functionality is" << ::std::endl
+ << "used, for example, \033[1mdev.tar.xz\033[0m." << ::std::endl
+ << ::std::endl
+ << "The \033[1mpackage::system_version\033[0m and/or \033[1mfile::system_name\033[0m members are absent if not" << ::std::endl
+ << "applicable to the distribution. The \033[1mfile::system_name\033[0m member is also absent if" << ::std::endl
+ << "the file is not a binary package (for example, \033[1m.changes\033[0m and \033[1m.buildid\033[0m files in" << ::std::endl
+ << "the \033[1mdebian\033[0m distribution)." << ::std::endl;
+
+ p = ::bpkg::pkg_bindist_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-bindist\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-bindist.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-bindist\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-bindist-options.hxx b/bpkg/pkg-bindist-options.hxx
new file mode 100644
index 0000000..97b6a3b
--- /dev/null
+++ b/bpkg/pkg-bindist-options.hxx
@@ -0,0 +1,742 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_BINDIST_OPTIONS_HXX
+#define BPKG_PKG_BINDIST_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <map>
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_bindist_common_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_bindist_common_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_bindist_common_options&);
+
+ // Option accessors.
+ //
+ const string&
+ distribution () const;
+
+ bool
+ distribution_specified () const;
+
+ const string&
+ architecture () const;
+
+ bool
+ architecture_specified () const;
+
+ const string&
+ recursive () const;
+
+ bool
+ recursive_specified () const;
+
+ const bool&
+ private_ () const;
+
+ const dir_path&
+ output_root () const;
+
+ bool
+ output_root_specified () const;
+
+ const bool&
+ wipe_output () const;
+
+ const bool&
+ keep_output () const;
+
+ const bool&
+ allow_dependent_config () const;
+
+ const string&
+ os_release_id () const;
+
+ bool
+ os_release_id_specified () const;
+
+ const string&
+ os_release_version_id () const;
+
+ bool
+ os_release_version_id_specified () const;
+
+ const string&
+ os_release_name () const;
+
+ bool
+ os_release_name_specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ string distribution_;
+ bool distribution_specified_;
+ string architecture_;
+ bool architecture_specified_;
+ string recursive_;
+ bool recursive_specified_;
+ bool private__;
+ dir_path output_root_;
+ bool output_root_specified_;
+ bool wipe_output_;
+ bool keep_output_;
+ bool allow_dependent_config_;
+ string os_release_id_;
+ bool os_release_id_specified_;
+ string os_release_version_id_;
+ bool os_release_version_id_specified_;
+ string os_release_name_;
+ bool os_release_name_specified_;
+ };
+
+ class pkg_bindist_debian_options
+ {
+ public:
+ pkg_bindist_debian_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_bindist_debian_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ debian_prepare_only () const;
+
+ const string&
+ debian_buildflags () const;
+
+ bool
+ debian_buildflags_specified () const;
+
+ const strings&
+ debian_maint_option () const;
+
+ bool
+ debian_maint_option_specified () const;
+
+ const strings&
+ debian_build_option () const;
+
+ bool
+ debian_build_option_specified () const;
+
+ const string&
+ debian_build_meta () const;
+
+ bool
+ debian_build_meta_specified () const;
+
+ const string&
+ debian_section () const;
+
+ bool
+ debian_section_specified () const;
+
+ const string&
+ debian_priority () const;
+
+ bool
+ debian_priority_specified () const;
+
+ const string&
+ debian_maintainer () const;
+
+ bool
+ debian_maintainer_specified () const;
+
+ const string&
+ debian_architecture () const;
+
+ bool
+ debian_architecture_specified () const;
+
+ const string&
+ debian_main_langdep () const;
+
+ bool
+ debian_main_langdep_specified () const;
+
+ const string&
+ debian_dev_langdep () const;
+
+ bool
+ debian_dev_langdep_specified () const;
+
+ const string&
+ debian_main_extradep () const;
+
+ bool
+ debian_main_extradep_specified () const;
+
+ const string&
+ debian_dev_extradep () const;
+
+ bool
+ debian_dev_extradep_specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool debian_prepare_only_;
+ string debian_buildflags_;
+ bool debian_buildflags_specified_;
+ strings debian_maint_option_;
+ bool debian_maint_option_specified_;
+ strings debian_build_option_;
+ bool debian_build_option_specified_;
+ string debian_build_meta_;
+ bool debian_build_meta_specified_;
+ string debian_section_;
+ bool debian_section_specified_;
+ string debian_priority_;
+ bool debian_priority_specified_;
+ string debian_maintainer_;
+ bool debian_maintainer_specified_;
+ string debian_architecture_;
+ bool debian_architecture_specified_;
+ string debian_main_langdep_;
+ bool debian_main_langdep_specified_;
+ string debian_dev_langdep_;
+ bool debian_dev_langdep_specified_;
+ string debian_main_extradep_;
+ bool debian_main_extradep_specified_;
+ string debian_dev_extradep_;
+ bool debian_dev_extradep_specified_;
+ };
+
+ class pkg_bindist_fedora_options
+ {
+ public:
+ pkg_bindist_fedora_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_bindist_fedora_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ fedora_prepare_only () const;
+
+ const string&
+ fedora_buildflags () const;
+
+ bool
+ fedora_buildflags_specified () const;
+
+ const strings&
+ fedora_build_option () const;
+
+ bool
+ fedora_build_option_specified () const;
+
+ const strings&
+ fedora_query_option () const;
+
+ bool
+ fedora_query_option_specified () const;
+
+ const string&
+ fedora_dist_tag () const;
+
+ bool
+ fedora_dist_tag_specified () const;
+
+ const string&
+ fedora_packager () const;
+
+ bool
+ fedora_packager_specified () const;
+
+ const string&
+ fedora_build_arch () const;
+
+ bool
+ fedora_build_arch_specified () const;
+
+ const strings&
+ fedora_main_langreq () const;
+
+ bool
+ fedora_main_langreq_specified () const;
+
+ const strings&
+ fedora_devel_langreq () const;
+
+ bool
+ fedora_devel_langreq_specified () const;
+
+ const strings&
+ fedora_stat_langreq () const;
+
+ bool
+ fedora_stat_langreq_specified () const;
+
+ const strings&
+ fedora_main_extrareq () const;
+
+ bool
+ fedora_main_extrareq_specified () const;
+
+ const strings&
+ fedora_devel_extrareq () const;
+
+ bool
+ fedora_devel_extrareq_specified () const;
+
+ const strings&
+ fedora_stat_extrareq () const;
+
+ bool
+ fedora_stat_extrareq_specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool fedora_prepare_only_;
+ string fedora_buildflags_;
+ bool fedora_buildflags_specified_;
+ strings fedora_build_option_;
+ bool fedora_build_option_specified_;
+ strings fedora_query_option_;
+ bool fedora_query_option_specified_;
+ string fedora_dist_tag_;
+ bool fedora_dist_tag_specified_;
+ string fedora_packager_;
+ bool fedora_packager_specified_;
+ string fedora_build_arch_;
+ bool fedora_build_arch_specified_;
+ strings fedora_main_langreq_;
+ bool fedora_main_langreq_specified_;
+ strings fedora_devel_langreq_;
+ bool fedora_devel_langreq_specified_;
+ strings fedora_stat_langreq_;
+ bool fedora_stat_langreq_specified_;
+ strings fedora_main_extrareq_;
+ bool fedora_main_extrareq_specified_;
+ strings fedora_devel_extrareq_;
+ bool fedora_devel_extrareq_specified_;
+ strings fedora_stat_extrareq_;
+ bool fedora_stat_extrareq_specified_;
+ };
+
+ class pkg_bindist_archive_options
+ {
+ public:
+ pkg_bindist_archive_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_bindist_archive_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ archive_prepare_only () const;
+
+ const strings&
+ archive_type () const;
+
+ bool
+ archive_type_specified () const;
+
+ const std::multimap<string, string>&
+ archive_lang () const;
+
+ bool
+ archive_lang_specified () const;
+
+ const std::multimap<string, string>&
+ archive_lang_impl () const;
+
+ bool
+ archive_lang_impl_specified () const;
+
+ const bool&
+ archive_no_cpu () const;
+
+ const bool&
+ archive_no_os () const;
+
+ const string&
+ archive_build_meta () const;
+
+ bool
+ archive_build_meta_specified () const;
+
+ const dir_path&
+ archive_install_root () const;
+
+ bool
+ archive_install_root_specified () const;
+
+ const bool&
+ archive_install_config () const;
+
+ const std::map<string, string>&
+ archive_split () const;
+
+ bool
+ archive_split_specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool archive_prepare_only_;
+ strings archive_type_;
+ bool archive_type_specified_;
+ std::multimap<string, string> archive_lang_;
+ bool archive_lang_specified_;
+ std::multimap<string, string> archive_lang_impl_;
+ bool archive_lang_impl_specified_;
+ bool archive_no_cpu_;
+ bool archive_no_os_;
+ string archive_build_meta_;
+ bool archive_build_meta_specified_;
+ dir_path archive_install_root_;
+ bool archive_install_root_specified_;
+ bool archive_install_config_;
+ std::map<string, string> archive_split_;
+ bool archive_split_specified_;
+ };
+
+ class pkg_bindist_options: public ::bpkg::pkg_bindist_common_options,
+ public ::bpkg::pkg_bindist_debian_options,
+ public ::bpkg::pkg_bindist_fedora_options,
+ public ::bpkg::pkg_bindist_archive_options
+ {
+ public:
+ pkg_bindist_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_bindist_options&);
+
+ // Option accessors.
+ //
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_bindist_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-bindist-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_BINDIST_OPTIONS_HXX
diff --git a/bpkg/pkg-bindist-options.ixx b/bpkg/pkg-bindist-options.ixx
new file mode 100644
index 0000000..3a5ef7c
--- /dev/null
+++ b/bpkg/pkg-bindist-options.ixx
@@ -0,0 +1,537 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_bindist_common_options
+ //
+
+ inline const string& pkg_bindist_common_options::
+ distribution () const
+ {
+ return this->distribution_;
+ }
+
+ inline bool pkg_bindist_common_options::
+ distribution_specified () const
+ {
+ return this->distribution_specified_;
+ }
+
+ inline const string& pkg_bindist_common_options::
+ architecture () const
+ {
+ return this->architecture_;
+ }
+
+ inline bool pkg_bindist_common_options::
+ architecture_specified () const
+ {
+ return this->architecture_specified_;
+ }
+
+ inline const string& pkg_bindist_common_options::
+ recursive () const
+ {
+ return this->recursive_;
+ }
+
+ inline bool pkg_bindist_common_options::
+ recursive_specified () const
+ {
+ return this->recursive_specified_;
+ }
+
+ inline const bool& pkg_bindist_common_options::
+ private_ () const
+ {
+ return this->private__;
+ }
+
+ inline const dir_path& pkg_bindist_common_options::
+ output_root () const
+ {
+ return this->output_root_;
+ }
+
+ inline bool pkg_bindist_common_options::
+ output_root_specified () const
+ {
+ return this->output_root_specified_;
+ }
+
+ inline const bool& pkg_bindist_common_options::
+ wipe_output () const
+ {
+ return this->wipe_output_;
+ }
+
+ inline const bool& pkg_bindist_common_options::
+ keep_output () const
+ {
+ return this->keep_output_;
+ }
+
+ inline const bool& pkg_bindist_common_options::
+ allow_dependent_config () const
+ {
+ return this->allow_dependent_config_;
+ }
+
+ inline const string& pkg_bindist_common_options::
+ os_release_id () const
+ {
+ return this->os_release_id_;
+ }
+
+ inline bool pkg_bindist_common_options::
+ os_release_id_specified () const
+ {
+ return this->os_release_id_specified_;
+ }
+
+ inline const string& pkg_bindist_common_options::
+ os_release_version_id () const
+ {
+ return this->os_release_version_id_;
+ }
+
+ inline bool pkg_bindist_common_options::
+ os_release_version_id_specified () const
+ {
+ return this->os_release_version_id_specified_;
+ }
+
+ inline const string& pkg_bindist_common_options::
+ os_release_name () const
+ {
+ return this->os_release_name_;
+ }
+
+ inline bool pkg_bindist_common_options::
+ os_release_name_specified () const
+ {
+ return this->os_release_name_specified_;
+ }
+
+ // pkg_bindist_debian_options
+ //
+
+ inline const bool& pkg_bindist_debian_options::
+ debian_prepare_only () const
+ {
+ return this->debian_prepare_only_;
+ }
+
+ inline const string& pkg_bindist_debian_options::
+ debian_buildflags () const
+ {
+ return this->debian_buildflags_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_buildflags_specified () const
+ {
+ return this->debian_buildflags_specified_;
+ }
+
+ inline const strings& pkg_bindist_debian_options::
+ debian_maint_option () const
+ {
+ return this->debian_maint_option_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_maint_option_specified () const
+ {
+ return this->debian_maint_option_specified_;
+ }
+
+ inline const strings& pkg_bindist_debian_options::
+ debian_build_option () const
+ {
+ return this->debian_build_option_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_build_option_specified () const
+ {
+ return this->debian_build_option_specified_;
+ }
+
+ inline const string& pkg_bindist_debian_options::
+ debian_build_meta () const
+ {
+ return this->debian_build_meta_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_build_meta_specified () const
+ {
+ return this->debian_build_meta_specified_;
+ }
+
+ inline const string& pkg_bindist_debian_options::
+ debian_section () const
+ {
+ return this->debian_section_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_section_specified () const
+ {
+ return this->debian_section_specified_;
+ }
+
+ inline const string& pkg_bindist_debian_options::
+ debian_priority () const
+ {
+ return this->debian_priority_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_priority_specified () const
+ {
+ return this->debian_priority_specified_;
+ }
+
+ inline const string& pkg_bindist_debian_options::
+ debian_maintainer () const
+ {
+ return this->debian_maintainer_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_maintainer_specified () const
+ {
+ return this->debian_maintainer_specified_;
+ }
+
+ inline const string& pkg_bindist_debian_options::
+ debian_architecture () const
+ {
+ return this->debian_architecture_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_architecture_specified () const
+ {
+ return this->debian_architecture_specified_;
+ }
+
+ inline const string& pkg_bindist_debian_options::
+ debian_main_langdep () const
+ {
+ return this->debian_main_langdep_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_main_langdep_specified () const
+ {
+ return this->debian_main_langdep_specified_;
+ }
+
+ inline const string& pkg_bindist_debian_options::
+ debian_dev_langdep () const
+ {
+ return this->debian_dev_langdep_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_dev_langdep_specified () const
+ {
+ return this->debian_dev_langdep_specified_;
+ }
+
+ inline const string& pkg_bindist_debian_options::
+ debian_main_extradep () const
+ {
+ return this->debian_main_extradep_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_main_extradep_specified () const
+ {
+ return this->debian_main_extradep_specified_;
+ }
+
+ inline const string& pkg_bindist_debian_options::
+ debian_dev_extradep () const
+ {
+ return this->debian_dev_extradep_;
+ }
+
+ inline bool pkg_bindist_debian_options::
+ debian_dev_extradep_specified () const
+ {
+ return this->debian_dev_extradep_specified_;
+ }
+
+ // pkg_bindist_fedora_options
+ //
+
+ inline const bool& pkg_bindist_fedora_options::
+ fedora_prepare_only () const
+ {
+ return this->fedora_prepare_only_;
+ }
+
+ inline const string& pkg_bindist_fedora_options::
+ fedora_buildflags () const
+ {
+ return this->fedora_buildflags_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_buildflags_specified () const
+ {
+ return this->fedora_buildflags_specified_;
+ }
+
+ inline const strings& pkg_bindist_fedora_options::
+ fedora_build_option () const
+ {
+ return this->fedora_build_option_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_build_option_specified () const
+ {
+ return this->fedora_build_option_specified_;
+ }
+
+ inline const strings& pkg_bindist_fedora_options::
+ fedora_query_option () const
+ {
+ return this->fedora_query_option_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_query_option_specified () const
+ {
+ return this->fedora_query_option_specified_;
+ }
+
+ inline const string& pkg_bindist_fedora_options::
+ fedora_dist_tag () const
+ {
+ return this->fedora_dist_tag_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_dist_tag_specified () const
+ {
+ return this->fedora_dist_tag_specified_;
+ }
+
+ inline const string& pkg_bindist_fedora_options::
+ fedora_packager () const
+ {
+ return this->fedora_packager_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_packager_specified () const
+ {
+ return this->fedora_packager_specified_;
+ }
+
+ inline const string& pkg_bindist_fedora_options::
+ fedora_build_arch () const
+ {
+ return this->fedora_build_arch_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_build_arch_specified () const
+ {
+ return this->fedora_build_arch_specified_;
+ }
+
+ inline const strings& pkg_bindist_fedora_options::
+ fedora_main_langreq () const
+ {
+ return this->fedora_main_langreq_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_main_langreq_specified () const
+ {
+ return this->fedora_main_langreq_specified_;
+ }
+
+ inline const strings& pkg_bindist_fedora_options::
+ fedora_devel_langreq () const
+ {
+ return this->fedora_devel_langreq_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_devel_langreq_specified () const
+ {
+ return this->fedora_devel_langreq_specified_;
+ }
+
+ inline const strings& pkg_bindist_fedora_options::
+ fedora_stat_langreq () const
+ {
+ return this->fedora_stat_langreq_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_stat_langreq_specified () const
+ {
+ return this->fedora_stat_langreq_specified_;
+ }
+
+ inline const strings& pkg_bindist_fedora_options::
+ fedora_main_extrareq () const
+ {
+ return this->fedora_main_extrareq_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_main_extrareq_specified () const
+ {
+ return this->fedora_main_extrareq_specified_;
+ }
+
+ inline const strings& pkg_bindist_fedora_options::
+ fedora_devel_extrareq () const
+ {
+ return this->fedora_devel_extrareq_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_devel_extrareq_specified () const
+ {
+ return this->fedora_devel_extrareq_specified_;
+ }
+
+ inline const strings& pkg_bindist_fedora_options::
+ fedora_stat_extrareq () const
+ {
+ return this->fedora_stat_extrareq_;
+ }
+
+ inline bool pkg_bindist_fedora_options::
+ fedora_stat_extrareq_specified () const
+ {
+ return this->fedora_stat_extrareq_specified_;
+ }
+
+ // pkg_bindist_archive_options
+ //
+
+ inline const bool& pkg_bindist_archive_options::
+ archive_prepare_only () const
+ {
+ return this->archive_prepare_only_;
+ }
+
+ inline const strings& pkg_bindist_archive_options::
+ archive_type () const
+ {
+ return this->archive_type_;
+ }
+
+ inline bool pkg_bindist_archive_options::
+ archive_type_specified () const
+ {
+ return this->archive_type_specified_;
+ }
+
+ inline const std::multimap<string, string>& pkg_bindist_archive_options::
+ archive_lang () const
+ {
+ return this->archive_lang_;
+ }
+
+ inline bool pkg_bindist_archive_options::
+ archive_lang_specified () const
+ {
+ return this->archive_lang_specified_;
+ }
+
+ inline const std::multimap<string, string>& pkg_bindist_archive_options::
+ archive_lang_impl () const
+ {
+ return this->archive_lang_impl_;
+ }
+
+ inline bool pkg_bindist_archive_options::
+ archive_lang_impl_specified () const
+ {
+ return this->archive_lang_impl_specified_;
+ }
+
+ inline const bool& pkg_bindist_archive_options::
+ archive_no_cpu () const
+ {
+ return this->archive_no_cpu_;
+ }
+
+ inline const bool& pkg_bindist_archive_options::
+ archive_no_os () const
+ {
+ return this->archive_no_os_;
+ }
+
+ inline const string& pkg_bindist_archive_options::
+ archive_build_meta () const
+ {
+ return this->archive_build_meta_;
+ }
+
+ inline bool pkg_bindist_archive_options::
+ archive_build_meta_specified () const
+ {
+ return this->archive_build_meta_specified_;
+ }
+
+ inline const dir_path& pkg_bindist_archive_options::
+ archive_install_root () const
+ {
+ return this->archive_install_root_;
+ }
+
+ inline bool pkg_bindist_archive_options::
+ archive_install_root_specified () const
+ {
+ return this->archive_install_root_specified_;
+ }
+
+ inline const bool& pkg_bindist_archive_options::
+ archive_install_config () const
+ {
+ return this->archive_install_config_;
+ }
+
+ inline const std::map<string, string>& pkg_bindist_archive_options::
+ archive_split () const
+ {
+ return this->archive_split_;
+ }
+
+ inline bool pkg_bindist_archive_options::
+ archive_split_specified () const
+ {
+ return this->archive_split_specified_;
+ }
+
+ // pkg_bindist_options
+ //
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-build-options.cxx b/bpkg/pkg-build-options.cxx
new file mode 100644
index 0000000..20d04f7
--- /dev/null
+++ b/bpkg/pkg-build-options.cxx
@@ -0,0 +1,1846 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-build-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_build_pkg_options
+ //
+
+ pkg_build_pkg_options::
+ pkg_build_pkg_options ()
+ : upgrade_ (),
+ patch_ (),
+ deorphan_ (),
+ immediate_ (),
+ recursive_ (),
+ upgrade_immediate_ (),
+ patch_immediate_ (),
+ deorphan_immediate_ (),
+ upgrade_recursive_ (),
+ patch_recursive_ (),
+ deorphan_recursive_ (),
+ dependency_ (),
+ keep_out_ (),
+ disfigure_ (),
+ checkout_root_ (),
+ checkout_root_specified_ (false),
+ checkout_purge_ (),
+ config_name_ (),
+ config_name_specified_ (false),
+ config_id_ (),
+ config_id_specified_ (false),
+ config_uuid_ (),
+ config_uuid_specified_ (false)
+ {
+ }
+
+ bool pkg_build_pkg_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_build_pkg_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_build_pkg_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_build_pkg_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_build_pkg_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_build_pkg_options::
+ merge (const pkg_build_pkg_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ if (a.upgrade_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->upgrade_, a.upgrade_);
+ }
+
+ if (a.patch_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->patch_, a.patch_);
+ }
+
+ if (a.deorphan_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->deorphan_, a.deorphan_);
+ }
+
+ if (a.immediate_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->immediate_, a.immediate_);
+ }
+
+ if (a.recursive_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->recursive_, a.recursive_);
+ }
+
+ if (a.upgrade_immediate_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->upgrade_immediate_, a.upgrade_immediate_);
+ }
+
+ if (a.patch_immediate_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->patch_immediate_, a.patch_immediate_);
+ }
+
+ if (a.deorphan_immediate_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->deorphan_immediate_, a.deorphan_immediate_);
+ }
+
+ if (a.upgrade_recursive_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->upgrade_recursive_, a.upgrade_recursive_);
+ }
+
+ if (a.patch_recursive_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->patch_recursive_, a.patch_recursive_);
+ }
+
+ if (a.deorphan_recursive_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->deorphan_recursive_, a.deorphan_recursive_);
+ }
+
+ if (a.dependency_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->dependency_, a.dependency_);
+ }
+
+ if (a.keep_out_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->keep_out_, a.keep_out_);
+ }
+
+ if (a.disfigure_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->disfigure_, a.disfigure_);
+ }
+
+ if (a.checkout_root_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->checkout_root_, a.checkout_root_);
+ this->checkout_root_specified_ = true;
+ }
+
+ if (a.checkout_purge_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->checkout_purge_, a.checkout_purge_);
+ }
+
+ if (a.config_name_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->config_name_, a.config_name_);
+ this->config_name_specified_ = true;
+ }
+
+ if (a.config_id_specified_)
+ {
+ ::bpkg::cli::parser< vector<uint64_t>>::merge (
+ this->config_id_, a.config_id_);
+ this->config_id_specified_ = true;
+ }
+
+ if (a.config_uuid_specified_)
+ {
+ ::bpkg::cli::parser< vector<uuid>>::merge (
+ this->config_uuid_, a.config_uuid_);
+ this->config_uuid_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_build_pkg_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-BUILD PACKAGE OPTIONS\033[0m" << ::std::endl
+ << ::std::endl
+ << "The following options (as well as additional configuration variables) can be" << ::std::endl
+ << "grouped to apply to a specific \033[4mpkg-spec\033[0m as well as specified globally, in which" << ::std::endl
+ << "case they apply to all the specified packages (see \033[1mbpkg-argument-grouping(1)\033[0m" << ::std::endl
+ << "for details)." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--upgrade\033[0m|\033[1m-u\033[0m Upgrade packages to the latest available version that" << ::std::endl
+ << " satisfies all the constraints." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--patch\033[0m|\033[1m-p\033[0m Upgrade packages to the latest available patch" << ::std::endl
+ << " version that satisfies all the constraints." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--deorphan\033[0m Replace orphaned packages with the best matching" << ::std::endl
+ << " available package versions which satisfy all the" << ::std::endl
+ << " constraints." << ::std::endl
+ << ::std::endl
+ << " It may happen that a built package no longer has the" << ::std::endl
+ << " corresponding package available in the repository it" << ::std::endl
+ << " came from (for example, as a result of" << ::std::endl
+ << " \033[1mbpkg-rep-fetch(1)\033[0m or \033[1mbpkg-rep-remove(1)\033[0m). Such a" << ::std::endl
+ << " package is called an \033[4morphan\033[0m. Without the \033[1m--deorphan\033[0m" << ::std::endl
+ << " option, upgrading, downgrading, or patching an orphan" << ::std::endl
+ << " will leave it unchanged if a more suitable version of" << ::std::endl
+ << " the package is not available. If the \033[1m--deorphan\033[0m" << ::std::endl
+ << " option is specified, then an orphan will be replaced" << ::std::endl
+ << " with a non-orphan. In this case, if \033[1m--upgrade\033[0m," << ::std::endl
+ << " \033[1m--patch\033[0m, or the package version is specified, then" << ::std::endl
+ << " the new version is selected accordingly. Otherwise," << ::std::endl
+ << " the closest version to the orphaned version is" << ::std::endl
+ << " selected using the following preference order: (1)" << ::std::endl
+ << " same version, revision, and iteration, (2) latest" << ::std::endl
+ << " iteration of same version and revision, (3) later" << ::std::endl
+ << " revision of same version, (4) later patch of same" << ::std::endl
+ << " version, (5) later minor of same version, (6) latest" << ::std::endl
+ << " available version, including earlier (see Package" << ::std::endl
+ << " Version (bpkg#package-version) for details)." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--immediate\033[0m|\033[1m-i\033[0m Also upgrade, patch, or deorphan immediate" << ::std::endl
+ << " dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--recursive\033[0m|\033[1m-r\033[0m Also upgrade, patch, or deorphan all dependencies," << ::std::endl
+ << " recursively." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--upgrade-immediate\033[0m Upgrade immediate dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--patch-immediate\033[0m Patch immediate dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--deorphan-immediate\033[0m Deorphan immediate dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--upgrade-recursive\033[0m Upgrade all dependencies, recursively." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--patch-recursive\033[0m Patch all dependencies, recursively." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--deorphan-recursive\033[0m Deorphan all dependencies, recursively." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--dependency\033[0m Build, upgrade, or downgrade a package as a" << ::std::endl
+ << " dependency rather than to hold." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--keep-out\033[0m Keep output directories of external packages between" << ::std::endl
+ << " upgrades and downgrades. Refer to" << ::std::endl
+ << " \033[1mbpkg-pkg-disfigure(1)\033[0m for details." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--disfigure\033[0m Disfigure packages between upgrades and downgrades" << ::std::endl
+ << " effectively causing a from-scratch reconfiguration." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--checkout-root\033[0m \033[4mdir\033[0m Check out packages that come from version" << ::std::endl
+ << " control-based repositories into the specified" << ::std::endl
+ << " directory rather than into the configuration" << ::std::endl
+ << " directory. Refer to the \033[1m--output-root\033[0m option in" << ::std::endl
+ << " \033[1mbpkg-pkg-checkout(1)\033[0m for details." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--checkout-purge\033[0m Remove the checked out package (source) directories" << ::std::endl
+ << " when the packages are purged. Refer to the" << ::std::endl
+ << " \033[1m--output-purge\033[0m option in \033[1mbpkg-pkg-checkout(1)\033[0m for" << ::std::endl
+ << " details." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--config-name\033[0m \033[4mname\033[0m Name of the linked configuration to build this" << ::std::endl
+ << " package(s) in. By default, the package is built in" << ::std::endl
+ << " the current configuration. Repeat this option to" << ::std::endl
+ << " specify multiple configurations." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--config-id\033[0m \033[4mnum\033[0m Numeric id of the linked configuration to build this" << ::std::endl
+ << " package(s) in. By default, the package is built in" << ::std::endl
+ << " the current configuration. Repeat this option to" << ::std::endl
+ << " specify multiple configurations." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--config-uuid\033[0m \033[4muuid\033[0m UUID of the linked configuration to build this" << ::std::endl
+ << " package(s) in. By default, the package is built in" << ::std::endl
+ << " the current configuration. Repeat this this option to" << ::std::endl
+ << " specify multiple configurations." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_build_pkg_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_build_pkg_options_map;
+
+ static _cli_pkg_build_pkg_options_map _cli_pkg_build_pkg_options_map_;
+
+ struct _cli_pkg_build_pkg_options_map_init
+ {
+ _cli_pkg_build_pkg_options_map_init ()
+ {
+ _cli_pkg_build_pkg_options_map_["--upgrade"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::upgrade_ >;
+ _cli_pkg_build_pkg_options_map_["-u"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::upgrade_ >;
+ _cli_pkg_build_pkg_options_map_["--patch"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::patch_ >;
+ _cli_pkg_build_pkg_options_map_["-p"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::patch_ >;
+ _cli_pkg_build_pkg_options_map_["--deorphan"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::deorphan_ >;
+ _cli_pkg_build_pkg_options_map_["--immediate"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::immediate_ >;
+ _cli_pkg_build_pkg_options_map_["-i"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::immediate_ >;
+ _cli_pkg_build_pkg_options_map_["--recursive"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::recursive_ >;
+ _cli_pkg_build_pkg_options_map_["-r"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::recursive_ >;
+ _cli_pkg_build_pkg_options_map_["--upgrade-immediate"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::upgrade_immediate_ >;
+ _cli_pkg_build_pkg_options_map_["--patch-immediate"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::patch_immediate_ >;
+ _cli_pkg_build_pkg_options_map_["--deorphan-immediate"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::deorphan_immediate_ >;
+ _cli_pkg_build_pkg_options_map_["--upgrade-recursive"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::upgrade_recursive_ >;
+ _cli_pkg_build_pkg_options_map_["--patch-recursive"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::patch_recursive_ >;
+ _cli_pkg_build_pkg_options_map_["--deorphan-recursive"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::deorphan_recursive_ >;
+ _cli_pkg_build_pkg_options_map_["--dependency"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::dependency_ >;
+ _cli_pkg_build_pkg_options_map_["--keep-out"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::keep_out_ >;
+ _cli_pkg_build_pkg_options_map_["--disfigure"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::disfigure_ >;
+ _cli_pkg_build_pkg_options_map_["--checkout-root"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, dir_path, &pkg_build_pkg_options::checkout_root_,
+ &pkg_build_pkg_options::checkout_root_specified_ >;
+ _cli_pkg_build_pkg_options_map_["--checkout-purge"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, &pkg_build_pkg_options::checkout_purge_ >;
+ _cli_pkg_build_pkg_options_map_["--config-name"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, strings, &pkg_build_pkg_options::config_name_,
+ &pkg_build_pkg_options::config_name_specified_ >;
+ _cli_pkg_build_pkg_options_map_["--config-id"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, vector<uint64_t>, &pkg_build_pkg_options::config_id_,
+ &pkg_build_pkg_options::config_id_specified_ >;
+ _cli_pkg_build_pkg_options_map_["--config-uuid"] =
+ &::bpkg::cli::thunk< pkg_build_pkg_options, vector<uuid>, &pkg_build_pkg_options::config_uuid_,
+ &pkg_build_pkg_options::config_uuid_specified_ >;
+ }
+ };
+
+ static _cli_pkg_build_pkg_options_map_init _cli_pkg_build_pkg_options_map_init_;
+
+ bool pkg_build_pkg_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_build_pkg_options_map::const_iterator i (_cli_pkg_build_pkg_options_map_.find (o));
+
+ if (i != _cli_pkg_build_pkg_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool pkg_build_pkg_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+
+ // pkg_build_options
+ //
+
+ pkg_build_options::
+ pkg_build_options ()
+ : yes_ (),
+ for__ (),
+ for__specified_ (false),
+ keep_unused_ (),
+ update_dependent_ (),
+ leave_dependent_ (),
+ configure_only_ (),
+ print_only_ (),
+ plan_ (),
+ plan_specified_ (false),
+ no_fetch_ (),
+ fetch_shallow_ (),
+ mask_repository_ (),
+ mask_repository_specified_ (false),
+ mask_repository_uuid_ (),
+ mask_repository_uuid_specified_ (false),
+ no_refinement_ (),
+ no_move_ (),
+ noop_exit_ (),
+ noop_exit_specified_ (false),
+ rebuild_checksum_ (),
+ rebuild_checksum_specified_ (false),
+ no_private_config_ (),
+ no_private_config_specified_ (false),
+ sys_no_query_ (),
+ sys_install_ (),
+ sys_no_fetch_ (),
+ sys_no_stub_ (),
+ sys_yes_ (),
+ sys_sudo_ ("sudo"),
+ sys_sudo_specified_ (false),
+ sys_distribution_ (),
+ sys_distribution_specified_ (false),
+ sys_architecture_ (),
+ sys_architecture_specified_ (false),
+ directory_ (),
+ directory_specified_ (false)
+ {
+ }
+
+ bool pkg_build_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_build_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_build_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_build_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_build_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_build_options::
+ merge (const pkg_build_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+
+ // pkg_build_pkg_options base
+ //
+ ::bpkg::pkg_build_pkg_options::merge (a);
+
+ if (a.yes_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->yes_, a.yes_);
+ }
+
+ if (a.for__specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->for__, a.for__);
+ this->for__specified_ = true;
+ }
+
+ if (a.keep_unused_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->keep_unused_, a.keep_unused_);
+ }
+
+ if (a.update_dependent_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->update_dependent_, a.update_dependent_);
+ }
+
+ if (a.leave_dependent_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->leave_dependent_, a.leave_dependent_);
+ }
+
+ if (a.configure_only_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->configure_only_, a.configure_only_);
+ }
+
+ if (a.print_only_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->print_only_, a.print_only_);
+ }
+
+ if (a.plan_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->plan_, a.plan_);
+ this->plan_specified_ = true;
+ }
+
+ if (a.no_fetch_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_fetch_, a.no_fetch_);
+ }
+
+ if (a.fetch_shallow_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->fetch_shallow_, a.fetch_shallow_);
+ }
+
+ if (a.mask_repository_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->mask_repository_, a.mask_repository_);
+ this->mask_repository_specified_ = true;
+ }
+
+ if (a.mask_repository_uuid_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->mask_repository_uuid_, a.mask_repository_uuid_);
+ this->mask_repository_uuid_specified_ = true;
+ }
+
+ if (a.no_refinement_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_refinement_, a.no_refinement_);
+ }
+
+ if (a.no_move_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_move_, a.no_move_);
+ }
+
+ if (a.noop_exit_specified_)
+ {
+ ::bpkg::cli::parser< uint16_t>::merge (
+ this->noop_exit_, a.noop_exit_);
+ this->noop_exit_specified_ = true;
+ }
+
+ if (a.rebuild_checksum_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->rebuild_checksum_, a.rebuild_checksum_);
+ this->rebuild_checksum_specified_ = true;
+ }
+
+ if (a.no_private_config_specified_)
+ {
+ ::bpkg::cli::parser< uint16_t>::merge (
+ this->no_private_config_, a.no_private_config_);
+ this->no_private_config_specified_ = true;
+ }
+
+ if (a.sys_no_query_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->sys_no_query_, a.sys_no_query_);
+ }
+
+ if (a.sys_install_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->sys_install_, a.sys_install_);
+ }
+
+ if (a.sys_no_fetch_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->sys_no_fetch_, a.sys_no_fetch_);
+ }
+
+ if (a.sys_no_stub_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->sys_no_stub_, a.sys_no_stub_);
+ }
+
+ if (a.sys_yes_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->sys_yes_, a.sys_yes_);
+ }
+
+ if (a.sys_sudo_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->sys_sudo_, a.sys_sudo_);
+ this->sys_sudo_specified_ = true;
+ }
+
+ if (a.sys_distribution_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->sys_distribution_, a.sys_distribution_);
+ this->sys_distribution_specified_ = true;
+ }
+
+ if (a.sys_architecture_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->sys_architecture_, a.sys_architecture_);
+ this->sys_architecture_specified_ = true;
+ }
+
+ if (a.directory_specified_)
+ {
+ ::bpkg::cli::parser< dir_paths>::merge (
+ this->directory_, a.directory_);
+ this->directory_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_build_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-BUILD GLOBAL OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--yes\033[0m|\033[1m-y\033[0m Assume the answer to all prompts is \033[1myes\033[0m. Note that" << ::std::endl
+ << " this excludes the system package manager prompts; see" << ::std::endl
+ << " \033[1m--sys-yes\033[0m for details." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--for\033[0m|\033[1m-f\033[0m \033[4moperation\033[0m Instead of the default \033[1mupdate\033[0m build system operation," << ::std::endl
+ << " perform the \033[1mupdate-for-\033[0m\033[4moperation\033[0m variant where" << ::std::endl
+ << " \033[4moperation\033[0m is normally \033[1minstall\033[0m or \033[1mtest\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--keep-unused\033[0m|\033[1m-K\033[0m Don't drop dependency packages that were" << ::std::endl
+ << " automatically built but will no longer be used." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--update-dependent\033[0m|\033[1m-U\033[0m Update without confirmation dependent packages that" << ::std::endl
+ << " are reconfigured due to their dependencies being" << ::std::endl
+ << " upgraded or downgraded." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--leave-dependent\033[0m|\033[1m-L\033[0m Don't offer to update dependent packages that are" << ::std::endl
+ << " reconfigured due to their dependencies being upgraded" << ::std::endl
+ << " or downgraded." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--configure-only\033[0m|\033[1m-c\033[0m Configure all the packages but don't update." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--print-only\033[0m Print to \033[1mstdout\033[0m what would be done without actually" << ::std::endl
+ << " doing anything." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--plan\033[0m \033[4mheader\033[0m Print the plan (even if \033[1m--yes\033[0m is specified) and start" << ::std::endl
+ << " it with the \033[4mheader\033[0m line (unless it is empty)." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-fetch\033[0m Don't fetch repositories specified as part of the" << ::std::endl
+ << " build command." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fetch-shallow\033[0m Don't re-fetch complement and prerequisite" << ::std::endl
+ << " repositories of repositories specified as part of the" << ::std::endl
+ << " build command. Refer to the \033[1m--shallow\033[0m option in" << ::std::endl
+ << " \033[1mbpkg-rep-fetch(1)\033[0m for details." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--mask-repository\033[0m \033[4mrep\033[0m For the duration of the command execution pretend the" << ::std::endl
+ << " specified repository was removed as if by performing" << ::std::endl
+ << " the \033[1mrep-remove\033[0m command. The repository can be" << ::std::endl
+ << " specified either as a repository name or as a" << ::std::endl
+ << " repository location (URL or a directory path). Note" << ::std::endl
+ << " that the repository's complement and prerequisite" << ::std::endl
+ << " repositories are also considered masked, recursively," << ::std::endl
+ << " unless they are complements and/or prerequisites of" << ::std::endl
+ << " other unmasked repositories. Repeat this option to" << ::std::endl
+ << " mask multiple repositories." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--mask-repository-uuid\033[0m \033[4mv\033[0m For the duration of the command execution pretend the" << ::std::endl
+ << " specified repository was removed from the specified" << ::std::endl
+ << " configuration. Similar to \033[1m--mask-repository\033[0m but only" << ::std::endl
+ << " masks the repository in a single configuration. The" << ::std::endl
+ << " option value is a key-value pair in the form:" << ::std::endl
+ << ::std::endl
+ << " \033[4mconfig-uuid\033[0m\033[1m=\033[0m\033[4mrep\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << " Repeat this option to mask multiple repositories." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-refinement\033[0m Don't try to refine the configuration by offering to" << ::std::endl
+ << " drop any unused dependencies that were potentially" << ::std::endl
+ << " left behind on the previous \033[1mpkg-build\033[0m or \033[1mpkg-drop\033[0m" << ::std::endl
+ << " command execution if the command is otherwise a noop" << ::std::endl
+ << " (performs no new package builds, upgrades, etc)." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-move\033[0m Don't move dependency packages between" << ::std::endl
+ << " configurations. In this mode the \033[1m--config-*\033[0m options" << ::std::endl
+ << " specify packages' current rather than new locations." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--noop-exit\033[0m \033[4mcode\033[0m Exit with the specified error code if the command" << ::std::endl
+ << " execution is a noop (performs no new package builds," << ::std::endl
+ << " upgrades, etc)." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--rebuild-checksum\033[0m \033[4msum\033[0m Hash the names, versions, and configurations of all" << ::std::endl
+ << " the packages that would be built. If the resulting" << ::std::endl
+ << " checksum matches the specified, then exit without" << ::std::endl
+ << " building anything (potentially with a special error" << ::std::endl
+ << " code specified with the \033[1m--noop-exit\033[0m option)." << ::std::endl
+ << " Otherwise, proceed to build as normal. In both cases," << ::std::endl
+ << " print the resulting checksum to \033[1mstdout\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-private-config\033[0m \033[4mcode\033[0m If no configuration of a suitable type is linked to" << ::std::endl
+ << " build a build-time dependency, instead of" << ::std::endl
+ << " automatically creating a private configuration of" << ::std::endl
+ << " this type, exit with the specified error code" << ::std::endl
+ << " printing to \033[1mstdout\033[0m the dependency chain starting from" << ::std::endl
+ << " the build-time dependency (together with its" << ::std::endl
+ << " constraint, if present) and ending with the top-level" << ::std::endl
+ << " dependent (together with their configuration" << ::std::endl
+ << " directories), one entry per line. For example:" << ::std::endl
+ << ::std::endl
+ << " yacc ^1.0.0" << ::std::endl
+ << " libbar/1.0.0 /path/to/libbar/cfg/" << ::std::endl
+ << " libfoo/1.0.0 /path/to/libfoo/cfg/" << ::std::endl
+ << ::std::endl
+ << " See \033[1mbpkg-cfg-create(1)\033[0m for details on linked" << ::std::endl
+ << " configurations." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sys-no-query\033[0m Do not query the system package manager for the" << ::std::endl
+ << " installed versions of packages specified with the" << ::std::endl
+ << " \033[1msys\033[0m scheme." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sys-install\033[0m Instruct the system package manager to install" << ::std::endl
+ << " available versions of packages specified with the" << ::std::endl
+ << " \033[1msys\033[0m scheme that are not already installed. See also" << ::std::endl
+ << " the \033[1m--sys-no-fetch\033[0m, \033[1m--sys-yes\033[0m, and \033[1m--sys-sudo\033[0m" << ::std::endl
+ << " options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sys-no-fetch\033[0m Do not fetch the system package manager metadata" << ::std::endl
+ << " before querying for available versions of packages" << ::std::endl
+ << " specified with the \033[1msys\033[0m scheme. This option only makes" << ::std::endl
+ << " sense together with \033[1m--sys-install\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sys-no-stub\033[0m Do no require a stub for packages specified with the" << ::std::endl
+ << " \033[1msys\033[0m scheme. Note that this option has effect only if" << ::std::endl
+ << " the system package manager interactions are supported" << ::std::endl
+ << " and not disabled." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sys-yes\033[0m Assume the answer to the system package manager" << ::std::endl
+ << " prompts is \033[1myes\033[0m. Note that system package manager" << ::std::endl
+ << " interactions may break your system and you should" << ::std::endl
+ << " normally only use this option on throw-away setups" << ::std::endl
+ << " (test virtual machines, etc)." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sys-sudo\033[0m \033[4mprog\033[0m The \033[1msudo\033[0m program to use for system package manager" << ::std::endl
+ << " interactions that normally require administrative" << ::std::endl
+ << " privileges (fetch package metadata, install packages," << ::std::endl
+ << " etc). If unspecified, \033[1msudo\033[0m is used by default. Pass" << ::std::endl
+ << " empty or the special \033[1mfalse\033[0m value to disable the use" << ::std::endl
+ << " of the \033[1msudo\033[0m program. Note that the \033[1msudo\033[0m program is" << ::std::endl
+ << " normally only needed if the system package" << ::std::endl
+ << " installation is enabled with the \033[1m--sys-install\033[0m" << ::std::endl
+ << " option." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sys-distribution\033[0m \033[4mname\033[0m Alternative system/distribution package manager to" << ::std::endl
+ << " interact with. The valid \033[4mname\033[0m values are \033[1mdebian\033[0m" << ::std::endl
+ << " (Debian and alike, such as Ubuntu, etc) and \033[1mfedora\033[0m" << ::std::endl
+ << " (Fedora and alike, such as RHEL, CentOS, etc). Note" << ::std::endl
+ << " that some package managers may only be supported when" << ::std::endl
+ << " running on certain host operating systems." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sys-architecture\033[0m \033[4mname\033[0m Alternative architecture to use when interacting with" << ::std::endl
+ << " the system package manager. The valid \033[4mname\033[0m values are" << ::std::endl
+ << " system/distribution package manager-specific. If" << ::std::endl
+ << " unspecified, the host architecture is used." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--directory\033[0m|\033[1m-d\033[0m \033[4mdir\033[0m Assume current configuration is in \033[4mdir\033[0m rather than in" << ::std::endl
+ << " the current working directory. Repeat this option to" << ::std::endl
+ << " specify multiple current configurations. If multiple" << ::std::endl
+ << " configurations are specified, they need not belong to" << ::std::endl
+ << " the same linked configuration cluster." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_build_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_build_options_map;
+
+ static _cli_pkg_build_options_map _cli_pkg_build_options_map_;
+
+ struct _cli_pkg_build_options_map_init
+ {
+ _cli_pkg_build_options_map_init ()
+ {
+ _cli_pkg_build_options_map_["--yes"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::yes_ >;
+ _cli_pkg_build_options_map_["-y"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::yes_ >;
+ _cli_pkg_build_options_map_["--for"] =
+ &::bpkg::cli::thunk< pkg_build_options, string, &pkg_build_options::for__,
+ &pkg_build_options::for__specified_ >;
+ _cli_pkg_build_options_map_["-f"] =
+ &::bpkg::cli::thunk< pkg_build_options, string, &pkg_build_options::for__,
+ &pkg_build_options::for__specified_ >;
+ _cli_pkg_build_options_map_["--keep-unused"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::keep_unused_ >;
+ _cli_pkg_build_options_map_["-K"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::keep_unused_ >;
+ _cli_pkg_build_options_map_["--update-dependent"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::update_dependent_ >;
+ _cli_pkg_build_options_map_["-U"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::update_dependent_ >;
+ _cli_pkg_build_options_map_["--leave-dependent"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::leave_dependent_ >;
+ _cli_pkg_build_options_map_["-L"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::leave_dependent_ >;
+ _cli_pkg_build_options_map_["--configure-only"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::configure_only_ >;
+ _cli_pkg_build_options_map_["-c"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::configure_only_ >;
+ _cli_pkg_build_options_map_["--print-only"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::print_only_ >;
+ _cli_pkg_build_options_map_["--plan"] =
+ &::bpkg::cli::thunk< pkg_build_options, string, &pkg_build_options::plan_,
+ &pkg_build_options::plan_specified_ >;
+ _cli_pkg_build_options_map_["--no-fetch"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::no_fetch_ >;
+ _cli_pkg_build_options_map_["--fetch-shallow"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::fetch_shallow_ >;
+ _cli_pkg_build_options_map_["--mask-repository"] =
+ &::bpkg::cli::thunk< pkg_build_options, strings, &pkg_build_options::mask_repository_,
+ &pkg_build_options::mask_repository_specified_ >;
+ _cli_pkg_build_options_map_["--mask-repository-uuid"] =
+ &::bpkg::cli::thunk< pkg_build_options, strings, &pkg_build_options::mask_repository_uuid_,
+ &pkg_build_options::mask_repository_uuid_specified_ >;
+ _cli_pkg_build_options_map_["--no-refinement"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::no_refinement_ >;
+ _cli_pkg_build_options_map_["--no-move"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::no_move_ >;
+ _cli_pkg_build_options_map_["--noop-exit"] =
+ &::bpkg::cli::thunk< pkg_build_options, uint16_t, &pkg_build_options::noop_exit_,
+ &pkg_build_options::noop_exit_specified_ >;
+ _cli_pkg_build_options_map_["--rebuild-checksum"] =
+ &::bpkg::cli::thunk< pkg_build_options, string, &pkg_build_options::rebuild_checksum_,
+ &pkg_build_options::rebuild_checksum_specified_ >;
+ _cli_pkg_build_options_map_["--no-private-config"] =
+ &::bpkg::cli::thunk< pkg_build_options, uint16_t, &pkg_build_options::no_private_config_,
+ &pkg_build_options::no_private_config_specified_ >;
+ _cli_pkg_build_options_map_["--sys-no-query"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::sys_no_query_ >;
+ _cli_pkg_build_options_map_["--sys-install"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::sys_install_ >;
+ _cli_pkg_build_options_map_["--sys-no-fetch"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::sys_no_fetch_ >;
+ _cli_pkg_build_options_map_["--sys-no-stub"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::sys_no_stub_ >;
+ _cli_pkg_build_options_map_["--sys-yes"] =
+ &::bpkg::cli::thunk< pkg_build_options, &pkg_build_options::sys_yes_ >;
+ _cli_pkg_build_options_map_["--sys-sudo"] =
+ &::bpkg::cli::thunk< pkg_build_options, string, &pkg_build_options::sys_sudo_,
+ &pkg_build_options::sys_sudo_specified_ >;
+ _cli_pkg_build_options_map_["--sys-distribution"] =
+ &::bpkg::cli::thunk< pkg_build_options, string, &pkg_build_options::sys_distribution_,
+ &pkg_build_options::sys_distribution_specified_ >;
+ _cli_pkg_build_options_map_["--sys-architecture"] =
+ &::bpkg::cli::thunk< pkg_build_options, string, &pkg_build_options::sys_architecture_,
+ &pkg_build_options::sys_architecture_specified_ >;
+ _cli_pkg_build_options_map_["--directory"] =
+ &::bpkg::cli::thunk< pkg_build_options, dir_paths, &pkg_build_options::directory_,
+ &pkg_build_options::directory_specified_ >;
+ _cli_pkg_build_options_map_["-d"] =
+ &::bpkg::cli::thunk< pkg_build_options, dir_paths, &pkg_build_options::directory_,
+ &pkg_build_options::directory_specified_ >;
+ }
+ };
+
+ static _cli_pkg_build_options_map_init _cli_pkg_build_options_map_init_;
+
+ bool pkg_build_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_build_options_map::const_iterator i (_cli_pkg_build_options_map_.find (o));
+
+ if (i != _cli_pkg_build_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ // pkg_build_pkg_options base
+ //
+ if (::bpkg::pkg_build_pkg_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_build_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_build_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-build\033[0m|\033[1mbuild\033[0m [\033[4moptions\033[0m] [\033[1m--upgrade\033[0m|\033[1m-u\033[0m | \033[1m--patch\033[0m|\033[1m-p\033[0m]" << ::std::endl
+ << " [\033[4mcfg-var\033[0m... \033[1m--\033[0m] \033[4mpkg-spec\033[0m..." << ::std::endl
+ << "\033[1mbpkg pkg-build\033[0m|\033[1mbuild\033[0m [\033[4moptions\033[0m] \033[1m--upgrade\033[0m|\033[1m-u\033[0m | \033[1m--patch\033[0m|\033[1m-p\033[0m" << ::std::endl
+ << " [\033[4mcfg-var\033[0m... \033[1m--\033[0m]\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[4mpkg-spec\033[0m = [\033[4mflags\033[0m](([\033[4mscheme\033[0m\033[1m:\033[0m]\033[4mpkg\033[0m[\033[4mver-spec\033[0m])\033[1m,\033[0m...[\033[1m@\033[0m\033[4mrep-loc\033[0m] | " << ::std::endl
+ << " [\033[1m@\033[0m]\033[4mrep-loc\033[0m | " << ::std::endl
+ << " \033[4mfile\033[0m | " << ::std::endl
+ << " \033[4mdir\033[0m\033[1m/\033[0m)" << ::std::endl
+ << "\033[4mflags\033[0m = \033[1m?\033[0m" << ::std::endl
+ << "\033[4mscheme\033[0m = \033[1msys\033[0m" << ::std::endl
+ << "\033[4mver-spec\033[0m = \033[1m/\033[0m\033[4mversion\033[0m | \033[4mversion-constraint\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-build\033[0m command builds one or more packages including all their" << ::std::endl
+ << "dependencies. Besides building new packages, this command is also used to" << ::std::endl
+ << "upgrade or downgrade packages that are already present in the configuration." << ::std::endl
+ << "And unless the \033[1m--keep-unused\033[0m|\033[1m-K\033[0m\033[0m option is specified, \033[1mpkg-build\033[0m will also drop" << ::std::endl
+ << "dependency packages that would otherwise no longer be used." << ::std::endl
+ << ::std::endl
+ << "The first form (one or more packages are specified) builds new or upgrades (by" << ::std::endl
+ << "default or if \033[1m--upgrade\033[0m is specified) or patches (if \033[1m--patch\033[0m is specified) the" << ::std::endl
+ << "specified packages. The second form (no arguments but either \033[1m--upgrade\033[0m or" << ::std::endl
+ << "\033[1m--patch\033[0m is specified) upgrades or patches all the held packages in the" << ::std::endl
+ << "configuration (see below for details on held package)." << ::std::endl
+ << ::std::endl
+ << "In both forms specifying the \033[1m--immediate\033[0m|\033[1m-i\033[0m\033[0m or \033[1m--recursive\033[0m|\033[1m-r\033[0m\033[0m option causes" << ::std::endl
+ << "\033[1mpkg-build\033[0m to also upgrade or patch the immediate or all dependencies of the" << ::std::endl
+ << "specified (first form) or held (second form) packages, respectively. Note also" << ::std::endl
+ << "that in the first form these options can only be specified with an explicit" << ::std::endl
+ << "\033[1m--upgrade\033[0m or \033[1m--patch\033[0m." << ::std::endl
+ << ::std::endl
+ << "Each package can be specified as just the name (\033[4mpkg\033[0m) with optional version" << ::std::endl
+ << "specification (\033[4mver-spec\033[0m), in which case the source code for the package will be" << ::std::endl
+ << "automatically fetched from one of the configured repositories. See the" << ::std::endl
+ << "\033[1mbpkg-rep-add(1)\033[0m and \033[1mbpkg-rep-fetch(1)\033[0m commands for more information on package" << ::std::endl
+ << "repositories. The version specification (\033[4mver-spec\033[0m) can be either the exact" << ::std::endl
+ << "version in the \033[1m/\033[0m\033[4mversion\033[0m\033[0m form or the version constraint as described in Package" << ::std::endl
+ << "Version Constraint (bpkg#package-version-constraint). If \033[4mver-spec\033[0m is not" << ::std::endl
+ << "specified, then the latest available version will be built. To downgrade, the" << ::std::endl
+ << "desired version must be specified explicitly. For example:" << ::std::endl
+ << ::std::endl
+ << "bpkg build foo libfoo/1.2.3 \"bar < 2.0.0\"" << ::std::endl
+ << ::std::endl
+ << "Alternatively, the package repository location (\033[4mrep-loc\033[0m) can be specified as" << ::std::endl
+ << "part of the build command. In this case, if \033[4mver-spec\033[0m is not specified, then the" << ::std::endl
+ << "latest available from this repository version will be built. For example:" << ::std::endl
+ << ::std::endl
+ << "bpkg build foo,libfoo/1.2.3@https://git.example.org/foo.git#master" << ::std::endl
+ << ::std::endl
+ << "If only the location is specified, then the latest versions of all the packages" << ::std::endl
+ << "available directly from this repository will be built (note that this does not" << ::std::endl
+ << "include packages available from complement repositories). The \033[1m@\033[0m delimiter can" << ::std::endl
+ << "be omitted if the location is a URL. For example:" << ::std::endl
+ << ::std::endl
+ << "bpkg build https://git.example.org/foo.git#master" << ::std::endl
+ << "bpkg build @/path/to/repository/" << ::std::endl
+ << ::std::endl
+ << "A package name (\033[4mpkg\033[0m) can be prefixed with a package scheme (\033[4mscheme\033[0m). Currently" << ::std::endl
+ << "the only recognized scheme is \033[1msys\033[0m which instructs \033[1mpkg-build\033[0m to configure the" << ::std::endl
+ << "package as available from the system rather than building it from source." << ::std::endl
+ << ::std::endl
+ << "The system package version (\033[4mver-spec\033[0m) may not be a version constraint but may" << ::std::endl
+ << "be the special '\033[1m/*\033[0m' value, which indicates that the version should be" << ::std::endl
+ << "considered unknown but satisfying any version constraint. If unspecified, then" << ::std::endl
+ << "\033[1mpkg-build\033[0m will attempt to query the system package manager for the installed" << ::std::endl
+ << "version unless the system package manager is unsupported or this functionality" << ::std::endl
+ << "is disabled with \033[1m--sys-no-query\033[0m, in which case the '\033[1m/*\033[0m' \033[4mver-spec\033[0m is assumed. If" << ::std::endl
+ << "the system package manager is supported, then the automatic installation of an" << ::std::endl
+ << "available package can be requested with the \033[1m--sys-install\033[0m option. Note that if" << ::std::endl
+ << "the version is not explicitly specified, then at least a stub package must be" << ::std::endl
+ << "available from one of the repositories unless the \033[1m--sys-no-stub\033[0m option is" << ::std::endl
+ << "specified." << ::std::endl
+ << ::std::endl
+ << "Finally, a package can be specified as either the path to the package archive" << ::std::endl
+ << "(\033[4mfile\033[0m) or to the package directory (\033[4mdir\033[0m\033[1m/\033[0m; note that it must end with a" << ::std::endl
+ << "directory separator). See the \033[1mbpkg-pkg-fetch(1)\033[0m and \033[1mbpkg-pkg-unpack(1)\033[0m commands" << ::std::endl
+ << "for more information on the semantics of specifying the package as an archive" << ::std::endl
+ << "or a directory." << ::std::endl
+ << ::std::endl
+ << "Additional configuration variables (\033[4mcfg-var\033[0m), if any, should be specified" << ::std::endl
+ << "before packages (\033[4mpkg-spec\033[0m) and should be separated with \033[1m--\033[0m. Such variables are" << ::std::endl
+ << "effective only when configuring and only for packages that were explicitly" << ::std::endl
+ << "specified on the command line (unless global overrides). They can also be" << ::std::endl
+ << "specified to only apply to specific packages using the argument grouping" << ::std::endl
+ << "mechanism discussed below. See \033[1mbpkg-pkg-configure(1)\033[0m for more information on" << ::std::endl
+ << "configuration variables." << ::std::endl
+ << ::std::endl
+ << "By default a package that is specified explicitly on the command line is built" << ::std::endl
+ << "to \033[4mhold\033[0m: it will not be considered for automatic removal if it no longer has" << ::std::endl
+ << "any dependents. Only versions from repositories that were added to the" << ::std::endl
+ << "configuration (\033[1mbpkg-rep-add(1)\033[0m) are considered as available for build to hold." << ::std::endl
+ << ::std::endl
+ << "Alternatively, a package can be built (or, more commonly, upgraded/downgraded)" << ::std::endl
+ << "as a \033[4mdependency\033[0m by specifying the \033[1m?\033[0m flag (\033[4mflags\033[0m) or the \033[1m--dependency\033[0m option." << ::std::endl
+ << "Such a package will only be added to the configuration if it actually has any" << ::std::endl
+ << "dependents and once no longer used, it will be automatically dropped. Only" << ::std::endl
+ << "versions from prerequisite repositories of dependent packages are considered as" << ::std::endl
+ << "available for build as a dependency." << ::std::endl
+ << ::std::endl
+ << "Packages (both built to hold and as dependencies) that are specified with an" << ::std::endl
+ << "explicit package version (\033[4mver-spec\033[0m) or as an archive or directory, will have" << ::std::endl
+ << "their versions held, that is, they will not be automatically upgraded." << ::std::endl
+ << ::std::endl
+ << "As an illustration, let's assume in the following example that the stable" << ::std::endl
+ << "repository contains packages \033[1mfoo\033[0m \033[1m1.0.0\033[0m as well as \033[1mlibfoo\033[0m \033[1m1.0.0\033[0m and \033[1m1.1.0\033[0m while" << ::std::endl
+ << "testing -- \033[1mlibfoo\033[0m \033[1m2.0.0\033[0m, that testing is complemented by stable, and that \033[1mfoo\033[0m" << ::std::endl
+ << "depends on \033[1mlibfoo >= 1.0.0\033[0m:" << ::std::endl
+ << ::std::endl
+ << "bpkg fetch https://example.org/1/testing" << ::std::endl
+ << ::std::endl
+ << "bpkg build foo # build foo 1.0.0 to hold" << ::std::endl
+ << " # build libfoo 1.1.0 as dependency" << ::std::endl
+ << ::std::endl
+ << "bpkg build ?libfoo/1.0.0 # downgrade libfoo 1.0.0 as dependency," << ::std::endl
+ << " # also hold version 1.0.0" << ::std::endl
+ << ::std::endl
+ << "bpkg build ?libfoo/2.0.0 # error: 2.0.0 unavailable in dependent's" << ::std::endl
+ << " # (foo) repository (stable)" << ::std::endl
+ << ::std::endl
+ << "bpkg build libfoo/2.0.0 # upgrade libfoo 2.0.0 to hold," << ::std::endl
+ << " # also hold version 2.0.0" << ::std::endl
+ << ::std::endl
+ << "A package can be built in one of the linked configurations instead of the" << ::std::endl
+ << "current (or host/build system module, for build-time dependencies)" << ::std::endl
+ << "configuration by specifying one of the \033[1m--config-*\033[0m options (see" << ::std::endl
+ << "\033[1mbpkg-cfg-create(1)\033[0m for background on linked configurations). For example:" << ::std::endl
+ << ::std::endl
+ << "bpkg build foo { --config-name=alt-host }+ ?bison" << ::std::endl;
+
+ p = ::bpkg::pkg_build_pkg_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ p = ::bpkg::pkg_build_options::print_usage (os, p);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-build\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-build.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-build\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-build-options.hxx b/bpkg/pkg-build-options.hxx
new file mode 100644
index 0000000..7442120
--- /dev/null
+++ b/bpkg/pkg-build-options.hxx
@@ -0,0 +1,738 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_BUILD_OPTIONS_HXX
+#define BPKG_PKG_BUILD_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class pkg_build_pkg_options
+ {
+ public:
+ pkg_build_pkg_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_build_pkg_options&);
+
+ // Option accessors and modifiers.
+ //
+ const bool&
+ upgrade () const;
+
+ bool&
+ upgrade ();
+
+ void
+ upgrade (const bool&);
+
+ const bool&
+ patch () const;
+
+ bool&
+ patch ();
+
+ void
+ patch (const bool&);
+
+ const bool&
+ deorphan () const;
+
+ bool&
+ deorphan ();
+
+ void
+ deorphan (const bool&);
+
+ const bool&
+ immediate () const;
+
+ bool&
+ immediate ();
+
+ void
+ immediate (const bool&);
+
+ const bool&
+ recursive () const;
+
+ bool&
+ recursive ();
+
+ void
+ recursive (const bool&);
+
+ const bool&
+ upgrade_immediate () const;
+
+ bool&
+ upgrade_immediate ();
+
+ void
+ upgrade_immediate (const bool&);
+
+ const bool&
+ patch_immediate () const;
+
+ bool&
+ patch_immediate ();
+
+ void
+ patch_immediate (const bool&);
+
+ const bool&
+ deorphan_immediate () const;
+
+ bool&
+ deorphan_immediate ();
+
+ void
+ deorphan_immediate (const bool&);
+
+ const bool&
+ upgrade_recursive () const;
+
+ bool&
+ upgrade_recursive ();
+
+ void
+ upgrade_recursive (const bool&);
+
+ const bool&
+ patch_recursive () const;
+
+ bool&
+ patch_recursive ();
+
+ void
+ patch_recursive (const bool&);
+
+ const bool&
+ deorphan_recursive () const;
+
+ bool&
+ deorphan_recursive ();
+
+ void
+ deorphan_recursive (const bool&);
+
+ const bool&
+ dependency () const;
+
+ bool&
+ dependency ();
+
+ void
+ dependency (const bool&);
+
+ const bool&
+ keep_out () const;
+
+ bool&
+ keep_out ();
+
+ void
+ keep_out (const bool&);
+
+ const bool&
+ disfigure () const;
+
+ bool&
+ disfigure ();
+
+ void
+ disfigure (const bool&);
+
+ const dir_path&
+ checkout_root () const;
+
+ dir_path&
+ checkout_root ();
+
+ void
+ checkout_root (const dir_path&);
+
+ bool
+ checkout_root_specified () const;
+
+ void
+ checkout_root_specified (bool);
+
+ const bool&
+ checkout_purge () const;
+
+ bool&
+ checkout_purge ();
+
+ void
+ checkout_purge (const bool&);
+
+ const strings&
+ config_name () const;
+
+ strings&
+ config_name ();
+
+ void
+ config_name (const strings&);
+
+ bool
+ config_name_specified () const;
+
+ void
+ config_name_specified (bool);
+
+ const vector<uint64_t>&
+ config_id () const;
+
+ vector<uint64_t>&
+ config_id ();
+
+ void
+ config_id (const vector<uint64_t>&);
+
+ bool
+ config_id_specified () const;
+
+ void
+ config_id_specified (bool);
+
+ const vector<uuid>&
+ config_uuid () const;
+
+ vector<uuid>&
+ config_uuid ();
+
+ void
+ config_uuid (const vector<uuid>&);
+
+ bool
+ config_uuid_specified () const;
+
+ void
+ config_uuid_specified (bool);
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool upgrade_;
+ bool patch_;
+ bool deorphan_;
+ bool immediate_;
+ bool recursive_;
+ bool upgrade_immediate_;
+ bool patch_immediate_;
+ bool deorphan_immediate_;
+ bool upgrade_recursive_;
+ bool patch_recursive_;
+ bool deorphan_recursive_;
+ bool dependency_;
+ bool keep_out_;
+ bool disfigure_;
+ dir_path checkout_root_;
+ bool checkout_root_specified_;
+ bool checkout_purge_;
+ strings config_name_;
+ bool config_name_specified_;
+ vector<uint64_t> config_id_;
+ bool config_id_specified_;
+ vector<uuid> config_uuid_;
+ bool config_uuid_specified_;
+ };
+
+ class pkg_build_options: public ::bpkg::common_options,
+ public ::bpkg::pkg_build_pkg_options
+ {
+ public:
+ pkg_build_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_build_options&);
+
+ // Option accessors and modifiers.
+ //
+ const bool&
+ yes () const;
+
+ bool&
+ yes ();
+
+ void
+ yes (const bool&);
+
+ const string&
+ for_ () const;
+
+ string&
+ for_ ();
+
+ void
+ for_ (const string&);
+
+ bool
+ for__specified () const;
+
+ void
+ for__specified (bool);
+
+ const bool&
+ keep_unused () const;
+
+ bool&
+ keep_unused ();
+
+ void
+ keep_unused (const bool&);
+
+ const bool&
+ update_dependent () const;
+
+ bool&
+ update_dependent ();
+
+ void
+ update_dependent (const bool&);
+
+ const bool&
+ leave_dependent () const;
+
+ bool&
+ leave_dependent ();
+
+ void
+ leave_dependent (const bool&);
+
+ const bool&
+ configure_only () const;
+
+ bool&
+ configure_only ();
+
+ void
+ configure_only (const bool&);
+
+ const bool&
+ print_only () const;
+
+ bool&
+ print_only ();
+
+ void
+ print_only (const bool&);
+
+ const string&
+ plan () const;
+
+ string&
+ plan ();
+
+ void
+ plan (const string&);
+
+ bool
+ plan_specified () const;
+
+ void
+ plan_specified (bool);
+
+ const bool&
+ no_fetch () const;
+
+ bool&
+ no_fetch ();
+
+ void
+ no_fetch (const bool&);
+
+ const bool&
+ fetch_shallow () const;
+
+ bool&
+ fetch_shallow ();
+
+ void
+ fetch_shallow (const bool&);
+
+ const strings&
+ mask_repository () const;
+
+ strings&
+ mask_repository ();
+
+ void
+ mask_repository (const strings&);
+
+ bool
+ mask_repository_specified () const;
+
+ void
+ mask_repository_specified (bool);
+
+ const strings&
+ mask_repository_uuid () const;
+
+ strings&
+ mask_repository_uuid ();
+
+ void
+ mask_repository_uuid (const strings&);
+
+ bool
+ mask_repository_uuid_specified () const;
+
+ void
+ mask_repository_uuid_specified (bool);
+
+ const bool&
+ no_refinement () const;
+
+ bool&
+ no_refinement ();
+
+ void
+ no_refinement (const bool&);
+
+ const bool&
+ no_move () const;
+
+ bool&
+ no_move ();
+
+ void
+ no_move (const bool&);
+
+ const uint16_t&
+ noop_exit () const;
+
+ uint16_t&
+ noop_exit ();
+
+ void
+ noop_exit (const uint16_t&);
+
+ bool
+ noop_exit_specified () const;
+
+ void
+ noop_exit_specified (bool);
+
+ const string&
+ rebuild_checksum () const;
+
+ string&
+ rebuild_checksum ();
+
+ void
+ rebuild_checksum (const string&);
+
+ bool
+ rebuild_checksum_specified () const;
+
+ void
+ rebuild_checksum_specified (bool);
+
+ const uint16_t&
+ no_private_config () const;
+
+ uint16_t&
+ no_private_config ();
+
+ void
+ no_private_config (const uint16_t&);
+
+ bool
+ no_private_config_specified () const;
+
+ void
+ no_private_config_specified (bool);
+
+ const bool&
+ sys_no_query () const;
+
+ bool&
+ sys_no_query ();
+
+ void
+ sys_no_query (const bool&);
+
+ const bool&
+ sys_install () const;
+
+ bool&
+ sys_install ();
+
+ void
+ sys_install (const bool&);
+
+ const bool&
+ sys_no_fetch () const;
+
+ bool&
+ sys_no_fetch ();
+
+ void
+ sys_no_fetch (const bool&);
+
+ const bool&
+ sys_no_stub () const;
+
+ bool&
+ sys_no_stub ();
+
+ void
+ sys_no_stub (const bool&);
+
+ const bool&
+ sys_yes () const;
+
+ bool&
+ sys_yes ();
+
+ void
+ sys_yes (const bool&);
+
+ const string&
+ sys_sudo () const;
+
+ string&
+ sys_sudo ();
+
+ void
+ sys_sudo (const string&);
+
+ bool
+ sys_sudo_specified () const;
+
+ void
+ sys_sudo_specified (bool);
+
+ const string&
+ sys_distribution () const;
+
+ string&
+ sys_distribution ();
+
+ void
+ sys_distribution (const string&);
+
+ bool
+ sys_distribution_specified () const;
+
+ void
+ sys_distribution_specified (bool);
+
+ const string&
+ sys_architecture () const;
+
+ string&
+ sys_architecture ();
+
+ void
+ sys_architecture (const string&);
+
+ bool
+ sys_architecture_specified () const;
+
+ void
+ sys_architecture_specified (bool);
+
+ const dir_paths&
+ directory () const;
+
+ dir_paths&
+ directory ();
+
+ void
+ directory (const dir_paths&);
+
+ bool
+ directory_specified () const;
+
+ void
+ directory_specified (bool);
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool yes_;
+ string for__;
+ bool for__specified_;
+ bool keep_unused_;
+ bool update_dependent_;
+ bool leave_dependent_;
+ bool configure_only_;
+ bool print_only_;
+ string plan_;
+ bool plan_specified_;
+ bool no_fetch_;
+ bool fetch_shallow_;
+ strings mask_repository_;
+ bool mask_repository_specified_;
+ strings mask_repository_uuid_;
+ bool mask_repository_uuid_specified_;
+ bool no_refinement_;
+ bool no_move_;
+ uint16_t noop_exit_;
+ bool noop_exit_specified_;
+ string rebuild_checksum_;
+ bool rebuild_checksum_specified_;
+ uint16_t no_private_config_;
+ bool no_private_config_specified_;
+ bool sys_no_query_;
+ bool sys_install_;
+ bool sys_no_fetch_;
+ bool sys_no_stub_;
+ bool sys_yes_;
+ string sys_sudo_;
+ bool sys_sudo_specified_;
+ string sys_distribution_;
+ bool sys_distribution_specified_;
+ string sys_architecture_;
+ bool sys_architecture_specified_;
+ dir_paths directory_;
+ bool directory_specified_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_build_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-build-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_BUILD_OPTIONS_HXX
diff --git a/bpkg/pkg-build-options.ixx b/bpkg/pkg-build-options.ixx
new file mode 100644
index 0000000..7b0da30
--- /dev/null
+++ b/bpkg/pkg-build-options.ixx
@@ -0,0 +1,1014 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_build_pkg_options
+ //
+
+ inline const bool& pkg_build_pkg_options::
+ upgrade () const
+ {
+ return this->upgrade_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ upgrade ()
+ {
+ return this->upgrade_;
+ }
+
+ inline void pkg_build_pkg_options::
+ upgrade (const bool& x)
+ {
+ this->upgrade_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ patch () const
+ {
+ return this->patch_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ patch ()
+ {
+ return this->patch_;
+ }
+
+ inline void pkg_build_pkg_options::
+ patch (const bool& x)
+ {
+ this->patch_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ deorphan () const
+ {
+ return this->deorphan_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ deorphan ()
+ {
+ return this->deorphan_;
+ }
+
+ inline void pkg_build_pkg_options::
+ deorphan (const bool& x)
+ {
+ this->deorphan_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ immediate () const
+ {
+ return this->immediate_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ immediate ()
+ {
+ return this->immediate_;
+ }
+
+ inline void pkg_build_pkg_options::
+ immediate (const bool& x)
+ {
+ this->immediate_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ recursive () const
+ {
+ return this->recursive_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ recursive ()
+ {
+ return this->recursive_;
+ }
+
+ inline void pkg_build_pkg_options::
+ recursive (const bool& x)
+ {
+ this->recursive_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ upgrade_immediate () const
+ {
+ return this->upgrade_immediate_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ upgrade_immediate ()
+ {
+ return this->upgrade_immediate_;
+ }
+
+ inline void pkg_build_pkg_options::
+ upgrade_immediate (const bool& x)
+ {
+ this->upgrade_immediate_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ patch_immediate () const
+ {
+ return this->patch_immediate_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ patch_immediate ()
+ {
+ return this->patch_immediate_;
+ }
+
+ inline void pkg_build_pkg_options::
+ patch_immediate (const bool& x)
+ {
+ this->patch_immediate_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ deorphan_immediate () const
+ {
+ return this->deorphan_immediate_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ deorphan_immediate ()
+ {
+ return this->deorphan_immediate_;
+ }
+
+ inline void pkg_build_pkg_options::
+ deorphan_immediate (const bool& x)
+ {
+ this->deorphan_immediate_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ upgrade_recursive () const
+ {
+ return this->upgrade_recursive_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ upgrade_recursive ()
+ {
+ return this->upgrade_recursive_;
+ }
+
+ inline void pkg_build_pkg_options::
+ upgrade_recursive (const bool& x)
+ {
+ this->upgrade_recursive_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ patch_recursive () const
+ {
+ return this->patch_recursive_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ patch_recursive ()
+ {
+ return this->patch_recursive_;
+ }
+
+ inline void pkg_build_pkg_options::
+ patch_recursive (const bool& x)
+ {
+ this->patch_recursive_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ deorphan_recursive () const
+ {
+ return this->deorphan_recursive_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ deorphan_recursive ()
+ {
+ return this->deorphan_recursive_;
+ }
+
+ inline void pkg_build_pkg_options::
+ deorphan_recursive (const bool& x)
+ {
+ this->deorphan_recursive_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ dependency () const
+ {
+ return this->dependency_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ dependency ()
+ {
+ return this->dependency_;
+ }
+
+ inline void pkg_build_pkg_options::
+ dependency (const bool& x)
+ {
+ this->dependency_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ keep_out () const
+ {
+ return this->keep_out_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ keep_out ()
+ {
+ return this->keep_out_;
+ }
+
+ inline void pkg_build_pkg_options::
+ keep_out (const bool& x)
+ {
+ this->keep_out_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ disfigure () const
+ {
+ return this->disfigure_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ disfigure ()
+ {
+ return this->disfigure_;
+ }
+
+ inline void pkg_build_pkg_options::
+ disfigure (const bool& x)
+ {
+ this->disfigure_ = x;
+ }
+
+ inline const dir_path& pkg_build_pkg_options::
+ checkout_root () const
+ {
+ return this->checkout_root_;
+ }
+
+ inline dir_path& pkg_build_pkg_options::
+ checkout_root ()
+ {
+ return this->checkout_root_;
+ }
+
+ inline void pkg_build_pkg_options::
+ checkout_root (const dir_path& x)
+ {
+ this->checkout_root_ = x;
+ }
+
+ inline bool pkg_build_pkg_options::
+ checkout_root_specified () const
+ {
+ return this->checkout_root_specified_;
+ }
+
+ inline void pkg_build_pkg_options::
+ checkout_root_specified (bool x)
+ {
+ this->checkout_root_specified_ = x;
+ }
+
+ inline const bool& pkg_build_pkg_options::
+ checkout_purge () const
+ {
+ return this->checkout_purge_;
+ }
+
+ inline bool& pkg_build_pkg_options::
+ checkout_purge ()
+ {
+ return this->checkout_purge_;
+ }
+
+ inline void pkg_build_pkg_options::
+ checkout_purge (const bool& x)
+ {
+ this->checkout_purge_ = x;
+ }
+
+ inline const strings& pkg_build_pkg_options::
+ config_name () const
+ {
+ return this->config_name_;
+ }
+
+ inline strings& pkg_build_pkg_options::
+ config_name ()
+ {
+ return this->config_name_;
+ }
+
+ inline void pkg_build_pkg_options::
+ config_name (const strings& x)
+ {
+ this->config_name_ = x;
+ }
+
+ inline bool pkg_build_pkg_options::
+ config_name_specified () const
+ {
+ return this->config_name_specified_;
+ }
+
+ inline void pkg_build_pkg_options::
+ config_name_specified (bool x)
+ {
+ this->config_name_specified_ = x;
+ }
+
+ inline const vector<uint64_t>& pkg_build_pkg_options::
+ config_id () const
+ {
+ return this->config_id_;
+ }
+
+ inline vector<uint64_t>& pkg_build_pkg_options::
+ config_id ()
+ {
+ return this->config_id_;
+ }
+
+ inline void pkg_build_pkg_options::
+ config_id (const vector<uint64_t>& x)
+ {
+ this->config_id_ = x;
+ }
+
+ inline bool pkg_build_pkg_options::
+ config_id_specified () const
+ {
+ return this->config_id_specified_;
+ }
+
+ inline void pkg_build_pkg_options::
+ config_id_specified (bool x)
+ {
+ this->config_id_specified_ = x;
+ }
+
+ inline const vector<uuid>& pkg_build_pkg_options::
+ config_uuid () const
+ {
+ return this->config_uuid_;
+ }
+
+ inline vector<uuid>& pkg_build_pkg_options::
+ config_uuid ()
+ {
+ return this->config_uuid_;
+ }
+
+ inline void pkg_build_pkg_options::
+ config_uuid (const vector<uuid>& x)
+ {
+ this->config_uuid_ = x;
+ }
+
+ inline bool pkg_build_pkg_options::
+ config_uuid_specified () const
+ {
+ return this->config_uuid_specified_;
+ }
+
+ inline void pkg_build_pkg_options::
+ config_uuid_specified (bool x)
+ {
+ this->config_uuid_specified_ = x;
+ }
+
+ // pkg_build_options
+ //
+
+ inline const bool& pkg_build_options::
+ yes () const
+ {
+ return this->yes_;
+ }
+
+ inline bool& pkg_build_options::
+ yes ()
+ {
+ return this->yes_;
+ }
+
+ inline void pkg_build_options::
+ yes (const bool& x)
+ {
+ this->yes_ = x;
+ }
+
+ inline const string& pkg_build_options::
+ for_ () const
+ {
+ return this->for__;
+ }
+
+ inline string& pkg_build_options::
+ for_ ()
+ {
+ return this->for__;
+ }
+
+ inline void pkg_build_options::
+ for_ (const string& x)
+ {
+ this->for__ = x;
+ }
+
+ inline bool pkg_build_options::
+ for__specified () const
+ {
+ return this->for__specified_;
+ }
+
+ inline void pkg_build_options::
+ for__specified (bool x)
+ {
+ this->for__specified_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ keep_unused () const
+ {
+ return this->keep_unused_;
+ }
+
+ inline bool& pkg_build_options::
+ keep_unused ()
+ {
+ return this->keep_unused_;
+ }
+
+ inline void pkg_build_options::
+ keep_unused (const bool& x)
+ {
+ this->keep_unused_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ update_dependent () const
+ {
+ return this->update_dependent_;
+ }
+
+ inline bool& pkg_build_options::
+ update_dependent ()
+ {
+ return this->update_dependent_;
+ }
+
+ inline void pkg_build_options::
+ update_dependent (const bool& x)
+ {
+ this->update_dependent_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ leave_dependent () const
+ {
+ return this->leave_dependent_;
+ }
+
+ inline bool& pkg_build_options::
+ leave_dependent ()
+ {
+ return this->leave_dependent_;
+ }
+
+ inline void pkg_build_options::
+ leave_dependent (const bool& x)
+ {
+ this->leave_dependent_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ configure_only () const
+ {
+ return this->configure_only_;
+ }
+
+ inline bool& pkg_build_options::
+ configure_only ()
+ {
+ return this->configure_only_;
+ }
+
+ inline void pkg_build_options::
+ configure_only (const bool& x)
+ {
+ this->configure_only_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ print_only () const
+ {
+ return this->print_only_;
+ }
+
+ inline bool& pkg_build_options::
+ print_only ()
+ {
+ return this->print_only_;
+ }
+
+ inline void pkg_build_options::
+ print_only (const bool& x)
+ {
+ this->print_only_ = x;
+ }
+
+ inline const string& pkg_build_options::
+ plan () const
+ {
+ return this->plan_;
+ }
+
+ inline string& pkg_build_options::
+ plan ()
+ {
+ return this->plan_;
+ }
+
+ inline void pkg_build_options::
+ plan (const string& x)
+ {
+ this->plan_ = x;
+ }
+
+ inline bool pkg_build_options::
+ plan_specified () const
+ {
+ return this->plan_specified_;
+ }
+
+ inline void pkg_build_options::
+ plan_specified (bool x)
+ {
+ this->plan_specified_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ no_fetch () const
+ {
+ return this->no_fetch_;
+ }
+
+ inline bool& pkg_build_options::
+ no_fetch ()
+ {
+ return this->no_fetch_;
+ }
+
+ inline void pkg_build_options::
+ no_fetch (const bool& x)
+ {
+ this->no_fetch_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ fetch_shallow () const
+ {
+ return this->fetch_shallow_;
+ }
+
+ inline bool& pkg_build_options::
+ fetch_shallow ()
+ {
+ return this->fetch_shallow_;
+ }
+
+ inline void pkg_build_options::
+ fetch_shallow (const bool& x)
+ {
+ this->fetch_shallow_ = x;
+ }
+
+ inline const strings& pkg_build_options::
+ mask_repository () const
+ {
+ return this->mask_repository_;
+ }
+
+ inline strings& pkg_build_options::
+ mask_repository ()
+ {
+ return this->mask_repository_;
+ }
+
+ inline void pkg_build_options::
+ mask_repository (const strings& x)
+ {
+ this->mask_repository_ = x;
+ }
+
+ inline bool pkg_build_options::
+ mask_repository_specified () const
+ {
+ return this->mask_repository_specified_;
+ }
+
+ inline void pkg_build_options::
+ mask_repository_specified (bool x)
+ {
+ this->mask_repository_specified_ = x;
+ }
+
+ inline const strings& pkg_build_options::
+ mask_repository_uuid () const
+ {
+ return this->mask_repository_uuid_;
+ }
+
+ inline strings& pkg_build_options::
+ mask_repository_uuid ()
+ {
+ return this->mask_repository_uuid_;
+ }
+
+ inline void pkg_build_options::
+ mask_repository_uuid (const strings& x)
+ {
+ this->mask_repository_uuid_ = x;
+ }
+
+ inline bool pkg_build_options::
+ mask_repository_uuid_specified () const
+ {
+ return this->mask_repository_uuid_specified_;
+ }
+
+ inline void pkg_build_options::
+ mask_repository_uuid_specified (bool x)
+ {
+ this->mask_repository_uuid_specified_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ no_refinement () const
+ {
+ return this->no_refinement_;
+ }
+
+ inline bool& pkg_build_options::
+ no_refinement ()
+ {
+ return this->no_refinement_;
+ }
+
+ inline void pkg_build_options::
+ no_refinement (const bool& x)
+ {
+ this->no_refinement_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ no_move () const
+ {
+ return this->no_move_;
+ }
+
+ inline bool& pkg_build_options::
+ no_move ()
+ {
+ return this->no_move_;
+ }
+
+ inline void pkg_build_options::
+ no_move (const bool& x)
+ {
+ this->no_move_ = x;
+ }
+
+ inline const uint16_t& pkg_build_options::
+ noop_exit () const
+ {
+ return this->noop_exit_;
+ }
+
+ inline uint16_t& pkg_build_options::
+ noop_exit ()
+ {
+ return this->noop_exit_;
+ }
+
+ inline void pkg_build_options::
+ noop_exit (const uint16_t& x)
+ {
+ this->noop_exit_ = x;
+ }
+
+ inline bool pkg_build_options::
+ noop_exit_specified () const
+ {
+ return this->noop_exit_specified_;
+ }
+
+ inline void pkg_build_options::
+ noop_exit_specified (bool x)
+ {
+ this->noop_exit_specified_ = x;
+ }
+
+ inline const string& pkg_build_options::
+ rebuild_checksum () const
+ {
+ return this->rebuild_checksum_;
+ }
+
+ inline string& pkg_build_options::
+ rebuild_checksum ()
+ {
+ return this->rebuild_checksum_;
+ }
+
+ inline void pkg_build_options::
+ rebuild_checksum (const string& x)
+ {
+ this->rebuild_checksum_ = x;
+ }
+
+ inline bool pkg_build_options::
+ rebuild_checksum_specified () const
+ {
+ return this->rebuild_checksum_specified_;
+ }
+
+ inline void pkg_build_options::
+ rebuild_checksum_specified (bool x)
+ {
+ this->rebuild_checksum_specified_ = x;
+ }
+
+ inline const uint16_t& pkg_build_options::
+ no_private_config () const
+ {
+ return this->no_private_config_;
+ }
+
+ inline uint16_t& pkg_build_options::
+ no_private_config ()
+ {
+ return this->no_private_config_;
+ }
+
+ inline void pkg_build_options::
+ no_private_config (const uint16_t& x)
+ {
+ this->no_private_config_ = x;
+ }
+
+ inline bool pkg_build_options::
+ no_private_config_specified () const
+ {
+ return this->no_private_config_specified_;
+ }
+
+ inline void pkg_build_options::
+ no_private_config_specified (bool x)
+ {
+ this->no_private_config_specified_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ sys_no_query () const
+ {
+ return this->sys_no_query_;
+ }
+
+ inline bool& pkg_build_options::
+ sys_no_query ()
+ {
+ return this->sys_no_query_;
+ }
+
+ inline void pkg_build_options::
+ sys_no_query (const bool& x)
+ {
+ this->sys_no_query_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ sys_install () const
+ {
+ return this->sys_install_;
+ }
+
+ inline bool& pkg_build_options::
+ sys_install ()
+ {
+ return this->sys_install_;
+ }
+
+ inline void pkg_build_options::
+ sys_install (const bool& x)
+ {
+ this->sys_install_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ sys_no_fetch () const
+ {
+ return this->sys_no_fetch_;
+ }
+
+ inline bool& pkg_build_options::
+ sys_no_fetch ()
+ {
+ return this->sys_no_fetch_;
+ }
+
+ inline void pkg_build_options::
+ sys_no_fetch (const bool& x)
+ {
+ this->sys_no_fetch_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ sys_no_stub () const
+ {
+ return this->sys_no_stub_;
+ }
+
+ inline bool& pkg_build_options::
+ sys_no_stub ()
+ {
+ return this->sys_no_stub_;
+ }
+
+ inline void pkg_build_options::
+ sys_no_stub (const bool& x)
+ {
+ this->sys_no_stub_ = x;
+ }
+
+ inline const bool& pkg_build_options::
+ sys_yes () const
+ {
+ return this->sys_yes_;
+ }
+
+ inline bool& pkg_build_options::
+ sys_yes ()
+ {
+ return this->sys_yes_;
+ }
+
+ inline void pkg_build_options::
+ sys_yes (const bool& x)
+ {
+ this->sys_yes_ = x;
+ }
+
+ inline const string& pkg_build_options::
+ sys_sudo () const
+ {
+ return this->sys_sudo_;
+ }
+
+ inline string& pkg_build_options::
+ sys_sudo ()
+ {
+ return this->sys_sudo_;
+ }
+
+ inline void pkg_build_options::
+ sys_sudo (const string& x)
+ {
+ this->sys_sudo_ = x;
+ }
+
+ inline bool pkg_build_options::
+ sys_sudo_specified () const
+ {
+ return this->sys_sudo_specified_;
+ }
+
+ inline void pkg_build_options::
+ sys_sudo_specified (bool x)
+ {
+ this->sys_sudo_specified_ = x;
+ }
+
+ inline const string& pkg_build_options::
+ sys_distribution () const
+ {
+ return this->sys_distribution_;
+ }
+
+ inline string& pkg_build_options::
+ sys_distribution ()
+ {
+ return this->sys_distribution_;
+ }
+
+ inline void pkg_build_options::
+ sys_distribution (const string& x)
+ {
+ this->sys_distribution_ = x;
+ }
+
+ inline bool pkg_build_options::
+ sys_distribution_specified () const
+ {
+ return this->sys_distribution_specified_;
+ }
+
+ inline void pkg_build_options::
+ sys_distribution_specified (bool x)
+ {
+ this->sys_distribution_specified_ = x;
+ }
+
+ inline const string& pkg_build_options::
+ sys_architecture () const
+ {
+ return this->sys_architecture_;
+ }
+
+ inline string& pkg_build_options::
+ sys_architecture ()
+ {
+ return this->sys_architecture_;
+ }
+
+ inline void pkg_build_options::
+ sys_architecture (const string& x)
+ {
+ this->sys_architecture_ = x;
+ }
+
+ inline bool pkg_build_options::
+ sys_architecture_specified () const
+ {
+ return this->sys_architecture_specified_;
+ }
+
+ inline void pkg_build_options::
+ sys_architecture_specified (bool x)
+ {
+ this->sys_architecture_specified_ = x;
+ }
+
+ inline const dir_paths& pkg_build_options::
+ directory () const
+ {
+ return this->directory_;
+ }
+
+ inline dir_paths& pkg_build_options::
+ directory ()
+ {
+ return this->directory_;
+ }
+
+ inline void pkg_build_options::
+ directory (const dir_paths& x)
+ {
+ this->directory_ = x;
+ }
+
+ inline bool pkg_build_options::
+ directory_specified () const
+ {
+ return this->directory_specified_;
+ }
+
+ inline void pkg_build_options::
+ directory_specified (bool x)
+ {
+ this->directory_specified_ = x;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-checkout-options.cxx b/bpkg/pkg-checkout-options.cxx
new file mode 100644
index 0000000..b8ad0d9
--- /dev/null
+++ b/bpkg/pkg-checkout-options.cxx
@@ -0,0 +1,728 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-checkout-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_checkout_options
+ //
+
+ pkg_checkout_options::
+ pkg_checkout_options ()
+ : replace_ (),
+ output_root_ (),
+ output_root_specified_ (false),
+ output_purge_ ()
+ {
+ }
+
+ bool pkg_checkout_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_checkout_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_checkout_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_checkout_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_checkout_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_checkout_options::
+ merge (const pkg_checkout_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.replace_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->replace_, a.replace_);
+ }
+
+ if (a.output_root_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->output_root_, a.output_root_);
+ this->output_root_specified_ = true;
+ }
+
+ if (a.output_purge_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->output_purge_, a.output_purge_);
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_checkout_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-CHECKOUT OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--replace\033[0m|\033[1m-r\033[0m Replace the source directory if the package is" << ::std::endl
+ << " already fetched or unpacked." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--output-root\033[0m \033[4mdir\033[0m Check out the package into the specified directory" << ::std::endl
+ << " rather than into the configuration directory. Note" << ::std::endl
+ << " that the package source is placed into the" << ::std::endl
+ << " \033[4mpackage\033[0m\033[1m-\033[0m\033[4mversion\033[0m\033[0m subdirectory of this directory." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--output-purge\033[0m Remove the checked out package (source) directory" << ::std::endl
+ << " when the package is purged." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_checkout_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_checkout_options_map;
+
+ static _cli_pkg_checkout_options_map _cli_pkg_checkout_options_map_;
+
+ struct _cli_pkg_checkout_options_map_init
+ {
+ _cli_pkg_checkout_options_map_init ()
+ {
+ _cli_pkg_checkout_options_map_["--replace"] =
+ &::bpkg::cli::thunk< pkg_checkout_options, &pkg_checkout_options::replace_ >;
+ _cli_pkg_checkout_options_map_["-r"] =
+ &::bpkg::cli::thunk< pkg_checkout_options, &pkg_checkout_options::replace_ >;
+ _cli_pkg_checkout_options_map_["--output-root"] =
+ &::bpkg::cli::thunk< pkg_checkout_options, dir_path, &pkg_checkout_options::output_root_,
+ &pkg_checkout_options::output_root_specified_ >;
+ _cli_pkg_checkout_options_map_["--output-purge"] =
+ &::bpkg::cli::thunk< pkg_checkout_options, &pkg_checkout_options::output_purge_ >;
+ }
+ };
+
+ static _cli_pkg_checkout_options_map_init _cli_pkg_checkout_options_map_init_;
+
+ bool pkg_checkout_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_checkout_options_map::const_iterator i (_cli_pkg_checkout_options_map_.find (o));
+
+ if (i != _cli_pkg_checkout_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_checkout_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_checkout_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-checkout\033[0m [\033[4moptions\033[0m] \033[4mpkg\033[0m\033[1m/\033[0m\033[4mver\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-checkout\033[0m command checks out the specified package version from one of" << ::std::endl
+ << "the version control-based repositories (\033[1mbpkg-rep-add(1)\033[0m). The resulting package" << ::std::endl
+ << "state is \033[1munpacked\033[0m (\033[1mbpkg-pkg-status(1)\033[0m)." << ::std::endl
+ << ::std::endl
+ << "If the \033[1m--output-root\033[0m option is passed, then the package is checked out into the" << ::std::endl
+ << "specified directory rather than into the configuration directory. In this case," << ::std::endl
+ << "\033[1mbpkg\033[0m uses the package (source) directory in place, similar to the \033[1mpkg-unpack" << ::std::endl
+ << "--existing|-e\033[0m mode. Also, unless the \033[1m--output-purge\033[0m option is specified, \033[1mbpkg\033[0m" << ::std::endl
+ << "will not attempt to remove this directory when the package is later purged with" << ::std::endl
+ << "the \033[1mbpkg-pkg-purge(1)\033[0m command. Note also that such a package is not \033[4mexternal\033[0m" << ::std::endl
+ << "(see \033[1mbpkg-pkg-unpack(1)\033[0m for details)." << ::std::endl
+ << ::std::endl
+ << "If the \033[1m--replace|-r\033[0m option is specified, then \033[1mpkg-checkout\033[0m will replace the" << ::std::endl
+ << "archive and/or source directory of a package that is already in the \033[1munpacked\033[0m or" << ::std::endl
+ << "\033[1mfetched\033[0m state." << ::std::endl;
+
+ p = ::bpkg::pkg_checkout_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-checkout\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-checkout.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-checkout\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-checkout-options.hxx b/bpkg/pkg-checkout-options.hxx
new file mode 100644
index 0000000..53ddc1e
--- /dev/null
+++ b/bpkg/pkg-checkout-options.hxx
@@ -0,0 +1,125 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_CHECKOUT_OPTIONS_HXX
+#define BPKG_PKG_CHECKOUT_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_checkout_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_checkout_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_checkout_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ replace () const;
+
+ const dir_path&
+ output_root () const;
+
+ bool
+ output_root_specified () const;
+
+ const bool&
+ output_purge () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool replace_;
+ dir_path output_root_;
+ bool output_root_specified_;
+ bool output_purge_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_checkout_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-checkout-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_CHECKOUT_OPTIONS_HXX
diff --git a/bpkg/pkg-checkout-options.ixx b/bpkg/pkg-checkout-options.ixx
new file mode 100644
index 0000000..af1e0c4
--- /dev/null
+++ b/bpkg/pkg-checkout-options.ixx
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_checkout_options
+ //
+
+ inline const bool& pkg_checkout_options::
+ replace () const
+ {
+ return this->replace_;
+ }
+
+ inline const dir_path& pkg_checkout_options::
+ output_root () const
+ {
+ return this->output_root_;
+ }
+
+ inline bool pkg_checkout_options::
+ output_root_specified () const
+ {
+ return this->output_root_specified_;
+ }
+
+ inline const bool& pkg_checkout_options::
+ output_purge () const
+ {
+ return this->output_purge_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-clean-options.cxx b/bpkg/pkg-clean-options.cxx
new file mode 100644
index 0000000..482f279
--- /dev/null
+++ b/bpkg/pkg-clean-options.cxx
@@ -0,0 +1,742 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-clean-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_clean_options
+ //
+
+ pkg_clean_options::
+ pkg_clean_options ()
+ : all_ (),
+ all_pattern_ (),
+ all_pattern_specified_ (false),
+ immediate_ (),
+ recursive_ ()
+ {
+ }
+
+ bool pkg_clean_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_clean_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_clean_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_clean_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_clean_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_clean_options::
+ merge (const pkg_clean_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.all_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->all_, a.all_);
+ }
+
+ if (a.all_pattern_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->all_pattern_, a.all_pattern_);
+ this->all_pattern_specified_ = true;
+ }
+
+ if (a.immediate_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->immediate_, a.immediate_);
+ }
+
+ if (a.recursive_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->recursive_, a.recursive_);
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_clean_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-CLEAN OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all\033[0m|\033[1m-a\033[0m Clean all held packages." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all-pattern\033[0m \033[4mpattern\033[0m Clean held packages that match the specified wildcard" << ::std::endl
+ << " pattern. Repeat this option to match multiple" << ::std::endl
+ << " patterns. Note that you may need to quote the pattern" << ::std::endl
+ << " to prevent expansion by your shell." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--immediate\033[0m|\033[1m-i\033[0m Also clean immediate dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--recursive\033[0m|\033[1m-r\033[0m Also clean all dependencies, recursively." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_clean_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_clean_options_map;
+
+ static _cli_pkg_clean_options_map _cli_pkg_clean_options_map_;
+
+ struct _cli_pkg_clean_options_map_init
+ {
+ _cli_pkg_clean_options_map_init ()
+ {
+ _cli_pkg_clean_options_map_["--all"] =
+ &::bpkg::cli::thunk< pkg_clean_options, &pkg_clean_options::all_ >;
+ _cli_pkg_clean_options_map_["-a"] =
+ &::bpkg::cli::thunk< pkg_clean_options, &pkg_clean_options::all_ >;
+ _cli_pkg_clean_options_map_["--all-pattern"] =
+ &::bpkg::cli::thunk< pkg_clean_options, strings, &pkg_clean_options::all_pattern_,
+ &pkg_clean_options::all_pattern_specified_ >;
+ _cli_pkg_clean_options_map_["--immediate"] =
+ &::bpkg::cli::thunk< pkg_clean_options, &pkg_clean_options::immediate_ >;
+ _cli_pkg_clean_options_map_["-i"] =
+ &::bpkg::cli::thunk< pkg_clean_options, &pkg_clean_options::immediate_ >;
+ _cli_pkg_clean_options_map_["--recursive"] =
+ &::bpkg::cli::thunk< pkg_clean_options, &pkg_clean_options::recursive_ >;
+ _cli_pkg_clean_options_map_["-r"] =
+ &::bpkg::cli::thunk< pkg_clean_options, &pkg_clean_options::recursive_ >;
+ }
+ };
+
+ static _cli_pkg_clean_options_map_init _cli_pkg_clean_options_map_init_;
+
+ bool pkg_clean_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_clean_options_map::const_iterator i (_cli_pkg_clean_options_map_.find (o));
+
+ if (i != _cli_pkg_clean_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_clean_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_clean_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-clean\033[0m|\033[1mclean\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] \033[4mpkg\033[0m..." << ::std::endl
+ << "\033[1mbpkg pkg-clean\033[0m|\033[1mclean\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] \033[1m--all\033[0m|\033[1m-a\033[0m" << ::std::endl
+ << "\033[1mbpkg pkg-clean\033[0m|\033[1mclean\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] (\033[1m--all-pattern\033[0m <pattern>)...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-clean\033[0m command cleans the specified packages (the first form), all the" << ::std::endl
+ << "held packages (the second form, see \033[1mbpkg-pkg-status(1)\033[0m), or all the held" << ::std::endl
+ << "packages that match any of the specified wildcard patterns (the third form)." << ::std::endl
+ << "Additionally, immediate or all dependencies of these packages can be also" << ::std::endl
+ << "cleaned by specifying the \033[1m--immediate\033[0m|\033[1m-i\033[0m\033[0m or \033[1m--recursive\033[0m|\033[1m-r\033[0m\033[0m options," << ::std::endl
+ << "respectively. Underneath, this command doesn't do much more than run \033[1mb clean\033[0m." << ::std::endl
+ << "In the first form the specified packages must have been previously configured" << ::std::endl
+ << "with \033[1mbpkg-pkg-build(1)\033[0m or \033[1mbpkg-pkg-configure(1)\033[0m." << ::std::endl
+ << ::std::endl
+ << "Additional command line variables (\033[4mvars\033[0m, normally \033[1mconfig.*\033[0m) can be passed to" << ::std::endl
+ << "the build system. Such variables apply to all the specified packages but can" << ::std::endl
+ << "also be specified to only apply to specific packages using the argument" << ::std::endl
+ << "grouping mechanism (see \033[1mbpkg-argument-grouping(1)\033[0m for details)." << ::std::endl;
+
+ p = ::bpkg::pkg_clean_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-clean\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-clean.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-clean\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-clean-options.hxx b/bpkg/pkg-clean-options.hxx
new file mode 100644
index 0000000..13a1e73
--- /dev/null
+++ b/bpkg/pkg-clean-options.hxx
@@ -0,0 +1,129 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_CLEAN_OPTIONS_HXX
+#define BPKG_PKG_CLEAN_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_clean_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_clean_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_clean_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ all () const;
+
+ const strings&
+ all_pattern () const;
+
+ bool
+ all_pattern_specified () const;
+
+ const bool&
+ immediate () const;
+
+ const bool&
+ recursive () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool all_;
+ strings all_pattern_;
+ bool all_pattern_specified_;
+ bool immediate_;
+ bool recursive_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_clean_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-clean-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_CLEAN_OPTIONS_HXX
diff --git a/bpkg/pkg-clean-options.ixx b/bpkg/pkg-clean-options.ixx
new file mode 100644
index 0000000..afa49a1
--- /dev/null
+++ b/bpkg/pkg-clean-options.ixx
@@ -0,0 +1,51 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_clean_options
+ //
+
+ inline const bool& pkg_clean_options::
+ all () const
+ {
+ return this->all_;
+ }
+
+ inline const strings& pkg_clean_options::
+ all_pattern () const
+ {
+ return this->all_pattern_;
+ }
+
+ inline bool pkg_clean_options::
+ all_pattern_specified () const
+ {
+ return this->all_pattern_specified_;
+ }
+
+ inline const bool& pkg_clean_options::
+ immediate () const
+ {
+ return this->immediate_;
+ }
+
+ inline const bool& pkg_clean_options::
+ recursive () const
+ {
+ return this->recursive_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-configure-options.cxx b/bpkg/pkg-configure-options.cxx
new file mode 100644
index 0000000..8fb31cb
--- /dev/null
+++ b/bpkg/pkg-configure-options.cxx
@@ -0,0 +1,679 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-configure-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_configure_options
+ //
+
+ pkg_configure_options::
+ pkg_configure_options ()
+ {
+ }
+
+ bool pkg_configure_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_configure_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_configure_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_configure_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_configure_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_configure_options::
+ merge (const pkg_configure_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+ }
+
+ ::bpkg::cli::usage_para pkg_configure_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-CONFIGURE OPTIONS\033[0m" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_configure_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_configure_options_map;
+
+ static _cli_pkg_configure_options_map _cli_pkg_configure_options_map_;
+
+ struct _cli_pkg_configure_options_map_init
+ {
+ _cli_pkg_configure_options_map_init ()
+ {
+ }
+ };
+
+ static _cli_pkg_configure_options_map_init _cli_pkg_configure_options_map_init_;
+
+ bool pkg_configure_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_configure_options_map::const_iterator i (_cli_pkg_configure_options_map_.find (o));
+
+ if (i != _cli_pkg_configure_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_configure_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_configure_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-configure\033[0m [\033[4moptions\033[0m] [\033[4mcfg-var\033[0m...] \033[4mpkg\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-configure\033[0m command configures either the previously unpacked" << ::std::endl
+ << "(\033[1mbpkg-pkg-unpack(1)\033[0m, \033[1mbpkg-pkg-checkout(1)\033[0m) source code package or a package" << ::std::endl
+ << "that is present in the system." << ::std::endl
+ << ::std::endl
+ << "A source code package inherits the common \033[1mbuild2\033[0m configuration values that were" << ::std::endl
+ << "specified when creating the configuration (\033[1mbpkg-cfg-create(1)\033[0m). Additional" << ::std::endl
+ << "package-specific configuration variables can be passed to \033[1mpkg-configure\033[0m" << ::std::endl
+ << "(\033[4mcfg-var\033[0m)." << ::std::endl
+ << ::std::endl
+ << "A system package is specified using the \033[1msys:\033[0m\033[4mpkg\033[0m[/\033[4mver\033[0m]\033[0m syntax. If the package" << ::std::endl
+ << "version (\033[4mver\033[0m) is not specified, then it is considered to be unknown but" << ::std::endl
+ << "satisfying any dependency constraint. Such a version is displayed as \033[1m*\033[0m." << ::std::endl;
+
+ p = ::bpkg::pkg_configure_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-configure\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-configure.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-configure\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-configure-options.hxx b/bpkg/pkg-configure-options.hxx
new file mode 100644
index 0000000..e990f9c
--- /dev/null
+++ b/bpkg/pkg-configure-options.hxx
@@ -0,0 +1,109 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_CONFIGURE_OPTIONS_HXX
+#define BPKG_PKG_CONFIGURE_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_configure_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_configure_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_configure_options&);
+
+ // Option accessors.
+ //
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_configure_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-configure-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_CONFIGURE_OPTIONS_HXX
diff --git a/bpkg/pkg-configure-options.ixx b/bpkg/pkg-configure-options.ixx
new file mode 100644
index 0000000..645428c
--- /dev/null
+++ b/bpkg/pkg-configure-options.ixx
@@ -0,0 +1,21 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_configure_options
+ //
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-disfigure-options.cxx b/bpkg/pkg-disfigure-options.cxx
new file mode 100644
index 0000000..4a15052
--- /dev/null
+++ b/bpkg/pkg-disfigure-options.cxx
@@ -0,0 +1,701 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-disfigure-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_disfigure_options
+ //
+
+ pkg_disfigure_options::
+ pkg_disfigure_options ()
+ : keep_out_ (),
+ keep_config_ ()
+ {
+ }
+
+ bool pkg_disfigure_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_disfigure_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_disfigure_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_disfigure_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_disfigure_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_disfigure_options::
+ merge (const pkg_disfigure_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.keep_out_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->keep_out_, a.keep_out_);
+ }
+
+ if (a.keep_config_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->keep_config_, a.keep_config_);
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_disfigure_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-DISFIGURE OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--keep-out\033[0m Don't clean the package's output directory." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--keep-config\033[0m Don't remove the package's build system configuration" << ::std::endl
+ << " (\033[1mconfig.build\033[0m)." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_disfigure_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_disfigure_options_map;
+
+ static _cli_pkg_disfigure_options_map _cli_pkg_disfigure_options_map_;
+
+ struct _cli_pkg_disfigure_options_map_init
+ {
+ _cli_pkg_disfigure_options_map_init ()
+ {
+ _cli_pkg_disfigure_options_map_["--keep-out"] =
+ &::bpkg::cli::thunk< pkg_disfigure_options, &pkg_disfigure_options::keep_out_ >;
+ _cli_pkg_disfigure_options_map_["--keep-config"] =
+ &::bpkg::cli::thunk< pkg_disfigure_options, &pkg_disfigure_options::keep_config_ >;
+ }
+ };
+
+ static _cli_pkg_disfigure_options_map_init _cli_pkg_disfigure_options_map_init_;
+
+ bool pkg_disfigure_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_disfigure_options_map::const_iterator i (_cli_pkg_disfigure_options_map_.find (o));
+
+ if (i != _cli_pkg_disfigure_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_disfigure_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_disfigure_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-disfigure\033[0m [\033[4moptions\033[0m] \033[4mpkg\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-disfigure\033[0m command disfigures the previously configured (via" << ::std::endl
+ << "\033[1mbpkg-pkg-build(1)\033[0m or \033[1mbpkg-pkg-configure(1)\033[0m) package. A source code package is" << ::std::endl
+ << "returned to the \033[1munpacked\033[0m state. A system package is removed from the" << ::std::endl
+ << "configuration." << ::std::endl
+ << ::std::endl
+ << "By default \033[1mpkg-disfigure\033[0m will remove the package's build system configuration" << ::std::endl
+ << "(\033[1mconfig.build\033[0m) and also clean its output directory. This behavior can be" << ::std::endl
+ << "suppressed with the \033[1m--keep-config\033[0m and \033[1m--keep-out\033[0m options, respectively, for" << ::std::endl
+ << "example, if the package is to be reconfigured." << ::std::endl;
+
+ p = ::bpkg::pkg_disfigure_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-disfigure\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-disfigure.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-disfigure\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-disfigure-options.hxx b/bpkg/pkg-disfigure-options.hxx
new file mode 100644
index 0000000..2ee4a48
--- /dev/null
+++ b/bpkg/pkg-disfigure-options.hxx
@@ -0,0 +1,117 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_DISFIGURE_OPTIONS_HXX
+#define BPKG_PKG_DISFIGURE_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_disfigure_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_disfigure_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_disfigure_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ keep_out () const;
+
+ const bool&
+ keep_config () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool keep_out_;
+ bool keep_config_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_disfigure_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-disfigure-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_DISFIGURE_OPTIONS_HXX
diff --git a/bpkg/pkg-disfigure-options.ixx b/bpkg/pkg-disfigure-options.ixx
new file mode 100644
index 0000000..9868fda
--- /dev/null
+++ b/bpkg/pkg-disfigure-options.ixx
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_disfigure_options
+ //
+
+ inline const bool& pkg_disfigure_options::
+ keep_out () const
+ {
+ return this->keep_out_;
+ }
+
+ inline const bool& pkg_disfigure_options::
+ keep_config () const
+ {
+ return this->keep_config_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-drop-options.cxx b/bpkg/pkg-drop-options.cxx
new file mode 100644
index 0000000..c9956b2
--- /dev/null
+++ b/bpkg/pkg-drop-options.cxx
@@ -0,0 +1,845 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-drop-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_drop_options
+ //
+
+ pkg_drop_options::
+ pkg_drop_options ()
+ : all_ (),
+ all_pattern_ (),
+ all_pattern_specified_ (false),
+ yes_ (),
+ no_ (),
+ keep_unused_ (),
+ drop_dependent_ (),
+ keep_dependent_ (),
+ dependent_exit_ (),
+ dependent_exit_specified_ (false),
+ disfigure_only_ (),
+ print_only_ (),
+ plan_ (),
+ plan_specified_ (false)
+ {
+ }
+
+ bool pkg_drop_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_drop_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_drop_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_drop_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_drop_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_drop_options::
+ merge (const pkg_drop_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.all_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->all_, a.all_);
+ }
+
+ if (a.all_pattern_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->all_pattern_, a.all_pattern_);
+ this->all_pattern_specified_ = true;
+ }
+
+ if (a.yes_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->yes_, a.yes_);
+ }
+
+ if (a.no_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_, a.no_);
+ }
+
+ if (a.keep_unused_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->keep_unused_, a.keep_unused_);
+ }
+
+ if (a.drop_dependent_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->drop_dependent_, a.drop_dependent_);
+ }
+
+ if (a.keep_dependent_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->keep_dependent_, a.keep_dependent_);
+ }
+
+ if (a.dependent_exit_specified_)
+ {
+ ::bpkg::cli::parser< uint16_t>::merge (
+ this->dependent_exit_, a.dependent_exit_);
+ this->dependent_exit_specified_ = true;
+ }
+
+ if (a.disfigure_only_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->disfigure_only_, a.disfigure_only_);
+ }
+
+ if (a.print_only_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->print_only_, a.print_only_);
+ }
+
+ if (a.plan_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->plan_, a.plan_);
+ this->plan_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_drop_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-DROP OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all\033[0m|\033[1m-a\033[0m Drop all held packages." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all-pattern\033[0m \033[4mpattern\033[0m Drop held packages that match the specified wildcard" << ::std::endl
+ << " pattern. Repeat this option to match multiple" << ::std::endl
+ << " patterns. Note that you may need to quote the pattern" << ::std::endl
+ << " to prevent expansion by your shell." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--yes\033[0m|\033[1m-y\033[0m Assume the answer to all prompts is \033[1myes\033[0m. Note that" << ::std::endl
+ << " this option does not apply to the dropping of" << ::std::endl
+ << " dependents; use \033[1m--drop-dependent\033[0m for that." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no\033[0m|\033[1m-n\033[0m Assume the answer to all prompts is \033[1mno\033[0m. Only makes" << ::std::endl
+ << " sense together with \033[1m--print-only|-p\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--keep-unused\033[0m|\033[1m-K\033[0m Don't drop dependency packages that were" << ::std::endl
+ << " automatically built but will no longer be used." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--drop-dependent\033[0m|\033[1m-D\033[0m Don't warn about or ask for confirmation if dropping" << ::std::endl
+ << " dependent packages." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--keep-dependent\033[0m Issue an error if attempting to drop dependent" << ::std::endl
+ << " packages." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--dependent-exit\033[0m \033[4mcode\033[0m Silently exit with the specified error code if" << ::std::endl
+ << " attempting to drop dependent packages." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--disfigure-only\033[0m Disfigure all the packages but don't purge." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--print-only\033[0m|\033[1m-p\033[0m Print to \033[1mstdout\033[0m what would be done without actually" << ::std::endl
+ << " doing anything." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--plan\033[0m \033[4mheader\033[0m Print the plan (even if \033[1m--yes\033[0m is specified) and start" << ::std::endl
+ << " it with the \033[4mheader\033[0m line (unless it is empty)." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_drop_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_drop_options_map;
+
+ static _cli_pkg_drop_options_map _cli_pkg_drop_options_map_;
+
+ struct _cli_pkg_drop_options_map_init
+ {
+ _cli_pkg_drop_options_map_init ()
+ {
+ _cli_pkg_drop_options_map_["--all"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::all_ >;
+ _cli_pkg_drop_options_map_["-a"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::all_ >;
+ _cli_pkg_drop_options_map_["--all-pattern"] =
+ &::bpkg::cli::thunk< pkg_drop_options, strings, &pkg_drop_options::all_pattern_,
+ &pkg_drop_options::all_pattern_specified_ >;
+ _cli_pkg_drop_options_map_["--yes"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::yes_ >;
+ _cli_pkg_drop_options_map_["-y"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::yes_ >;
+ _cli_pkg_drop_options_map_["--no"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::no_ >;
+ _cli_pkg_drop_options_map_["-n"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::no_ >;
+ _cli_pkg_drop_options_map_["--keep-unused"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::keep_unused_ >;
+ _cli_pkg_drop_options_map_["-K"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::keep_unused_ >;
+ _cli_pkg_drop_options_map_["--drop-dependent"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::drop_dependent_ >;
+ _cli_pkg_drop_options_map_["-D"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::drop_dependent_ >;
+ _cli_pkg_drop_options_map_["--keep-dependent"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::keep_dependent_ >;
+ _cli_pkg_drop_options_map_["--dependent-exit"] =
+ &::bpkg::cli::thunk< pkg_drop_options, uint16_t, &pkg_drop_options::dependent_exit_,
+ &pkg_drop_options::dependent_exit_specified_ >;
+ _cli_pkg_drop_options_map_["--disfigure-only"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::disfigure_only_ >;
+ _cli_pkg_drop_options_map_["--print-only"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::print_only_ >;
+ _cli_pkg_drop_options_map_["-p"] =
+ &::bpkg::cli::thunk< pkg_drop_options, &pkg_drop_options::print_only_ >;
+ _cli_pkg_drop_options_map_["--plan"] =
+ &::bpkg::cli::thunk< pkg_drop_options, string, &pkg_drop_options::plan_,
+ &pkg_drop_options::plan_specified_ >;
+ }
+ };
+
+ static _cli_pkg_drop_options_map_init _cli_pkg_drop_options_map_init_;
+
+ bool pkg_drop_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_drop_options_map::const_iterator i (_cli_pkg_drop_options_map_.find (o));
+
+ if (i != _cli_pkg_drop_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_drop_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_drop_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-drop\033[0m|\033[1mdrop\033[0m [\033[4moptions\033[0m] <pkg>..." << ::std::endl
+ << "\033[1mbpkg pkg-drop\033[0m|\033[1mdrop\033[0m [\033[4moptions\033[0m] \033[1m--all\033[0m|\033[1m-a\033[0m" << ::std::endl
+ << "\033[1mbpkg pkg-drop\033[0m|\033[1mdrop\033[0m [\033[4moptions\033[0m] (\033[1m--all-pattern\033[0m <pattern>)...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-drop\033[0m command drops from the configuration the specified packages (the" << ::std::endl
+ << "first form), all the held packages (the second form, see \033[1mbpkg-pkg-status(1)\033[0m)," << ::std::endl
+ << "or all the held packages that match any of the specified wildcard patterns (the" << ::std::endl
+ << "third form). If the packages being dropped still have dependent packages, then" << ::std::endl
+ << "those will have to be dropped as well and you will be prompted to confirm. And" << ::std::endl
+ << "if the packages being dropped have dependency packages that would otherwise no" << ::std::endl
+ << "longer be used, then they will be dropped as well unless the \033[1m--keep-unused\033[0m|\033[1m-K\033[0m\033[0m" << ::std::endl
+ << "option is specified." << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-drop\033[0m command also supports several options (described below) that allow" << ::std::endl
+ << "you to control the amount of work that will be done." << ::std::endl;
+
+ p = ::bpkg::pkg_drop_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-drop\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-drop.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-drop\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-drop-options.hxx b/bpkg/pkg-drop-options.hxx
new file mode 100644
index 0000000..e72e9fb
--- /dev/null
+++ b/bpkg/pkg-drop-options.hxx
@@ -0,0 +1,165 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_DROP_OPTIONS_HXX
+#define BPKG_PKG_DROP_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_drop_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_drop_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_drop_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ all () const;
+
+ const strings&
+ all_pattern () const;
+
+ bool
+ all_pattern_specified () const;
+
+ const bool&
+ yes () const;
+
+ const bool&
+ no () const;
+
+ const bool&
+ keep_unused () const;
+
+ const bool&
+ drop_dependent () const;
+
+ const bool&
+ keep_dependent () const;
+
+ const uint16_t&
+ dependent_exit () const;
+
+ bool
+ dependent_exit_specified () const;
+
+ const bool&
+ disfigure_only () const;
+
+ const bool&
+ print_only () const;
+
+ const string&
+ plan () const;
+
+ bool
+ plan_specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool all_;
+ strings all_pattern_;
+ bool all_pattern_specified_;
+ bool yes_;
+ bool no_;
+ bool keep_unused_;
+ bool drop_dependent_;
+ bool keep_dependent_;
+ uint16_t dependent_exit_;
+ bool dependent_exit_specified_;
+ bool disfigure_only_;
+ bool print_only_;
+ string plan_;
+ bool plan_specified_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_drop_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-drop-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_DROP_OPTIONS_HXX
diff --git a/bpkg/pkg-drop-options.ixx b/bpkg/pkg-drop-options.ixx
new file mode 100644
index 0000000..b32cb95
--- /dev/null
+++ b/bpkg/pkg-drop-options.ixx
@@ -0,0 +1,105 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_drop_options
+ //
+
+ inline const bool& pkg_drop_options::
+ all () const
+ {
+ return this->all_;
+ }
+
+ inline const strings& pkg_drop_options::
+ all_pattern () const
+ {
+ return this->all_pattern_;
+ }
+
+ inline bool pkg_drop_options::
+ all_pattern_specified () const
+ {
+ return this->all_pattern_specified_;
+ }
+
+ inline const bool& pkg_drop_options::
+ yes () const
+ {
+ return this->yes_;
+ }
+
+ inline const bool& pkg_drop_options::
+ no () const
+ {
+ return this->no_;
+ }
+
+ inline const bool& pkg_drop_options::
+ keep_unused () const
+ {
+ return this->keep_unused_;
+ }
+
+ inline const bool& pkg_drop_options::
+ drop_dependent () const
+ {
+ return this->drop_dependent_;
+ }
+
+ inline const bool& pkg_drop_options::
+ keep_dependent () const
+ {
+ return this->keep_dependent_;
+ }
+
+ inline const uint16_t& pkg_drop_options::
+ dependent_exit () const
+ {
+ return this->dependent_exit_;
+ }
+
+ inline bool pkg_drop_options::
+ dependent_exit_specified () const
+ {
+ return this->dependent_exit_specified_;
+ }
+
+ inline const bool& pkg_drop_options::
+ disfigure_only () const
+ {
+ return this->disfigure_only_;
+ }
+
+ inline const bool& pkg_drop_options::
+ print_only () const
+ {
+ return this->print_only_;
+ }
+
+ inline const string& pkg_drop_options::
+ plan () const
+ {
+ return this->plan_;
+ }
+
+ inline bool pkg_drop_options::
+ plan_specified () const
+ {
+ return this->plan_specified_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-fetch-options.cxx b/bpkg/pkg-fetch-options.cxx
new file mode 100644
index 0000000..ae911d2
--- /dev/null
+++ b/bpkg/pkg-fetch-options.cxx
@@ -0,0 +1,727 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-fetch-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_fetch_options
+ //
+
+ pkg_fetch_options::
+ pkg_fetch_options ()
+ : replace_ (),
+ existing_ (),
+ purge_ ()
+ {
+ }
+
+ bool pkg_fetch_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_fetch_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_fetch_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_fetch_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_fetch_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_fetch_options::
+ merge (const pkg_fetch_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.replace_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->replace_, a.replace_);
+ }
+
+ if (a.existing_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->existing_, a.existing_);
+ }
+
+ if (a.purge_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->purge_, a.purge_);
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_fetch_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-FETCH OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--replace\033[0m|\033[1m-r\033[0m Replace the archive if the package is already fetched" << ::std::endl
+ << " or unpacked." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--existing\033[0m|\033[1m-e\033[0m Treat the argument as an existing package archive" << ::std::endl
+ << " path rather than the package name/version to fetch." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--purge\033[0m|\033[1m-p\033[0m Remove the existing package archive when the package" << ::std::endl
+ << " is purged." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_fetch_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_fetch_options_map;
+
+ static _cli_pkg_fetch_options_map _cli_pkg_fetch_options_map_;
+
+ struct _cli_pkg_fetch_options_map_init
+ {
+ _cli_pkg_fetch_options_map_init ()
+ {
+ _cli_pkg_fetch_options_map_["--replace"] =
+ &::bpkg::cli::thunk< pkg_fetch_options, &pkg_fetch_options::replace_ >;
+ _cli_pkg_fetch_options_map_["-r"] =
+ &::bpkg::cli::thunk< pkg_fetch_options, &pkg_fetch_options::replace_ >;
+ _cli_pkg_fetch_options_map_["--existing"] =
+ &::bpkg::cli::thunk< pkg_fetch_options, &pkg_fetch_options::existing_ >;
+ _cli_pkg_fetch_options_map_["-e"] =
+ &::bpkg::cli::thunk< pkg_fetch_options, &pkg_fetch_options::existing_ >;
+ _cli_pkg_fetch_options_map_["--purge"] =
+ &::bpkg::cli::thunk< pkg_fetch_options, &pkg_fetch_options::purge_ >;
+ _cli_pkg_fetch_options_map_["-p"] =
+ &::bpkg::cli::thunk< pkg_fetch_options, &pkg_fetch_options::purge_ >;
+ }
+ };
+
+ static _cli_pkg_fetch_options_map_init _cli_pkg_fetch_options_map_init_;
+
+ bool pkg_fetch_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_fetch_options_map::const_iterator i (_cli_pkg_fetch_options_map_.find (o));
+
+ if (i != _cli_pkg_fetch_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_fetch_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_fetch_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-fetch\033[0m [\033[4moptions\033[0m] (\033[4mpkg\033[0m\033[1m/\033[0m\033[4mver\033[0m | \033[1m--existing|-e\033[0m \033[4mfile\033[0m)\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-fetch\033[0m command fetches the archive for the specified package name and" << ::std::endl
+ << "version from one of the archive-based repositories (\033[1mbpkg-rep-add(1)\033[0m). The" << ::std::endl
+ << "resulting package state is \033[1mfetched\033[0m (\033[1mbpkg-pkg-status(1)\033[0m)." << ::std::endl
+ << ::std::endl
+ << "If the \033[1m--replace|-r\033[0m option is specified, then \033[1mpkg-fetch\033[0m will replace the" << ::std::endl
+ << "archive of a package that is already in the \033[1mfetched\033[0m or \033[1munpacked\033[0m state." << ::std::endl
+ << "Otherwise, \033[1mpkg-fetch\033[0m expects the package to not exist in the configuration." << ::std::endl
+ << ::std::endl
+ << "If the \033[1m--existing|-e\033[0m option is used, then instead of the name and version" << ::std::endl
+ << "arguments, \033[1mpkg-fetch\033[0m expects a local path to an existing package archive. In" << ::std::endl
+ << "this case, \033[1mbpkg\033[0m will use the archive in place, without copying it into the" << ::std::endl
+ << "configuration directory. Also, unless the \033[1m--purge|-p\033[0m option is specified, \033[1mbpkg\033[0m" << ::std::endl
+ << "will not attempt to remove this archive when the package is later purged with" << ::std::endl
+ << "the \033[1mbpkg-pkg-purge(1)\033[0m command." << ::std::endl;
+
+ p = ::bpkg::pkg_fetch_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-fetch\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-fetch.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-fetch\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl
+ << "--purge|-p" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-fetch-options.hxx b/bpkg/pkg-fetch-options.hxx
new file mode 100644
index 0000000..99c834c
--- /dev/null
+++ b/bpkg/pkg-fetch-options.hxx
@@ -0,0 +1,121 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_FETCH_OPTIONS_HXX
+#define BPKG_PKG_FETCH_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_fetch_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_fetch_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_fetch_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ replace () const;
+
+ const bool&
+ existing () const;
+
+ const bool&
+ purge () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool replace_;
+ bool existing_;
+ bool purge_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_fetch_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-fetch-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_FETCH_OPTIONS_HXX
diff --git a/bpkg/pkg-fetch-options.ixx b/bpkg/pkg-fetch-options.ixx
new file mode 100644
index 0000000..e57a26f
--- /dev/null
+++ b/bpkg/pkg-fetch-options.ixx
@@ -0,0 +1,39 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_fetch_options
+ //
+
+ inline const bool& pkg_fetch_options::
+ replace () const
+ {
+ return this->replace_;
+ }
+
+ inline const bool& pkg_fetch_options::
+ existing () const
+ {
+ return this->existing_;
+ }
+
+ inline const bool& pkg_fetch_options::
+ purge () const
+ {
+ return this->purge_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-install-options.cxx b/bpkg/pkg-install-options.cxx
new file mode 100644
index 0000000..dcd0147
--- /dev/null
+++ b/bpkg/pkg-install-options.cxx
@@ -0,0 +1,750 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-install-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_install_options
+ //
+
+ pkg_install_options::
+ pkg_install_options ()
+ : all_ (),
+ all_pattern_ (),
+ all_pattern_specified_ (false),
+ immediate_ (),
+ recursive_ ()
+ {
+ }
+
+ bool pkg_install_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_install_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_install_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_install_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_install_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_install_options::
+ merge (const pkg_install_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.all_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->all_, a.all_);
+ }
+
+ if (a.all_pattern_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->all_pattern_, a.all_pattern_);
+ this->all_pattern_specified_ = true;
+ }
+
+ if (a.immediate_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->immediate_, a.immediate_);
+ }
+
+ if (a.recursive_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->recursive_, a.recursive_);
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_install_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-INSTALL OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all\033[0m|\033[1m-a\033[0m Install all held packages." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all-pattern\033[0m \033[4mpattern\033[0m Install held packages that match the specified" << ::std::endl
+ << " wildcard pattern. Repeat this option to match" << ::std::endl
+ << " multiple patterns. Note that you may need to quote" << ::std::endl
+ << " the pattern to prevent expansion by your shell." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--immediate\033[0m|\033[1m-i\033[0m Also install immediate dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--recursive\033[0m|\033[1m-r\033[0m Also install all dependencies, recursively." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_install_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_install_options_map;
+
+ static _cli_pkg_install_options_map _cli_pkg_install_options_map_;
+
+ struct _cli_pkg_install_options_map_init
+ {
+ _cli_pkg_install_options_map_init ()
+ {
+ _cli_pkg_install_options_map_["--all"] =
+ &::bpkg::cli::thunk< pkg_install_options, &pkg_install_options::all_ >;
+ _cli_pkg_install_options_map_["-a"] =
+ &::bpkg::cli::thunk< pkg_install_options, &pkg_install_options::all_ >;
+ _cli_pkg_install_options_map_["--all-pattern"] =
+ &::bpkg::cli::thunk< pkg_install_options, strings, &pkg_install_options::all_pattern_,
+ &pkg_install_options::all_pattern_specified_ >;
+ _cli_pkg_install_options_map_["--immediate"] =
+ &::bpkg::cli::thunk< pkg_install_options, &pkg_install_options::immediate_ >;
+ _cli_pkg_install_options_map_["-i"] =
+ &::bpkg::cli::thunk< pkg_install_options, &pkg_install_options::immediate_ >;
+ _cli_pkg_install_options_map_["--recursive"] =
+ &::bpkg::cli::thunk< pkg_install_options, &pkg_install_options::recursive_ >;
+ _cli_pkg_install_options_map_["-r"] =
+ &::bpkg::cli::thunk< pkg_install_options, &pkg_install_options::recursive_ >;
+ }
+ };
+
+ static _cli_pkg_install_options_map_init _cli_pkg_install_options_map_init_;
+
+ bool pkg_install_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_install_options_map::const_iterator i (_cli_pkg_install_options_map_.find (o));
+
+ if (i != _cli_pkg_install_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_install_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_install_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-install\033[0m|\033[1minstall\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] \033[4mpkg\033[0m..." << ::std::endl
+ << "\033[1mbpkg pkg-install\033[0m|\033[1minstall\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] \033[1m--all\033[0m|\033[1m-a\033[0m" << ::std::endl
+ << "\033[1mbpkg pkg-install\033[0m|\033[1minstall\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] (\033[1m--all-pattern\033[0m <pattern>)...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-install\033[0m command installs the specified packages (the first form), all" << ::std::endl
+ << "the held packages (the second form, see \033[1mbpkg-pkg-status(1)\033[0m), or all the held" << ::std::endl
+ << "packages that match any of the specified wildcard patterns (the third form)." << ::std::endl
+ << "Additionally, immediate or all dependencies of these packages can be also" << ::std::endl
+ << "installed by specifying the \033[1m--immediate\033[0m|\033[1m-i\033[0m\033[0m or \033[1m--recursive\033[0m|\033[1m-r\033[0m\033[0m options," << ::std::endl
+ << "respectively. Underneath, this command doesn't do much more than run \033[1mb install\033[0m." << ::std::endl
+ << "In the first form the specified packages must have been previously configured" << ::std::endl
+ << "with \033[1mbpkg-pkg-build(1)\033[0m or \033[1mbpkg-pkg-configure(1)\033[0m." << ::std::endl
+ << ::std::endl
+ << "Additional command line variables (\033[4mvars\033[0m, normally \033[1mconfig.*\033[0m) can be passed to" << ::std::endl
+ << "the build system. Such variables apply to all the specified packages but can" << ::std::endl
+ << "also be specified to only apply to specific packages using the argument" << ::std::endl
+ << "grouping mechanism (see \033[1mbpkg-argument-grouping(1)\033[0m for details). In particular," << ::std::endl
+ << "this mechanism can be used to specify the installation directory, for example:" << ::std::endl
+ << ::std::endl
+ << "bpkg install config.install.root=/usr/local \\" << ::std::endl
+ << " config.install.sudo=sudo \\" << ::std::endl
+ << " libfoo libbar" << ::std::endl
+ << ::std::endl
+ << "Alternatively, the installation directory can be specified once when creating" << ::std::endl
+ << "the configuration (\033[1mbpkg-cfg-create(1)\033[0m)." << ::std::endl;
+
+ p = ::bpkg::pkg_install_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-install\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-install.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-install\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-install-options.hxx b/bpkg/pkg-install-options.hxx
new file mode 100644
index 0000000..6beff63
--- /dev/null
+++ b/bpkg/pkg-install-options.hxx
@@ -0,0 +1,129 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_INSTALL_OPTIONS_HXX
+#define BPKG_PKG_INSTALL_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_install_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_install_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_install_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ all () const;
+
+ const strings&
+ all_pattern () const;
+
+ bool
+ all_pattern_specified () const;
+
+ const bool&
+ immediate () const;
+
+ const bool&
+ recursive () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool all_;
+ strings all_pattern_;
+ bool all_pattern_specified_;
+ bool immediate_;
+ bool recursive_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_install_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-install-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_INSTALL_OPTIONS_HXX
diff --git a/bpkg/pkg-install-options.ixx b/bpkg/pkg-install-options.ixx
new file mode 100644
index 0000000..575b4b4
--- /dev/null
+++ b/bpkg/pkg-install-options.ixx
@@ -0,0 +1,51 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_install_options
+ //
+
+ inline const bool& pkg_install_options::
+ all () const
+ {
+ return this->all_;
+ }
+
+ inline const strings& pkg_install_options::
+ all_pattern () const
+ {
+ return this->all_pattern_;
+ }
+
+ inline bool pkg_install_options::
+ all_pattern_specified () const
+ {
+ return this->all_pattern_specified_;
+ }
+
+ inline const bool& pkg_install_options::
+ immediate () const
+ {
+ return this->immediate_;
+ }
+
+ inline const bool& pkg_install_options::
+ recursive () const
+ {
+ return this->recursive_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-purge-options.cxx b/bpkg/pkg-purge-options.cxx
new file mode 100644
index 0000000..65b59a4
--- /dev/null
+++ b/bpkg/pkg-purge-options.cxx
@@ -0,0 +1,707 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-purge-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_purge_options
+ //
+
+ pkg_purge_options::
+ pkg_purge_options ()
+ : keep_ (),
+ force_ ()
+ {
+ }
+
+ bool pkg_purge_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_purge_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_purge_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_purge_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_purge_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_purge_options::
+ merge (const pkg_purge_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.keep_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->keep_, a.keep_);
+ }
+
+ if (a.force_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->force_, a.force_);
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_purge_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-PURGE OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--keep\033[0m|\033[1m-k\033[0m Keep the package archive. Note that in this mode the" << ::std::endl
+ << " package is still retained in the configuration's" << ::std::endl
+ << " database in the \033[1mfetched\033[0m state." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--force\033[0m|\033[1m-f\033[0m Purge a broken package. In this mode \033[1mbpkg\033[0m will verify" << ::std::endl
+ << " that the package directory and archive no longer" << ::std::endl
+ << " exist and then remove the package from the" << ::std::endl
+ << " configuration." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_purge_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_purge_options_map;
+
+ static _cli_pkg_purge_options_map _cli_pkg_purge_options_map_;
+
+ struct _cli_pkg_purge_options_map_init
+ {
+ _cli_pkg_purge_options_map_init ()
+ {
+ _cli_pkg_purge_options_map_["--keep"] =
+ &::bpkg::cli::thunk< pkg_purge_options, &pkg_purge_options::keep_ >;
+ _cli_pkg_purge_options_map_["-k"] =
+ &::bpkg::cli::thunk< pkg_purge_options, &pkg_purge_options::keep_ >;
+ _cli_pkg_purge_options_map_["--force"] =
+ &::bpkg::cli::thunk< pkg_purge_options, &pkg_purge_options::force_ >;
+ _cli_pkg_purge_options_map_["-f"] =
+ &::bpkg::cli::thunk< pkg_purge_options, &pkg_purge_options::force_ >;
+ }
+ };
+
+ static _cli_pkg_purge_options_map_init _cli_pkg_purge_options_map_init_;
+
+ bool pkg_purge_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_purge_options_map::const_iterator i (_cli_pkg_purge_options_map_.find (o));
+
+ if (i != _cli_pkg_purge_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_purge_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_purge_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-purge\033[0m [\033[4moptions\033[0m] \033[4mpkg\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-purge\033[0m command removes the package directory and archive from the" << ::std::endl
+ << "filesystem and removes the package from the configuration. Only packages in" << ::std::endl
+ << "the \033[1mfetched\033[0m and \033[1munpacked\033[0m state (\033[1mbpkg-pkg-status(1)\033[0m) can be purged plus \033[1mbroken\033[0m" << ::std::endl
+ << "packages if the \033[1m--force|-f\033[0m option is specified (see the option's description" << ::std::endl
+ << "for details on purging broken packages). If the \033[1m--keep|-k\033[0m option is specified," << ::std::endl
+ << "then the package archive is not removed (see the option's description for" << ::std::endl
+ << "details on this mode)." << ::std::endl;
+
+ p = ::bpkg::pkg_purge_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-purge\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-purge.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-purge\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-purge-options.hxx b/bpkg/pkg-purge-options.hxx
new file mode 100644
index 0000000..2649a4a
--- /dev/null
+++ b/bpkg/pkg-purge-options.hxx
@@ -0,0 +1,117 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_PURGE_OPTIONS_HXX
+#define BPKG_PKG_PURGE_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_purge_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_purge_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_purge_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ keep () const;
+
+ const bool&
+ force () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool keep_;
+ bool force_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_purge_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-purge-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_PURGE_OPTIONS_HXX
diff --git a/bpkg/pkg-purge-options.ixx b/bpkg/pkg-purge-options.ixx
new file mode 100644
index 0000000..85b3e75
--- /dev/null
+++ b/bpkg/pkg-purge-options.ixx
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_purge_options
+ //
+
+ inline const bool& pkg_purge_options::
+ keep () const
+ {
+ return this->keep_;
+ }
+
+ inline const bool& pkg_purge_options::
+ force () const
+ {
+ return this->force_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-status-options.cxx b/bpkg/pkg-status-options.cxx
new file mode 100644
index 0000000..46ca79e
--- /dev/null
+++ b/bpkg/pkg-status-options.cxx
@@ -0,0 +1,973 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-status-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_status_options
+ //
+
+ pkg_status_options::
+ pkg_status_options ()
+ : all_ (),
+ link_ (),
+ immediate_ (),
+ recursive_ (),
+ old_available_ (),
+ constraint_ (),
+ system_ (),
+ no_hold_ (),
+ no_hold_package_ (),
+ no_hold_version_ ()
+ {
+ }
+
+ bool pkg_status_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_status_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_status_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_status_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_status_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_status_options::
+ merge (const pkg_status_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.all_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->all_, a.all_);
+ }
+
+ if (a.link_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->link_, a.link_);
+ }
+
+ if (a.immediate_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->immediate_, a.immediate_);
+ }
+
+ if (a.recursive_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->recursive_, a.recursive_);
+ }
+
+ if (a.old_available_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->old_available_, a.old_available_);
+ }
+
+ if (a.constraint_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->constraint_, a.constraint_);
+ }
+
+ if (a.system_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->system_, a.system_);
+ }
+
+ if (a.no_hold_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_hold_, a.no_hold_);
+ }
+
+ if (a.no_hold_package_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_hold_package_, a.no_hold_package_);
+ }
+
+ if (a.no_hold_version_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_hold_version_, a.no_hold_version_);
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_status_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-STATUS OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all\033[0m|\033[1m-a\033[0m Print the status of all the packages, not just held." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--link\033[0m Also print the status of held/all packages from" << ::std::endl
+ << " linked configurations." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--immediate\033[0m|\033[1m-i\033[0m Also print the status of immediate dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--recursive\033[0m|\033[1m-r\033[0m Also print the status of all dependencies," << ::std::endl
+ << " recursively." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--old-available\033[0m|\033[1m-o\033[0m Print old available versions." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--constraint\033[0m Print version constraints for dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--system\033[0m Check the availability of packages from the system." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-hold\033[0m Don't print the package or version hold status." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-hold-package\033[0m Don't print the package hold status." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-hold-version\033[0m Don't print the version hold status." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_status_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_status_options_map;
+
+ static _cli_pkg_status_options_map _cli_pkg_status_options_map_;
+
+ struct _cli_pkg_status_options_map_init
+ {
+ _cli_pkg_status_options_map_init ()
+ {
+ _cli_pkg_status_options_map_["--all"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::all_ >;
+ _cli_pkg_status_options_map_["-a"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::all_ >;
+ _cli_pkg_status_options_map_["--link"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::link_ >;
+ _cli_pkg_status_options_map_["--immediate"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::immediate_ >;
+ _cli_pkg_status_options_map_["-i"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::immediate_ >;
+ _cli_pkg_status_options_map_["--recursive"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::recursive_ >;
+ _cli_pkg_status_options_map_["-r"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::recursive_ >;
+ _cli_pkg_status_options_map_["--old-available"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::old_available_ >;
+ _cli_pkg_status_options_map_["-o"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::old_available_ >;
+ _cli_pkg_status_options_map_["--constraint"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::constraint_ >;
+ _cli_pkg_status_options_map_["--system"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::system_ >;
+ _cli_pkg_status_options_map_["--no-hold"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::no_hold_ >;
+ _cli_pkg_status_options_map_["--no-hold-package"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::no_hold_package_ >;
+ _cli_pkg_status_options_map_["--no-hold-version"] =
+ &::bpkg::cli::thunk< pkg_status_options, &pkg_status_options::no_hold_version_ >;
+ }
+ };
+
+ static _cli_pkg_status_options_map_init _cli_pkg_status_options_map_init_;
+
+ bool pkg_status_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_status_options_map::const_iterator i (_cli_pkg_status_options_map_.find (o));
+
+ if (i != _cli_pkg_status_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_status_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_status_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-status\033[0m|\033[1mstatus\033[0m [\033[4moptions\033[0m] [\033[4mpkg\033[0m[\033[1m/\033[0m\033[4mver\033[0m]...]\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-status\033[0m command prints the status of the specified packages or, if \033[4mver\033[0m" << ::std::endl
+ << "is specified, package versions. If no packages were specified, then \033[1mpkg-status\033[0m" << ::std::endl
+ << "prints the status of all the held packages (which are the packages that were" << ::std::endl
+ << "explicitly built; see \033[1mbpkg-pkg-build(1)\033[0m). The latter mode can be modified to" << ::std::endl
+ << "print the status of all the packages by specifying the \033[1m--all\033[0m|\033[1m-a\033[0m\033[0m option." << ::std::endl
+ << "Additionally, the status of immediate or all dependencies of the above packages" << ::std::endl
+ << "can be printed by specifying the \033[1m--immediate\033[0m|\033[1m-i\033[0m\033[0m or \033[1m--recursive\033[0m|\033[1m-r\033[0m\033[0m options," << ::std::endl
+ << "respectively. Note that the status is written to \033[1mstdout\033[0m, not \033[1mstderr\033[0m." << ::std::endl
+ << ::std::endl
+ << "The default output format (see the \033[1m--stdout-format\033[0m common option) is regular" << ::std::endl
+ << "with components separated with spaces. Each line starts with the package name" << ::std::endl
+ << "followed by one of the status words listed below. Some of them can be" << ::std::endl
+ << "optionally followed by '\033[1m,\033[0m' (no spaces) and a sub-status word. Lines" << ::std::endl
+ << "corresponding to dependencies from linked configurations will additionally" << ::std::endl
+ << "mention the configuration directory in square brackets after the package name." << ::std::endl
+ << ::std::endl
+ << "\033[1munknown\033[0m" << ::std::endl
+ << " Package is not part of the configuration nor available from any of the" << ::std::endl
+ << " repositories." << ::std::endl
+ << "\033[1mavailable\033[0m" << ::std::endl
+ << " Package is not part of the configuration but is available from one of the" << ::std::endl
+ << " repositories." << ::std::endl
+ << "\033[1mfetched\033[0m" << ::std::endl
+ << " Package is part of the configuration and is fetched." << ::std::endl
+ << "\033[1munpacked\033[0m" << ::std::endl
+ << " Package is part of the configuration and is unpacked." << ::std::endl
+ << "\033[1mconfigured\033[0m" << ::std::endl
+ << " Package is part of the configuration and is configured. May be followed by" << ::std::endl
+ << " the \033[1msystem\033[0m sub-status indicating a package coming from the system. The" << ::std::endl
+ << " version of such a system package (described below) may be the special '\033[1m*\033[0m'" << ::std::endl
+ << " value indicating a wildcard version." << ::std::endl
+ << "\033[1mbroken\033[0m" << ::std::endl
+ << " Package is part of the configuration and is broken (broken packages can" << ::std::endl
+ << " only be purged; see \033[1mbpkg-pkg-purge(1)\033[0m)." << ::std::endl
+ << ::std::endl
+ << "If only the package name was specified without the package version, then the" << ::std::endl
+ << "\033[1mavailable\033[0m status word is followed by the list of available versions. Versions" << ::std::endl
+ << "that are only available for up/down-grading are printed in '\033[1m[]\033[0m' (such version" << ::std::endl
+ << "are only available as dependencies from prerequisite repositories of other" << ::std::endl
+ << "repositories). If the \033[1m--system\033[0m option is specified, then the last version in" << ::std::endl
+ << "this list may have the \033[1msys:\033[0m prefix indicating an available system version. Such" << ::std::endl
+ << "a system version may be the special '\033[1m?\033[0m' value indicating that a package may or" << ::std::endl
+ << "may not be available from the system and that its version is unknown." << ::std::endl
+ << ::std::endl
+ << "The \033[1mfetched\033[0m, \033[1munpacked\033[0m, \033[1mconfigured\033[0m, and \033[1mbroken\033[0m status words are followed by the" << ::std::endl
+ << "version of the package. If the package version was specified, then the \033[1munknown\033[0m" << ::std::endl
+ << "status word is also followed by the version." << ::std::endl
+ << ::std::endl
+ << "If the status is \033[1mfetched\033[0m, \033[1munpacked\033[0m, \033[1mconfigured\033[0m, or \033[1mbroken\033[0m and newer versions" << ::std::endl
+ << "are available, then the package version is followed by the \033[1mavailable\033[0m status" << ::std::endl
+ << "word and the list of newer versions. To instead see a list of all versions," << ::std::endl
+ << "including the older ones, specify the \033[1m--old-available\033[0m|\033[1m-o\033[0m\033[0m option. In this case" << ::std::endl
+ << "the currently selected version is printed in '\033[1m()\033[0m'." << ::std::endl
+ << ::std::endl
+ << "If the package name was specified with the version, then only the status (such" << ::std::endl
+ << "as, \033[1mconfigured\033[0m, \033[1mavailable\033[0m, etc.) of this version is considered." << ::std::endl
+ << ::std::endl
+ << "If a package is being held, then its name is printed prefixed with '\033[1m!\033[0m'." << ::std::endl
+ << "Similarly, if a package version is being held, then the version is printed" << ::std::endl
+ << "prefixed with '\033[1m!\033[0m'. Held packages and held versions were selected by the user" << ::std::endl
+ << "and are not automatically dropped and upgraded, respectively." << ::std::endl
+ << ::std::endl
+ << "Below are some examples, assuming the configuration has \033[1mlibfoo\033[0m \033[1m1.0.0\033[0m configured" << ::std::endl
+ << "and held (both package and version) as well as \033[1mlibfoo\033[0m \033[1m1.1.0\033[0m and \033[1m1.1.1\033[0m available" << ::std::endl
+ << "from source and \033[1m1.1.0\033[0m from the system." << ::std::endl
+ << ::std::endl
+ << "bpkg status libbar" << ::std::endl
+ << "libbar unknown" << ::std::endl
+ << ::std::endl
+ << "bpkg status libbar/1.0.0" << ::std::endl
+ << "libbar unknown 1.0.0" << ::std::endl
+ << ::std::endl
+ << "bpkg status libfoo/1.0.0" << ::std::endl
+ << "!libfoo configured !1.0.0" << ::std::endl
+ << ::std::endl
+ << "bpkg status libfoo/1.1.0" << ::std::endl
+ << "libfoo available 1.1.0" << ::std::endl
+ << ::std::endl
+ << "bpkg status --system libfoo/1.1.0" << ::std::endl
+ << "libfoo available 1.1.0 sys:1.1.0" << ::std::endl
+ << ::std::endl
+ << "bpkg status libfoo" << ::std::endl
+ << "!libfoo configured !1.0.0 available 1.1.0 1.1.1" << ::std::endl
+ << ::std::endl
+ << "bpkg status libfoo/1.1.1 libbar" << ::std::endl
+ << "libfoo available 1.1.1" << ::std::endl
+ << "libbar unknown" << ::std::endl
+ << ::std::endl
+ << "Assuming now that we dropped \033[1mlibfoo\033[0m from the configuration:" << ::std::endl
+ << ::std::endl
+ << "bpkg status libfoo/1.0.0" << ::std::endl
+ << "libfoo unknown 1.0.0" << ::std::endl
+ << ::std::endl
+ << "bpkg status libfoo" << ::std::endl
+ << "libfoo available 1.1.0 1.1.1" << ::std::endl
+ << ::std::endl
+ << "And assuming now that we built \033[1mlibfoo\033[0m as a system package with the wildcard" << ::std::endl
+ << "version:" << ::std::endl
+ << ::std::endl
+ << "bpkg status libfoo" << ::std::endl
+ << "!libfoo configured,system !* available 1.1.0 1.1.1" << ::std::endl
+ << ::std::endl
+ << "Another example of the status output this time including dependencies:" << ::std::endl
+ << ::std::endl
+ << "bpkg status -r libbaz" << ::std::endl
+ << "!libbaz configured 1.0.0" << ::std::endl
+ << " libfoo configured 1.0.0" << ::std::endl
+ << " bison [.bpkg/host/] configured 1.0.0" << ::std::endl
+ << " libbar configured 2.0.0" << ::std::endl
+ << ::std::endl
+ << "If the output format is \033[1mjson\033[0m, then the output is a JSON array of objects which" << ::std::endl
+ << "are the serialized representation of the following C++ \033[1mstruct\033[0m \033[1mpackage_status\033[0m:" << ::std::endl
+ << ::std::endl
+ << "struct available_version" << ::std::endl
+ << "{" << ::std::endl
+ << " string version;" << ::std::endl
+ << " bool system;" << ::std::endl
+ << " bool dependency;" << ::std::endl
+ << "};" << ::std::endl
+ << ::std::endl
+ << "struct package_status" << ::std::endl
+ << "{" << ::std::endl
+ << " string name;" << ::std::endl
+ << " optional<string> configuration;" << ::std::endl
+ << " optional<string> constraint;" << ::std::endl
+ << " string status;" << ::std::endl
+ << " optional<string> sub_status;" << ::std::endl
+ << " optional<string> version;" << ::std::endl
+ << " bool hold_package;" << ::std::endl
+ << " bool hold_version;" << ::std::endl
+ << " vector<available_version> available_versions;" << ::std::endl
+ << " vector<package_status> dependencies;" << ::std::endl
+ << "};" << ::std::endl
+ << ::std::endl
+ << "For example:" << ::std::endl
+ << ::std::endl
+ << "[" << ::std::endl
+ << " {" << ::std::endl
+ << " \"name\": \"hello\"," << ::std::endl
+ << " \"status\": \"configured\"," << ::std::endl
+ << " \"version\": \"1.0.0\"," << ::std::endl
+ << " \"hold_package\": true," << ::std::endl
+ << " \"available_versions\": [" << ::std::endl
+ << " {" << ::std::endl
+ << " \"version\": \"1.0.1\"" << ::std::endl
+ << " }," << ::std::endl
+ << " {" << ::std::endl
+ << " \"version\": \"2.0.0\"" << ::std::endl
+ << " }" << ::std::endl
+ << " ]," << ::std::endl
+ << " \"dependencies\": [" << ::std::endl
+ << " {" << ::std::endl
+ << " \"name\": \"libhello\"," << ::std::endl
+ << " \"status\": \"configured\"," << ::std::endl
+ << " \"version\": \"1.0.2\"," << ::std::endl
+ << " }" << ::std::endl
+ << " ]" << ::std::endl
+ << " }" << ::std::endl
+ << "]" << ::std::endl
+ << ::std::endl
+ << "See the JSON OUTPUT section in \033[1mbpkg-common-options(1)\033[0m for details on the" << ::std::endl
+ << "overall properties of this format and the semantics of the \033[1mstruct\033[0m" << ::std::endl
+ << "serialization." << ::std::endl
+ << ::std::endl
+ << "In \033[1mpackage_status\033[0m, the \033[1mconfiguration\033[0m member contains the absolute directory of" << ::std::endl
+ << "a linked configuration if this package resides in a linked configuration. The" << ::std::endl
+ << "\033[1mconstraint\033[0m member is present only if the \033[1m--constraint\033[0m option is specified. The" << ::std::endl
+ << "\033[1mversion\033[0m member is absent if the \033[1mstatus\033[0m member is \033[1munknown\033[0m or \033[1mavailable\033[0m and no" << ::std::endl
+ << "package version is specified on the command line. If the \033[1msub_status\033[0m member is" << ::std::endl
+ << "\033[1msystem\033[0m, then the \033[1mversion\033[0m member can be special \033[1m*\033[0m. The \033[1mdependencies\033[0m member is" << ::std::endl
+ << "present only if the \033[1m--immediate|-i\033[0m or \033[1m--recursive|-r\033[0m options are specified." << ::std::endl
+ << ::std::endl
+ << "In \033[1mavailable_version\033[0m, if the \033[1msystem\033[0m member is \033[1mtrue\033[0m, then this version is" << ::std::endl
+ << "available from the system, in which case the \033[1mversion\033[0m member can be special \033[1m?\033[0m or" << ::std::endl
+ << "\033[1m*\033[0m. If the \033[1mdependency\033[0m member is \033[1mtrue\033[0m, then this version is only available as a" << ::std::endl
+ << "dependency from prerequisite repositories of other repositories." << ::std::endl;
+
+ p = ::bpkg::pkg_status_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-status\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-status.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-status\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-status-options.hxx b/bpkg/pkg-status-options.hxx
new file mode 100644
index 0000000..9271c1e
--- /dev/null
+++ b/bpkg/pkg-status-options.hxx
@@ -0,0 +1,149 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_STATUS_OPTIONS_HXX
+#define BPKG_PKG_STATUS_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_status_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_status_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_status_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ all () const;
+
+ const bool&
+ link () const;
+
+ const bool&
+ immediate () const;
+
+ const bool&
+ recursive () const;
+
+ const bool&
+ old_available () const;
+
+ const bool&
+ constraint () const;
+
+ const bool&
+ system () const;
+
+ const bool&
+ no_hold () const;
+
+ const bool&
+ no_hold_package () const;
+
+ const bool&
+ no_hold_version () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool all_;
+ bool link_;
+ bool immediate_;
+ bool recursive_;
+ bool old_available_;
+ bool constraint_;
+ bool system_;
+ bool no_hold_;
+ bool no_hold_package_;
+ bool no_hold_version_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_status_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-status-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_STATUS_OPTIONS_HXX
diff --git a/bpkg/pkg-status-options.ixx b/bpkg/pkg-status-options.ixx
new file mode 100644
index 0000000..bf0c13c
--- /dev/null
+++ b/bpkg/pkg-status-options.ixx
@@ -0,0 +1,81 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_status_options
+ //
+
+ inline const bool& pkg_status_options::
+ all () const
+ {
+ return this->all_;
+ }
+
+ inline const bool& pkg_status_options::
+ link () const
+ {
+ return this->link_;
+ }
+
+ inline const bool& pkg_status_options::
+ immediate () const
+ {
+ return this->immediate_;
+ }
+
+ inline const bool& pkg_status_options::
+ recursive () const
+ {
+ return this->recursive_;
+ }
+
+ inline const bool& pkg_status_options::
+ old_available () const
+ {
+ return this->old_available_;
+ }
+
+ inline const bool& pkg_status_options::
+ constraint () const
+ {
+ return this->constraint_;
+ }
+
+ inline const bool& pkg_status_options::
+ system () const
+ {
+ return this->system_;
+ }
+
+ inline const bool& pkg_status_options::
+ no_hold () const
+ {
+ return this->no_hold_;
+ }
+
+ inline const bool& pkg_status_options::
+ no_hold_package () const
+ {
+ return this->no_hold_package_;
+ }
+
+ inline const bool& pkg_status_options::
+ no_hold_version () const
+ {
+ return this->no_hold_version_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-test-options.cxx b/bpkg/pkg-test-options.cxx
new file mode 100644
index 0000000..f5fdcf7
--- /dev/null
+++ b/bpkg/pkg-test-options.cxx
@@ -0,0 +1,758 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-test-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_test_options
+ //
+
+ pkg_test_options::
+ pkg_test_options ()
+ : all_ (),
+ all_pattern_ (),
+ all_pattern_specified_ (false),
+ immediate_ (),
+ recursive_ (),
+ package_cwd_ ()
+ {
+ }
+
+ bool pkg_test_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_test_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_test_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_test_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_test_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_test_options::
+ merge (const pkg_test_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.all_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->all_, a.all_);
+ }
+
+ if (a.all_pattern_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->all_pattern_, a.all_pattern_);
+ this->all_pattern_specified_ = true;
+ }
+
+ if (a.immediate_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->immediate_, a.immediate_);
+ }
+
+ if (a.recursive_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->recursive_, a.recursive_);
+ }
+
+ if (a.package_cwd_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->package_cwd_, a.package_cwd_);
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_test_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-TEST OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all\033[0m|\033[1m-a\033[0m Test all held packages." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all-pattern\033[0m \033[4mpattern\033[0m Test held packages that match the specified wildcard" << ::std::endl
+ << " pattern. Repeat this option to match multiple" << ::std::endl
+ << " patterns. Note that you may need to quote the pattern" << ::std::endl
+ << " to prevent expansion by your shell." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--immediate\033[0m|\033[1m-i\033[0m Also test immediate dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--recursive\033[0m|\033[1m-r\033[0m Also test all dependencies, recursively." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--package-cwd\033[0m Change the current working directory to the package" << ::std::endl
+ << " directory prior to running tests. This may help" << ::std::endl
+ << " ported third-party packages since its not uncommon" << ::std::endl
+ << " for tests to expect they are running form the project" << ::std::endl
+ << " root directory." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_test_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_test_options_map;
+
+ static _cli_pkg_test_options_map _cli_pkg_test_options_map_;
+
+ struct _cli_pkg_test_options_map_init
+ {
+ _cli_pkg_test_options_map_init ()
+ {
+ _cli_pkg_test_options_map_["--all"] =
+ &::bpkg::cli::thunk< pkg_test_options, &pkg_test_options::all_ >;
+ _cli_pkg_test_options_map_["-a"] =
+ &::bpkg::cli::thunk< pkg_test_options, &pkg_test_options::all_ >;
+ _cli_pkg_test_options_map_["--all-pattern"] =
+ &::bpkg::cli::thunk< pkg_test_options, strings, &pkg_test_options::all_pattern_,
+ &pkg_test_options::all_pattern_specified_ >;
+ _cli_pkg_test_options_map_["--immediate"] =
+ &::bpkg::cli::thunk< pkg_test_options, &pkg_test_options::immediate_ >;
+ _cli_pkg_test_options_map_["-i"] =
+ &::bpkg::cli::thunk< pkg_test_options, &pkg_test_options::immediate_ >;
+ _cli_pkg_test_options_map_["--recursive"] =
+ &::bpkg::cli::thunk< pkg_test_options, &pkg_test_options::recursive_ >;
+ _cli_pkg_test_options_map_["-r"] =
+ &::bpkg::cli::thunk< pkg_test_options, &pkg_test_options::recursive_ >;
+ _cli_pkg_test_options_map_["--package-cwd"] =
+ &::bpkg::cli::thunk< pkg_test_options, &pkg_test_options::package_cwd_ >;
+ }
+ };
+
+ static _cli_pkg_test_options_map_init _cli_pkg_test_options_map_init_;
+
+ bool pkg_test_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_test_options_map::const_iterator i (_cli_pkg_test_options_map_.find (o));
+
+ if (i != _cli_pkg_test_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_test_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_test_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-test\033[0m|\033[1mtest\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] \033[4mpkg\033[0m..." << ::std::endl
+ << "\033[1mbpkg pkg-test\033[0m|\033[1mtest\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] \033[1m--all\033[0m|\033[1m-a\033[0m" << ::std::endl
+ << "\033[1mbpkg pkg-test\033[0m|\033[1mtest\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] (\033[1m--all-pattern\033[0m <pattern>)...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-test\033[0m command tests the specified packages (the first form), all the" << ::std::endl
+ << "held packages (the second form, see \033[1mbpkg-pkg-status(1)\033[0m), or all the held" << ::std::endl
+ << "packages that match any of the specified wildcard patterns (the third form)." << ::std::endl
+ << "Additionally, immediate or all dependencies of these packages can also be" << ::std::endl
+ << "tested by specifying the \033[1m--immediate\033[0m|\033[1m-i\033[0m\033[0m or \033[1m--recursive\033[0m|\033[1m-r\033[0m\033[0m options," << ::std::endl
+ << "respectively. Underneath, this command doesn't do much more than run \033[1mb test\033[0m. In" << ::std::endl
+ << "the first form the specified packages must have been previously configured with" << ::std::endl
+ << "\033[1mbpkg-pkg-build(1)\033[0m or \033[1mbpkg-pkg-configure(1)\033[0m." << ::std::endl
+ << ::std::endl
+ << "Additional command line variables (\033[4mvars\033[0m, normally \033[1mconfig.*\033[0m) can be passed to" << ::std::endl
+ << "the build system. Such variables apply to all the specified packages but can" << ::std::endl
+ << "also be specified to only apply to specific packages using the argument" << ::std::endl
+ << "grouping mechanism (see \033[1mbpkg-argument-grouping(1)\033[0m for details)." << ::std::endl;
+
+ p = ::bpkg::pkg_test_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-test\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-test.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-test\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-test-options.hxx b/bpkg/pkg-test-options.hxx
new file mode 100644
index 0000000..b2c1096
--- /dev/null
+++ b/bpkg/pkg-test-options.hxx
@@ -0,0 +1,133 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_TEST_OPTIONS_HXX
+#define BPKG_PKG_TEST_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_test_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_test_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_test_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ all () const;
+
+ const strings&
+ all_pattern () const;
+
+ bool
+ all_pattern_specified () const;
+
+ const bool&
+ immediate () const;
+
+ const bool&
+ recursive () const;
+
+ const bool&
+ package_cwd () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool all_;
+ strings all_pattern_;
+ bool all_pattern_specified_;
+ bool immediate_;
+ bool recursive_;
+ bool package_cwd_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_test_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-test-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_TEST_OPTIONS_HXX
diff --git a/bpkg/pkg-test-options.ixx b/bpkg/pkg-test-options.ixx
new file mode 100644
index 0000000..5c75c56
--- /dev/null
+++ b/bpkg/pkg-test-options.ixx
@@ -0,0 +1,57 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_test_options
+ //
+
+ inline const bool& pkg_test_options::
+ all () const
+ {
+ return this->all_;
+ }
+
+ inline const strings& pkg_test_options::
+ all_pattern () const
+ {
+ return this->all_pattern_;
+ }
+
+ inline bool pkg_test_options::
+ all_pattern_specified () const
+ {
+ return this->all_pattern_specified_;
+ }
+
+ inline const bool& pkg_test_options::
+ immediate () const
+ {
+ return this->immediate_;
+ }
+
+ inline const bool& pkg_test_options::
+ recursive () const
+ {
+ return this->recursive_;
+ }
+
+ inline const bool& pkg_test_options::
+ package_cwd () const
+ {
+ return this->package_cwd_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-uninstall-options.cxx b/bpkg/pkg-uninstall-options.cxx
new file mode 100644
index 0000000..611b19d
--- /dev/null
+++ b/bpkg/pkg-uninstall-options.cxx
@@ -0,0 +1,743 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-uninstall-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_uninstall_options
+ //
+
+ pkg_uninstall_options::
+ pkg_uninstall_options ()
+ : all_ (),
+ all_pattern_ (),
+ all_pattern_specified_ (false),
+ immediate_ (),
+ recursive_ ()
+ {
+ }
+
+ bool pkg_uninstall_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_uninstall_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_uninstall_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_uninstall_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_uninstall_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_uninstall_options::
+ merge (const pkg_uninstall_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.all_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->all_, a.all_);
+ }
+
+ if (a.all_pattern_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->all_pattern_, a.all_pattern_);
+ this->all_pattern_specified_ = true;
+ }
+
+ if (a.immediate_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->immediate_, a.immediate_);
+ }
+
+ if (a.recursive_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->recursive_, a.recursive_);
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_uninstall_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-UNINSTALL OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all\033[0m|\033[1m-a\033[0m Uninstall all held packages." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all-pattern\033[0m \033[4mpattern\033[0m Uninstall held packages that match the specified" << ::std::endl
+ << " wildcard pattern. Repeat this option to match" << ::std::endl
+ << " multiple patterns. Note that you may need to quote" << ::std::endl
+ << " the pattern to prevent expansion by your shell." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--immediate\033[0m|\033[1m-i\033[0m Also uninstall immediate dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--recursive\033[0m|\033[1m-r\033[0m Also uninstall all dependencies, recursively." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_uninstall_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_uninstall_options_map;
+
+ static _cli_pkg_uninstall_options_map _cli_pkg_uninstall_options_map_;
+
+ struct _cli_pkg_uninstall_options_map_init
+ {
+ _cli_pkg_uninstall_options_map_init ()
+ {
+ _cli_pkg_uninstall_options_map_["--all"] =
+ &::bpkg::cli::thunk< pkg_uninstall_options, &pkg_uninstall_options::all_ >;
+ _cli_pkg_uninstall_options_map_["-a"] =
+ &::bpkg::cli::thunk< pkg_uninstall_options, &pkg_uninstall_options::all_ >;
+ _cli_pkg_uninstall_options_map_["--all-pattern"] =
+ &::bpkg::cli::thunk< pkg_uninstall_options, strings, &pkg_uninstall_options::all_pattern_,
+ &pkg_uninstall_options::all_pattern_specified_ >;
+ _cli_pkg_uninstall_options_map_["--immediate"] =
+ &::bpkg::cli::thunk< pkg_uninstall_options, &pkg_uninstall_options::immediate_ >;
+ _cli_pkg_uninstall_options_map_["-i"] =
+ &::bpkg::cli::thunk< pkg_uninstall_options, &pkg_uninstall_options::immediate_ >;
+ _cli_pkg_uninstall_options_map_["--recursive"] =
+ &::bpkg::cli::thunk< pkg_uninstall_options, &pkg_uninstall_options::recursive_ >;
+ _cli_pkg_uninstall_options_map_["-r"] =
+ &::bpkg::cli::thunk< pkg_uninstall_options, &pkg_uninstall_options::recursive_ >;
+ }
+ };
+
+ static _cli_pkg_uninstall_options_map_init _cli_pkg_uninstall_options_map_init_;
+
+ bool pkg_uninstall_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_uninstall_options_map::const_iterator i (_cli_pkg_uninstall_options_map_.find (o));
+
+ if (i != _cli_pkg_uninstall_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_uninstall_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_uninstall_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-uninstall\033[0m|\033[1muninstall\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] \033[4mpkg\033[0m..." << ::std::endl
+ << "\033[1mbpkg pkg-uninstall\033[0m|\033[1muninstall\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] \033[1m--all\033[0m|\033[1m-a\033[0m" << ::std::endl
+ << "\033[1mbpkg pkg-uninstall\033[0m|\033[1muninstall\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] (\033[1m--all-pattern\033[0m <pattern>)...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-uninstall\033[0m command uninstalls the specified packages (the first form)," << ::std::endl
+ << "all the held packages (the second form, see \033[1mbpkg-pkg-status(1)\033[0m), or all the" << ::std::endl
+ << "held packages that match any of the specified wildcard patterns (the third" << ::std::endl
+ << "form). Additionally, immediate or all dependencies of these specified packages" << ::std::endl
+ << "can be also uninstalled by specifying the \033[1m--immediate\033[0m|\033[1m-i\033[0m\033[0m or \033[1m--recursive\033[0m|\033[1m-r\033[0m\033[0m" << ::std::endl
+ << "options, respectively. Underneath, this command doesn't do much more than run \033[1mb" << ::std::endl
+ << "uninstall\033[0m. In the first form the specified packages must have been previously" << ::std::endl
+ << "configured with \033[1mbpkg-pkg-build(1)\033[0m or \033[1mbpkg-pkg-configure(1)\033[0m." << ::std::endl
+ << ::std::endl
+ << "Additional command line variables (\033[4mvars\033[0m, normally \033[1mconfig.*\033[0m) can be passed to" << ::std::endl
+ << "the build system. Such variables apply to all the specified packages but can" << ::std::endl
+ << "also be specified to only apply to specific packages using the argument" << ::std::endl
+ << "grouping mechanism (see \033[1mbpkg-argument-grouping(1)\033[0m for details). See" << ::std::endl
+ << "\033[1mbpkg-pkg-install(1)\033[0m for some examples." << ::std::endl;
+
+ p = ::bpkg::pkg_uninstall_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-uninstall\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-uninstall.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-uninstall\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-uninstall-options.hxx b/bpkg/pkg-uninstall-options.hxx
new file mode 100644
index 0000000..1feb443
--- /dev/null
+++ b/bpkg/pkg-uninstall-options.hxx
@@ -0,0 +1,129 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_UNINSTALL_OPTIONS_HXX
+#define BPKG_PKG_UNINSTALL_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_uninstall_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_uninstall_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_uninstall_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ all () const;
+
+ const strings&
+ all_pattern () const;
+
+ bool
+ all_pattern_specified () const;
+
+ const bool&
+ immediate () const;
+
+ const bool&
+ recursive () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool all_;
+ strings all_pattern_;
+ bool all_pattern_specified_;
+ bool immediate_;
+ bool recursive_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_uninstall_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-uninstall-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_UNINSTALL_OPTIONS_HXX
diff --git a/bpkg/pkg-uninstall-options.ixx b/bpkg/pkg-uninstall-options.ixx
new file mode 100644
index 0000000..ef15f14
--- /dev/null
+++ b/bpkg/pkg-uninstall-options.ixx
@@ -0,0 +1,51 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_uninstall_options
+ //
+
+ inline const bool& pkg_uninstall_options::
+ all () const
+ {
+ return this->all_;
+ }
+
+ inline const strings& pkg_uninstall_options::
+ all_pattern () const
+ {
+ return this->all_pattern_;
+ }
+
+ inline bool pkg_uninstall_options::
+ all_pattern_specified () const
+ {
+ return this->all_pattern_specified_;
+ }
+
+ inline const bool& pkg_uninstall_options::
+ immediate () const
+ {
+ return this->immediate_;
+ }
+
+ inline const bool& pkg_uninstall_options::
+ recursive () const
+ {
+ return this->recursive_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-unpack-options.cxx b/bpkg/pkg-unpack-options.cxx
new file mode 100644
index 0000000..9654924
--- /dev/null
+++ b/bpkg/pkg-unpack-options.cxx
@@ -0,0 +1,741 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-unpack-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_unpack_options
+ //
+
+ pkg_unpack_options::
+ pkg_unpack_options ()
+ : existing_ (),
+ purge_ (),
+ replace_ ()
+ {
+ }
+
+ bool pkg_unpack_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_unpack_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_unpack_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_unpack_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_unpack_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_unpack_options::
+ merge (const pkg_unpack_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.existing_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->existing_, a.existing_);
+ }
+
+ if (a.purge_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->purge_, a.purge_);
+ }
+
+ if (a.replace_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->replace_, a.replace_);
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_unpack_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-UNPACK OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--existing\033[0m|\033[1m-e\033[0m Treat the argument as an existing package directory" << ::std::endl
+ << " path rather than the package name to unpack." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--purge\033[0m|\033[1m-p\033[0m Remove the existing package directory when the" << ::std::endl
+ << " package is purged." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--replace\033[0m|\033[1m-r\033[0m Replace the source directory if the package is" << ::std::endl
+ << " already unpacked or fetched. Can only be specified" << ::std::endl
+ << " with an external package." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_unpack_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_unpack_options_map;
+
+ static _cli_pkg_unpack_options_map _cli_pkg_unpack_options_map_;
+
+ struct _cli_pkg_unpack_options_map_init
+ {
+ _cli_pkg_unpack_options_map_init ()
+ {
+ _cli_pkg_unpack_options_map_["--existing"] =
+ &::bpkg::cli::thunk< pkg_unpack_options, &pkg_unpack_options::existing_ >;
+ _cli_pkg_unpack_options_map_["-e"] =
+ &::bpkg::cli::thunk< pkg_unpack_options, &pkg_unpack_options::existing_ >;
+ _cli_pkg_unpack_options_map_["--purge"] =
+ &::bpkg::cli::thunk< pkg_unpack_options, &pkg_unpack_options::purge_ >;
+ _cli_pkg_unpack_options_map_["-p"] =
+ &::bpkg::cli::thunk< pkg_unpack_options, &pkg_unpack_options::purge_ >;
+ _cli_pkg_unpack_options_map_["--replace"] =
+ &::bpkg::cli::thunk< pkg_unpack_options, &pkg_unpack_options::replace_ >;
+ _cli_pkg_unpack_options_map_["-r"] =
+ &::bpkg::cli::thunk< pkg_unpack_options, &pkg_unpack_options::replace_ >;
+ }
+ };
+
+ static _cli_pkg_unpack_options_map_init _cli_pkg_unpack_options_map_init_;
+
+ bool pkg_unpack_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_unpack_options_map::const_iterator i (_cli_pkg_unpack_options_map_.find (o));
+
+ if (i != _cli_pkg_unpack_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_unpack_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_unpack_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-unpack\033[0m [\033[4moptions\033[0m] (\033[4mpkg\033[0m[\033[1m/\033[0m\033[4mver\033[0m] | \033[1m--existing|-e\033[0m \033[4mdir\033[0m)\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "If only the package name is specified, then the \033[1mpkg-unpack\033[0m command unpacks the" << ::std::endl
+ << "archive for the previously fetched (\033[1mbpkg-pkg-fetch(1)\033[0m) package. The resulting" << ::std::endl
+ << "package state is \033[1munpacked\033[0m (\033[1mbpkg-pkg-status(1)\033[0m)." << ::std::endl
+ << ::std::endl
+ << "If the package version is also specified, then the (source) directory from one" << ::std::endl
+ << "of the directory-based repositories (\033[1mbpkg-rep-add(1)\033[0m) is used in place, without" << ::std::endl
+ << "copying it into the configuration directory. Such a package is called \033[4mexternal\033[0m." << ::std::endl
+ << ::std::endl
+ << "If the \033[1m--existing|-e\033[0m option is used, then instead of the package name," << ::std::endl
+ << "\033[1mpkg-unpack\033[0m expects a local path to an existing package directory. In this case," << ::std::endl
+ << "\033[1mbpkg\033[0m will use the (source) directory in place, the same as for packages from" << ::std::endl
+ << "directory-based repositories. Also, unless the \033[1m--purge|-p\033[0m option is specified," << ::std::endl
+ << "\033[1mbpkg\033[0m will not attempt to remove this directory when the package is later purged" << ::std::endl
+ << "with the \033[1mbpkg-pkg-purge(1)\033[0m command. Such a package is also \033[4mexternal\033[0m." << ::std::endl
+ << ::std::endl
+ << "If \033[1m--existing|-e\033[0m is specified together with the \033[1m--replace|-r\033[0m option, then" << ::std::endl
+ << "\033[1mpkg-unpack\033[0m will replace the archive and/or source directory of a package that" << ::std::endl
+ << "is already in the \033[1munpacked\033[0m or \033[1mfetched\033[0m state." << ::std::endl
+ << ::std::endl
+ << "An external package triggers several changes in semantics compared to a normal" << ::std::endl
+ << "package: The package (output) directory inside the configuration is called just" << ::std::endl
+ << "\033[4mpkg\033[0m rather than \033[4mpkg\033[0m\033[1m-\033[0m\033[4mver\033[0m. It is also assumed that the packaging information" << ::std::endl
+ << "(package manifest and lockfile) for such packages may change without" << ::std::endl
+ << "incrementing the package version (for example, during development). To support" << ::std::endl
+ << "this, \033[1mbpkg\033[0m implements the \033[4mpackage iteration\033[0m mechanism which may result in" << ::std::endl
+ << "iteration numbers to be shown as part of the package version, for example," << ::std::endl
+ << "\033[1m1.2.3#1\033[0m (see Package Version (bpkg#package-version))." << ::std::endl;
+
+ p = ::bpkg::pkg_unpack_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-unpack\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-unpack.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-unpack\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl
+ << "--purge|-p" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-unpack-options.hxx b/bpkg/pkg-unpack-options.hxx
new file mode 100644
index 0000000..752e17b
--- /dev/null
+++ b/bpkg/pkg-unpack-options.hxx
@@ -0,0 +1,121 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_UNPACK_OPTIONS_HXX
+#define BPKG_PKG_UNPACK_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_unpack_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_unpack_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_unpack_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ existing () const;
+
+ const bool&
+ purge () const;
+
+ const bool&
+ replace () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool existing_;
+ bool purge_;
+ bool replace_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_unpack_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-unpack-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_UNPACK_OPTIONS_HXX
diff --git a/bpkg/pkg-unpack-options.ixx b/bpkg/pkg-unpack-options.ixx
new file mode 100644
index 0000000..68abf8a
--- /dev/null
+++ b/bpkg/pkg-unpack-options.ixx
@@ -0,0 +1,39 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_unpack_options
+ //
+
+ inline const bool& pkg_unpack_options::
+ existing () const
+ {
+ return this->existing_;
+ }
+
+ inline const bool& pkg_unpack_options::
+ purge () const
+ {
+ return this->purge_;
+ }
+
+ inline const bool& pkg_unpack_options::
+ replace () const
+ {
+ return this->replace_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-update-options.cxx b/bpkg/pkg-update-options.cxx
new file mode 100644
index 0000000..0dc6187
--- /dev/null
+++ b/bpkg/pkg-update-options.cxx
@@ -0,0 +1,763 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-update-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_update_options
+ //
+
+ pkg_update_options::
+ pkg_update_options ()
+ : all_ (),
+ all_pattern_ (),
+ all_pattern_specified_ (false),
+ immediate_ (),
+ recursive_ (),
+ for__ (),
+ for__specified_ (false)
+ {
+ }
+
+ bool pkg_update_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_update_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_update_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_update_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_update_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_update_options::
+ merge (const pkg_update_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.all_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->all_, a.all_);
+ }
+
+ if (a.all_pattern_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->all_pattern_, a.all_pattern_);
+ this->all_pattern_specified_ = true;
+ }
+
+ if (a.immediate_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->immediate_, a.immediate_);
+ }
+
+ if (a.recursive_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->recursive_, a.recursive_);
+ }
+
+ if (a.for__specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->for__, a.for__);
+ this->for__specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_update_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-UPDATE OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all\033[0m|\033[1m-a\033[0m Update all held packages." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all-pattern\033[0m \033[4mpattern\033[0m Update held packages that match the specified" << ::std::endl
+ << " wildcard pattern. Repeat this option to match" << ::std::endl
+ << " multiple patterns. Note that you may need to quote" << ::std::endl
+ << " the pattern to prevent expansion by your shell." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--immediate\033[0m|\033[1m-i\033[0m Also update immediate dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--recursive\033[0m|\033[1m-r\033[0m Also update all dependencies, recursively." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--for\033[0m|\033[1m-f\033[0m \033[4moperation\033[0m Instead of the default \033[1mupdate\033[0m build system operation," << ::std::endl
+ << " perform the \033[1mupdate-for-\033[0m\033[4moperation\033[0m variant where" << ::std::endl
+ << " \033[4moperation\033[0m is normally \033[1minstall\033[0m or \033[1mtest\033[0m." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_update_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_update_options_map;
+
+ static _cli_pkg_update_options_map _cli_pkg_update_options_map_;
+
+ struct _cli_pkg_update_options_map_init
+ {
+ _cli_pkg_update_options_map_init ()
+ {
+ _cli_pkg_update_options_map_["--all"] =
+ &::bpkg::cli::thunk< pkg_update_options, &pkg_update_options::all_ >;
+ _cli_pkg_update_options_map_["-a"] =
+ &::bpkg::cli::thunk< pkg_update_options, &pkg_update_options::all_ >;
+ _cli_pkg_update_options_map_["--all-pattern"] =
+ &::bpkg::cli::thunk< pkg_update_options, strings, &pkg_update_options::all_pattern_,
+ &pkg_update_options::all_pattern_specified_ >;
+ _cli_pkg_update_options_map_["--immediate"] =
+ &::bpkg::cli::thunk< pkg_update_options, &pkg_update_options::immediate_ >;
+ _cli_pkg_update_options_map_["-i"] =
+ &::bpkg::cli::thunk< pkg_update_options, &pkg_update_options::immediate_ >;
+ _cli_pkg_update_options_map_["--recursive"] =
+ &::bpkg::cli::thunk< pkg_update_options, &pkg_update_options::recursive_ >;
+ _cli_pkg_update_options_map_["-r"] =
+ &::bpkg::cli::thunk< pkg_update_options, &pkg_update_options::recursive_ >;
+ _cli_pkg_update_options_map_["--for"] =
+ &::bpkg::cli::thunk< pkg_update_options, string, &pkg_update_options::for__,
+ &pkg_update_options::for__specified_ >;
+ _cli_pkg_update_options_map_["-f"] =
+ &::bpkg::cli::thunk< pkg_update_options, string, &pkg_update_options::for__,
+ &pkg_update_options::for__specified_ >;
+ }
+ };
+
+ static _cli_pkg_update_options_map_init _cli_pkg_update_options_map_init_;
+
+ bool pkg_update_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_update_options_map::const_iterator i (_cli_pkg_update_options_map_.find (o));
+
+ if (i != _cli_pkg_update_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_update_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_update_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-update\033[0m|\033[1mupdate\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] \033[4mpkg\033[0m..." << ::std::endl
+ << "\033[1mbpkg pkg-update\033[0m|\033[1mupdate\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] \033[1m--all\033[0m|\033[1m-a\033[0m" << ::std::endl
+ << "\033[1mbpkg pkg-update\033[0m|\033[1mupdate\033[0m [\033[4moptions\033[0m] [\033[4mvars\033[0m] (\033[1m--all-pattern\033[0m <pattern>)...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-update\033[0m command updates the specified packages (the first form), all the" << ::std::endl
+ << "held packages (the second form, see \033[1mbpkg-pkg-status(1)\033[0m), or all the held" << ::std::endl
+ << "packages that match any of the specified wildcard patterns (the third form)." << ::std::endl
+ << "Additionally, immediate or all dependencies of these packages can be also" << ::std::endl
+ << "updated by specifying the \033[1m--immediate\033[0m|\033[1m-i\033[0m\033[0m or \033[1m--recursive\033[0m|\033[1m-r\033[0m\033[0m options," << ::std::endl
+ << "respectively. Underneath, this command doesn't do much more than run \033[1mb update\033[0m" << ::std::endl
+ << "(or one of its update-for-*\033[0m variants; see \033[1m--for|-f\033[0m). In the first form the" << ::std::endl
+ << "specified packages must have been previously configured with \033[1mbpkg-pkg-build(1)\033[0m" << ::std::endl
+ << "or \033[1mbpkg-pkg-configure(1)\033[0m." << ::std::endl
+ << ::std::endl
+ << "Additional command line variables (\033[4mvars\033[0m, normally \033[1mconfig.*\033[0m) can be passed to" << ::std::endl
+ << "the build system. Such variables apply to all the specified packages but can" << ::std::endl
+ << "also be specified to only apply to specific packages using the argument" << ::std::endl
+ << "grouping mechanism (see \033[1mbpkg-argument-grouping(1)\033[0m for details)." << ::std::endl;
+
+ p = ::bpkg::pkg_update_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-update\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-update.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mpkg-update\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-update-options.hxx b/bpkg/pkg-update-options.hxx
new file mode 100644
index 0000000..291af69
--- /dev/null
+++ b/bpkg/pkg-update-options.hxx
@@ -0,0 +1,137 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_UPDATE_OPTIONS_HXX
+#define BPKG_PKG_UPDATE_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class pkg_update_options: public ::bpkg::configuration_options
+ {
+ public:
+ pkg_update_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_update_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ all () const;
+
+ const strings&
+ all_pattern () const;
+
+ bool
+ all_pattern_specified () const;
+
+ const bool&
+ immediate () const;
+
+ const bool&
+ recursive () const;
+
+ const string&
+ for_ () const;
+
+ bool
+ for__specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool all_;
+ strings all_pattern_;
+ bool all_pattern_specified_;
+ bool immediate_;
+ bool recursive_;
+ string for__;
+ bool for__specified_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_update_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-update-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_UPDATE_OPTIONS_HXX
diff --git a/bpkg/pkg-update-options.ixx b/bpkg/pkg-update-options.ixx
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/bpkg/pkg-update-options.ixx
@@ -0,0 +1,63 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_update_options
+ //
+
+ inline const bool& pkg_update_options::
+ all () const
+ {
+ return this->all_;
+ }
+
+ inline const strings& pkg_update_options::
+ all_pattern () const
+ {
+ return this->all_pattern_;
+ }
+
+ inline bool pkg_update_options::
+ all_pattern_specified () const
+ {
+ return this->all_pattern_specified_;
+ }
+
+ inline const bool& pkg_update_options::
+ immediate () const
+ {
+ return this->immediate_;
+ }
+
+ inline const bool& pkg_update_options::
+ recursive () const
+ {
+ return this->recursive_;
+ }
+
+ inline const string& pkg_update_options::
+ for_ () const
+ {
+ return this->for__;
+ }
+
+ inline bool pkg_update_options::
+ for__specified () const
+ {
+ return this->for__specified_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/pkg-verify-options.cxx b/bpkg/pkg-verify-options.cxx
new file mode 100644
index 0000000..8d5bc18
--- /dev/null
+++ b/bpkg/pkg-verify-options.cxx
@@ -0,0 +1,731 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/pkg-verify-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // pkg_verify_options
+ //
+
+ pkg_verify_options::
+ pkg_verify_options ()
+ : silent_ (),
+ deep_ (),
+ ignore_unknown_ (),
+ manifest_ ()
+ {
+ }
+
+ bool pkg_verify_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_verify_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool pkg_verify_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_verify_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool pkg_verify_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void pkg_verify_options::
+ merge (const pkg_verify_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+
+ if (a.silent_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->silent_, a.silent_);
+ }
+
+ if (a.deep_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->deep_, a.deep_);
+ }
+
+ if (a.ignore_unknown_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->ignore_unknown_, a.ignore_unknown_);
+ }
+
+ if (a.manifest_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->manifest_, a.manifest_);
+ }
+ }
+
+ ::bpkg::cli::usage_para pkg_verify_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mPKG-VERIFY OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--silent\033[0m Suppress the error messages about the reason why the" << ::std::endl
+ << " package is invalid. Just return the error status." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--deep\033[0m Verify the presence of the required *-build\033[0m" << ::std::endl
+ << " values/files and the validity of files referenced by" << ::std::endl
+ << " the \033[1m*-file\033[0m manifest values." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--ignore-unknown\033[0m Ignore unknown manifest entries. By default, \033[1mbpkg\033[0m" << ::std::endl
+ << " will refuse to declare such a package valid since it" << ::std::endl
+ << " cannot be sure the unknown entries are valid. Note" << ::std::endl
+ << " that this option also ignores the version constraints" << ::std::endl
+ << " in the special toolchain build-time dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--manifest\033[0m Instead of printing the successful verification" << ::std::endl
+ << " result in the human-readable form, dump the package" << ::std::endl
+ << " manifest to \033[1mstdout\033[0m. If the \033[1m--deep\033[0m option is" << ::std::endl
+ << " specified, then in the resulting manifest the \033[1m*-file\033[0m" << ::std::endl
+ << " values are replaced with the contents of the" << ::std::endl
+ << " referenced files, the *-build\033[0m values are" << ::std::endl
+ << " automatically added (unless the corresponding files" << ::std::endl
+ << " are absent), and the package dependency constraints" << ::std::endl
+ << " are completed." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (pkg_verify_options&, ::bpkg::cli::scanner&)>
+ _cli_pkg_verify_options_map;
+
+ static _cli_pkg_verify_options_map _cli_pkg_verify_options_map_;
+
+ struct _cli_pkg_verify_options_map_init
+ {
+ _cli_pkg_verify_options_map_init ()
+ {
+ _cli_pkg_verify_options_map_["--silent"] =
+ &::bpkg::cli::thunk< pkg_verify_options, &pkg_verify_options::silent_ >;
+ _cli_pkg_verify_options_map_["--deep"] =
+ &::bpkg::cli::thunk< pkg_verify_options, &pkg_verify_options::deep_ >;
+ _cli_pkg_verify_options_map_["--ignore-unknown"] =
+ &::bpkg::cli::thunk< pkg_verify_options, &pkg_verify_options::ignore_unknown_ >;
+ _cli_pkg_verify_options_map_["--manifest"] =
+ &::bpkg::cli::thunk< pkg_verify_options, &pkg_verify_options::manifest_ >;
+ }
+ };
+
+ static _cli_pkg_verify_options_map_init _cli_pkg_verify_options_map_init_;
+
+ bool pkg_verify_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_pkg_verify_options_map::const_iterator i (_cli_pkg_verify_options_map_.find (o));
+
+ if (i != _cli_pkg_verify_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool pkg_verify_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_verify_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg pkg-verify\033[0m [\033[4moptions\033[0m] \033[4mfile\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mpkg-verify\033[0m command verifies that the specified archive file is a valid" << ::std::endl
+ << "\033[1mbpkg\033[0m package. Specifically, it checks that the file's name and the top-level" << ::std::endl
+ << "directory inside the archive match the canonical \033[4mname\033[0m\033[1m-\033[0m\033[4mversion\033[0m\033[0m form and that" << ::std::endl
+ << "there is a valid manifest file in that top-level directory. Additionally, if" << ::std::endl
+ << "the \033[1m--deep\033[0m option is specified, it also checks that the required *-build\033[0m" << ::std::endl
+ << "values/files are present in the manifest/archive and the files referenced by" << ::std::endl
+ << "the \033[1m*-file\033[0m manifest values are present in the archive and are not empty." << ::std::endl;
+
+ p = ::bpkg::pkg_verify_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-verify\033[0m command the following options files are searched for in the" << ::std::endl
+ << "predefined directories (system, etc) and, if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-pkg-verify.options" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/pkg-verify-options.hxx b/bpkg/pkg-verify-options.hxx
new file mode 100644
index 0000000..d4b1415
--- /dev/null
+++ b/bpkg/pkg-verify-options.hxx
@@ -0,0 +1,125 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_PKG_VERIFY_OPTIONS_HXX
+#define BPKG_PKG_VERIFY_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class pkg_verify_options: public ::bpkg::common_options
+ {
+ public:
+ pkg_verify_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const pkg_verify_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ silent () const;
+
+ const bool&
+ deep () const;
+
+ const bool&
+ ignore_unknown () const;
+
+ const bool&
+ manifest () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool silent_;
+ bool deep_;
+ bool ignore_unknown_;
+ bool manifest_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_pkg_verify_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/pkg-verify-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_PKG_VERIFY_OPTIONS_HXX
diff --git a/bpkg/pkg-verify-options.ixx b/bpkg/pkg-verify-options.ixx
new file mode 100644
index 0000000..4e66b5a
--- /dev/null
+++ b/bpkg/pkg-verify-options.ixx
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // pkg_verify_options
+ //
+
+ inline const bool& pkg_verify_options::
+ silent () const
+ {
+ return this->silent_;
+ }
+
+ inline const bool& pkg_verify_options::
+ deep () const
+ {
+ return this->deep_;
+ }
+
+ inline const bool& pkg_verify_options::
+ ignore_unknown () const
+ {
+ return this->ignore_unknown_;
+ }
+
+ inline const bool& pkg_verify_options::
+ manifest () const
+ {
+ return this->manifest_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/rep-add-options.cxx b/bpkg/rep-add-options.cxx
new file mode 100644
index 0000000..194a5d7
--- /dev/null
+++ b/bpkg/rep-add-options.cxx
@@ -0,0 +1,703 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/rep-add-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // rep_add_options
+ //
+
+ rep_add_options::
+ rep_add_options ()
+ : type_ (),
+ type_specified_ (false)
+ {
+ }
+
+ bool rep_add_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_add_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_add_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_add_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_add_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void rep_add_options::
+ merge (const rep_add_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.type_specified_)
+ {
+ ::bpkg::cli::parser< repository_type>::merge (
+ this->type_, a.type_);
+ this->type_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para rep_add_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mREP-ADD OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--type\033[0m \033[4mtype\033[0m Specify the repository type with valid values being" << ::std::endl
+ << " \033[1mpkg\033[0m, \033[1mdir\033[0m, and \033[1mgit\033[0m." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (rep_add_options&, ::bpkg::cli::scanner&)>
+ _cli_rep_add_options_map;
+
+ static _cli_rep_add_options_map _cli_rep_add_options_map_;
+
+ struct _cli_rep_add_options_map_init
+ {
+ _cli_rep_add_options_map_init ()
+ {
+ _cli_rep_add_options_map_["--type"] =
+ &::bpkg::cli::thunk< rep_add_options, repository_type, &rep_add_options::type_,
+ &rep_add_options::type_specified_ >;
+ }
+ };
+
+ static _cli_rep_add_options_map_init _cli_rep_add_options_map_init_;
+
+ bool rep_add_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_rep_add_options_map::const_iterator i (_cli_rep_add_options_map_.find (o));
+
+ if (i != _cli_rep_add_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool rep_add_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_add_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg rep-add\033[0m|\033[1madd\033[0m [\033[4moptions\033[0m] \033[4mrep-loc\033[0m...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mrep-add\033[0m command adds the specified package repositories to the" << ::std::endl
+ << "configuration. The repository location \033[4mrep-loc\033[0m is a URL or a directory path. If" << ::std::endl
+ << "a repository with the same canonical name already exists in the configuration," << ::std::endl
+ << "then its location is replaced with the specified." << ::std::endl
+ << ::std::endl
+ << "Note that this command doesn't fetch the list of available packages for the" << ::std::endl
+ << "newly added repository. For that, use the \033[1mbpkg-rep-fetch(1)\033[0m command, normally," << ::std::endl
+ << "after adding all the repositories you wish to use." << ::std::endl
+ << ::std::endl
+ << "Currently three types of repositories are supported: archive-based \033[1mpkg\033[0m," << ::std::endl
+ << "directory-based \033[1mdir\033[0m, and version control-based \033[1mgit\033[0m. See" << ::std::endl
+ << "\033[1mbpkg-repository-types(1)\033[0m for details on their structure and URL format." << ::std::endl
+ << ::std::endl
+ << "Normally the repository type can be automatically guessed by examining its URL" << ::std::endl
+ << "(for example, the presence of the \033[1m.git\033[0m extension) or, in case of a local" << ::std::endl
+ << "repository, its content (for example, the presence of the \033[1m.git/\033[0m subdirectory)." << ::std::endl
+ << "Without any identifying information the \033[1mpkg\033[0m type is assumed unless explicitly" << ::std::endl
+ << "specified with the \033[1m--type\033[0m option or in the URL scheme. Note, however, that the" << ::std::endl
+ << "\033[1mdir\033[0m repository type is never guessed since it is not easily distinguishable" << ::std::endl
+ << "from local \033[1mpkg\033[0m and \033[1mgit\033[0m repositories." << ::std::endl;
+
+ p = ::bpkg::rep_add_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mrep-add\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-rep-add.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mrep-add\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/rep-add-options.hxx b/bpkg/rep-add-options.hxx
new file mode 100644
index 0000000..9e257c6
--- /dev/null
+++ b/bpkg/rep-add-options.hxx
@@ -0,0 +1,119 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_REP_ADD_OPTIONS_HXX
+#define BPKG_REP_ADD_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <libbpkg/manifest.hxx>
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class rep_add_options: public ::bpkg::configuration_options
+ {
+ public:
+ rep_add_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const rep_add_options&);
+
+ // Option accessors.
+ //
+ const repository_type&
+ type () const;
+
+ bool
+ type_specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ repository_type type_;
+ bool type_specified_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_add_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/rep-add-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_REP_ADD_OPTIONS_HXX
diff --git a/bpkg/rep-add-options.ixx b/bpkg/rep-add-options.ixx
new file mode 100644
index 0000000..bfaa70f
--- /dev/null
+++ b/bpkg/rep-add-options.ixx
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // rep_add_options
+ //
+
+ inline const repository_type& rep_add_options::
+ type () const
+ {
+ return this->type_;
+ }
+
+ inline bool rep_add_options::
+ type_specified () const
+ {
+ return this->type_specified_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/rep-create-options.cxx b/bpkg/rep-create-options.cxx
new file mode 100644
index 0000000..3c8c1d1
--- /dev/null
+++ b/bpkg/rep-create-options.cxx
@@ -0,0 +1,727 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/rep-create-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // rep_create_options
+ //
+
+ rep_create_options::
+ rep_create_options ()
+ : ignore_unknown_ (),
+ min_bpkg_version_ (),
+ min_bpkg_version_specified_ (false),
+ key_ (),
+ key_specified_ (false)
+ {
+ }
+
+ bool rep_create_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_create_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_create_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_create_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_create_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void rep_create_options::
+ merge (const rep_create_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+
+ if (a.ignore_unknown_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->ignore_unknown_, a.ignore_unknown_);
+ }
+
+ if (a.min_bpkg_version_specified_)
+ {
+ ::bpkg::cli::parser< butl::standard_version>::merge (
+ this->min_bpkg_version_, a.min_bpkg_version_);
+ this->min_bpkg_version_specified_ = true;
+ }
+
+ if (a.key_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->key_, a.key_);
+ this->key_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para rep_create_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mREP-CREATE OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--ignore-unknown\033[0m Ignore unknown manifest entries. Note that this" << ::std::endl
+ << " option also ignores the version constraints in the" << ::std::endl
+ << " special toolchain build-time dependencies." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--min-bpkg-version\033[0m \033[4mver\033[0m Apply backward compatibility workarounds to the" << ::std::endl
+ << " generated \033[1mpackages.manifest\033[0m file so that it can be" << ::std::endl
+ << " consumed by \033[1mbpkg\033[0m versions greater or equal to the" << ::std::endl
+ << " specified version. If unspecified, then the" << ::std::endl
+ << " \033[1mmin-bpkg-version\033[0m value from the" << ::std::endl
+ << " \033[1mrepositories.manifest\033[0m file is used, if present. If" << ::std::endl
+ << " the manifest value is not specified either, then no" << ::std::endl
+ << " backward compatibility workarounds are applied." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--key\033[0m \033[4mname\033[0m Private key to use to sign the repository. In most" << ::std::endl
+ << " cases \033[4mname\033[0m will be a path to the key file but it can" << ::std::endl
+ << " also be a key id when a custom \033[1mopenssl\033[0m cryptographic" << ::std::endl
+ << " engine is used." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (rep_create_options&, ::bpkg::cli::scanner&)>
+ _cli_rep_create_options_map;
+
+ static _cli_rep_create_options_map _cli_rep_create_options_map_;
+
+ struct _cli_rep_create_options_map_init
+ {
+ _cli_rep_create_options_map_init ()
+ {
+ _cli_rep_create_options_map_["--ignore-unknown"] =
+ &::bpkg::cli::thunk< rep_create_options, &rep_create_options::ignore_unknown_ >;
+ _cli_rep_create_options_map_["--min-bpkg-version"] =
+ &::bpkg::cli::thunk< rep_create_options, butl::standard_version, &rep_create_options::min_bpkg_version_,
+ &rep_create_options::min_bpkg_version_specified_ >;
+ _cli_rep_create_options_map_["--key"] =
+ &::bpkg::cli::thunk< rep_create_options, string, &rep_create_options::key_,
+ &rep_create_options::key_specified_ >;
+ }
+ };
+
+ static _cli_rep_create_options_map_init _cli_rep_create_options_map_init_;
+
+ bool rep_create_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_rep_create_options_map::const_iterator i (_cli_rep_create_options_map_.find (o));
+
+ if (i != _cli_rep_create_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool rep_create_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_create_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg rep-create\033[0m [\033[4moptions\033[0m] [\033[4mdir\033[0m]\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mrep-create\033[0m command regenerates the \033[1mpackages.manifest\033[0m file based on the" << ::std::endl
+ << "files present in the repository directory. If the \033[1mrepositories.manifest\033[0m file" << ::std::endl
+ << "contains a certificate, then the \033[1msignature.manifest\033[0m file is regenerated as" << ::std::endl
+ << "well. In this case the \033[1m--key\033[0m option must be used to specify the certificate's" << ::std::endl
+ << "private key. If \033[4mdir\033[0m is not specified, then the current working directory is" << ::std::endl
+ << "used as the repository root." << ::std::endl;
+
+ p = ::bpkg::rep_create_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mrep-create\033[0m command the search start directory is the repository" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-rep-create.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mrep-create\033[0m command options cannot be specified in the remote" << ::std::endl
+ << "default options files:" << ::std::endl
+ << ::std::endl
+ << "--key" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/rep-create-options.hxx b/bpkg/rep-create-options.hxx
new file mode 100644
index 0000000..9afb227
--- /dev/null
+++ b/bpkg/rep-create-options.hxx
@@ -0,0 +1,129 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_REP_CREATE_OPTIONS_HXX
+#define BPKG_REP_CREATE_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class rep_create_options: public ::bpkg::common_options
+ {
+ public:
+ rep_create_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const rep_create_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ ignore_unknown () const;
+
+ const butl::standard_version&
+ min_bpkg_version () const;
+
+ bool
+ min_bpkg_version_specified () const;
+
+ const string&
+ key () const;
+
+ bool
+ key_specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool ignore_unknown_;
+ butl::standard_version min_bpkg_version_;
+ bool min_bpkg_version_specified_;
+ string key_;
+ bool key_specified_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_create_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/rep-create-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_REP_CREATE_OPTIONS_HXX
diff --git a/bpkg/rep-create-options.ixx b/bpkg/rep-create-options.ixx
new file mode 100644
index 0000000..cf0a734
--- /dev/null
+++ b/bpkg/rep-create-options.ixx
@@ -0,0 +1,51 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // rep_create_options
+ //
+
+ inline const bool& rep_create_options::
+ ignore_unknown () const
+ {
+ return this->ignore_unknown_;
+ }
+
+ inline const butl::standard_version& rep_create_options::
+ min_bpkg_version () const
+ {
+ return this->min_bpkg_version_;
+ }
+
+ inline bool rep_create_options::
+ min_bpkg_version_specified () const
+ {
+ return this->min_bpkg_version_specified_;
+ }
+
+ inline const string& rep_create_options::
+ key () const
+ {
+ return this->key_;
+ }
+
+ inline bool rep_create_options::
+ key_specified () const
+ {
+ return this->key_specified_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/rep-fetch-options.cxx b/bpkg/rep-fetch-options.cxx
new file mode 100644
index 0000000..a9f336d
--- /dev/null
+++ b/bpkg/rep-fetch-options.cxx
@@ -0,0 +1,694 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/rep-fetch-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // rep_fetch_options
+ //
+
+ rep_fetch_options::
+ rep_fetch_options ()
+ : shallow_ ()
+ {
+ }
+
+ bool rep_fetch_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_fetch_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_fetch_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_fetch_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_fetch_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void rep_fetch_options::
+ merge (const rep_fetch_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.shallow_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->shallow_, a.shallow_);
+ }
+ }
+
+ ::bpkg::cli::usage_para rep_fetch_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mREP-FETCH OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--shallow\033[0m Do not re-fetch complement and prerequisite" << ::std::endl
+ << " repositories of the specified repositories unless the" << ::std::endl
+ << " set of complements and/or prerequisites has changed." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (rep_fetch_options&, ::bpkg::cli::scanner&)>
+ _cli_rep_fetch_options_map;
+
+ static _cli_rep_fetch_options_map _cli_rep_fetch_options_map_;
+
+ struct _cli_rep_fetch_options_map_init
+ {
+ _cli_rep_fetch_options_map_init ()
+ {
+ _cli_rep_fetch_options_map_["--shallow"] =
+ &::bpkg::cli::thunk< rep_fetch_options, &rep_fetch_options::shallow_ >;
+ }
+ };
+
+ static _cli_rep_fetch_options_map_init _cli_rep_fetch_options_map_init_;
+
+ bool rep_fetch_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_rep_fetch_options_map::const_iterator i (_cli_rep_fetch_options_map_.find (o));
+
+ if (i != _cli_rep_fetch_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool rep_fetch_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_fetch_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg rep-fetch\033[0m|\033[1mfetch\033[0m [\033[4moptions\033[0m] [(\033[4mrep-name\033[0m | \033[4mrep-loc\033[0m)...]\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mrep-fetch\033[0m command fetches the list of available packages for the specified" << ::std::endl
+ << "repositories as well as all their complement and prerequisite repositories," << ::std::endl
+ << "recursively. If no repositories were specified, then all the repositories" << ::std::endl
+ << "previously added (\033[1mbpkg-rep-add(1)\033[0m) to the configuration are fetched." << ::std::endl
+ << ::std::endl
+ << "The repository to fetch can be specified either as a repository name or as a" << ::std::endl
+ << "repository location (URL or a directory path; see \033[1mbpkg-rep-add(1)\033[0m for details)." << ::std::endl
+ << "In the latter case, the repository location is added/replaced as if by first" << ::std::endl
+ << "executing the \033[1mrep-add\033[0m command." << ::std::endl
+ << ::std::endl
+ << "Note that fetching only a specific repository that happens to be a prerequisite" << ::std::endl
+ << "or complete of another repository not being fetched may result in an" << ::std::endl
+ << "inconsistent repository state." << ::std::endl;
+
+ p = ::bpkg::rep_fetch_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mrep-fetch\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-rep-fetch.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mrep-fetch\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/rep-fetch-options.hxx b/bpkg/rep-fetch-options.hxx
new file mode 100644
index 0000000..01ed16e
--- /dev/null
+++ b/bpkg/rep-fetch-options.hxx
@@ -0,0 +1,113 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_REP_FETCH_OPTIONS_HXX
+#define BPKG_REP_FETCH_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class rep_fetch_options: public ::bpkg::configuration_options
+ {
+ public:
+ rep_fetch_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const rep_fetch_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ shallow () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool shallow_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_fetch_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/rep-fetch-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_REP_FETCH_OPTIONS_HXX
diff --git a/bpkg/rep-fetch-options.ixx b/bpkg/rep-fetch-options.ixx
new file mode 100644
index 0000000..283f304
--- /dev/null
+++ b/bpkg/rep-fetch-options.ixx
@@ -0,0 +1,27 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // rep_fetch_options
+ //
+
+ inline const bool& rep_fetch_options::
+ shallow () const
+ {
+ return this->shallow_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/rep-info-options.cxx b/bpkg/rep-info-options.cxx
new file mode 100644
index 0000000..e714f2e
--- /dev/null
+++ b/bpkg/rep-info-options.cxx
@@ -0,0 +1,902 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/rep-info-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // rep_info_options
+ //
+
+ rep_info_options::
+ rep_info_options ()
+ : name_ (),
+ cert_fingerprint_ (),
+ cert_name_ (),
+ cert_organization_ (),
+ cert_email_ (),
+ repositories_ (),
+ packages_ (),
+ manifest_ (),
+ ignore_unknown_ (),
+ deep_ (),
+ repositories_file_ (),
+ repositories_file_specified_ (false),
+ packages_file_ (),
+ packages_file_specified_ (false),
+ type_ (),
+ type_specified_ (false),
+ directory_ (),
+ directory_specified_ (false)
+ {
+ }
+
+ bool rep_info_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_info_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_info_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_info_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_info_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void rep_info_options::
+ merge (const rep_info_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+
+ if (a.name_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->name_, a.name_);
+ }
+
+ if (a.cert_fingerprint_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->cert_fingerprint_, a.cert_fingerprint_);
+ }
+
+ if (a.cert_name_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->cert_name_, a.cert_name_);
+ }
+
+ if (a.cert_organization_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->cert_organization_, a.cert_organization_);
+ }
+
+ if (a.cert_email_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->cert_email_, a.cert_email_);
+ }
+
+ if (a.repositories_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->repositories_, a.repositories_);
+ }
+
+ if (a.packages_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->packages_, a.packages_);
+ }
+
+ if (a.manifest_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->manifest_, a.manifest_);
+ }
+
+ if (a.ignore_unknown_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->ignore_unknown_, a.ignore_unknown_);
+ }
+
+ if (a.deep_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->deep_, a.deep_);
+ }
+
+ if (a.repositories_file_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->repositories_file_, a.repositories_file_);
+ this->repositories_file_specified_ = true;
+ }
+
+ if (a.packages_file_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->packages_file_, a.packages_file_);
+ this->packages_file_specified_ = true;
+ }
+
+ if (a.type_specified_)
+ {
+ ::bpkg::cli::parser< repository_type>::merge (
+ this->type_, a.type_);
+ this->type_specified_ = true;
+ }
+
+ if (a.directory_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->directory_, a.directory_);
+ this->directory_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para rep_info_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mREP-INFO OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--name\033[0m|\033[1m-n\033[0m Print the repository's name and location." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--cert-fingerprint\033[0m Print the repository's certificate fingerprint or" << ::std::endl
+ << " empty line if the repository is unsigned." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--cert-name\033[0m Print the repository's certificate common name (CN)" << ::std::endl
+ << " or empty line if the repository is unsigned." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--cert-organization\033[0m Print the repository's certificate organization name" << ::std::endl
+ << " (O) or empty line if the repository is unsigned." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--cert-email\033[0m Print the repository's certificate email or empty" << ::std::endl
+ << " line if the repository is unsigned." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--repositories\033[0m|\033[1m-r\033[0m Print the list of complement and prerequisite" << ::std::endl
+ << " repositories." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--packages\033[0m|\033[1m-p\033[0m Print the list of available packages." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--manifest\033[0m Instead of printing the information in the" << ::std::endl
+ << " human-readable form, dump it (to \033[1mstdout\033[0m) as" << ::std::endl
+ << " manifest(s). Normally you would use this option in" << ::std::endl
+ << " combination with \033[1m--packages|-p\033[0m or \033[1m--repositories|-r\033[0m" << ::std::endl
+ << " to only dump one of the manifests. If the \033[1m--deep\033[0m" << ::std::endl
+ << " option is specified, then in the resulting packages" << ::std::endl
+ << " manifest the \033[1m*-file\033[0m values are replaced with the" << ::std::endl
+ << " contents of the referenced files and the *-build\033[0m" << ::std::endl
+ << " values are automatically added (unless the" << ::std::endl
+ << " corresponding files are absent). See also" << ::std::endl
+ << " \033[1m--ignore-unknown\033[0m, \033[1m--repositories-file\033[0m, and" << ::std::endl
+ << " \033[1m--packages-file\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--ignore-unknown\033[0m Ignore unknown manifest entries. Note that this" << ::std::endl
+ << " option also ignores the version constraints in the" << ::std::endl
+ << " special toolchain build-time dependencies. This" << ::std::endl
+ << " option is implied if \033[1m--manifest\033[0m is not specified." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--deep\033[0m Verify the presence of the required *-build\033[0m" << ::std::endl
+ << " values/files and the validity of files referenced by" << ::std::endl
+ << " the \033[1m*-file\033[0m manifest values." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--repositories-file\033[0m \033[4mpath\033[0m If \033[1m--manifest\033[0m is specified, then save the" << ::std::endl
+ << " repositories manifest to the specified file instead" << ::std::endl
+ << " of dumping it to \033[1mstdout\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--packages-file\033[0m \033[4mpath\033[0m If \033[1m--manifest\033[0m is specified, then save the packages" << ::std::endl
+ << " manifest to the specified file instead of dumping it" << ::std::endl
+ << " to \033[1mstdout\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--type\033[0m \033[4mtype\033[0m Specify the repository type with valid values being" << ::std::endl
+ << " \033[1mpkg\033[0m, \033[1mdir\033[0m, and \033[1mgit\033[0m. Refer to \033[1mbpkg-rep-add(1)\033[0m for" << ::std::endl
+ << " details." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--directory\033[0m|\033[1m-d\033[0m \033[4mdir\033[0m Use configuration in \033[4mdir\033[0m for the trusted certificate" << ::std::endl
+ << " database." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (rep_info_options&, ::bpkg::cli::scanner&)>
+ _cli_rep_info_options_map;
+
+ static _cli_rep_info_options_map _cli_rep_info_options_map_;
+
+ struct _cli_rep_info_options_map_init
+ {
+ _cli_rep_info_options_map_init ()
+ {
+ _cli_rep_info_options_map_["--name"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::name_ >;
+ _cli_rep_info_options_map_["-n"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::name_ >;
+ _cli_rep_info_options_map_["--cert-fingerprint"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::cert_fingerprint_ >;
+ _cli_rep_info_options_map_["--cert-name"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::cert_name_ >;
+ _cli_rep_info_options_map_["--cert-organization"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::cert_organization_ >;
+ _cli_rep_info_options_map_["--cert-email"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::cert_email_ >;
+ _cli_rep_info_options_map_["--repositories"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::repositories_ >;
+ _cli_rep_info_options_map_["-r"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::repositories_ >;
+ _cli_rep_info_options_map_["--packages"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::packages_ >;
+ _cli_rep_info_options_map_["-p"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::packages_ >;
+ _cli_rep_info_options_map_["--manifest"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::manifest_ >;
+ _cli_rep_info_options_map_["--ignore-unknown"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::ignore_unknown_ >;
+ _cli_rep_info_options_map_["--deep"] =
+ &::bpkg::cli::thunk< rep_info_options, &rep_info_options::deep_ >;
+ _cli_rep_info_options_map_["--repositories-file"] =
+ &::bpkg::cli::thunk< rep_info_options, path, &rep_info_options::repositories_file_,
+ &rep_info_options::repositories_file_specified_ >;
+ _cli_rep_info_options_map_["--packages-file"] =
+ &::bpkg::cli::thunk< rep_info_options, path, &rep_info_options::packages_file_,
+ &rep_info_options::packages_file_specified_ >;
+ _cli_rep_info_options_map_["--type"] =
+ &::bpkg::cli::thunk< rep_info_options, repository_type, &rep_info_options::type_,
+ &rep_info_options::type_specified_ >;
+ _cli_rep_info_options_map_["--directory"] =
+ &::bpkg::cli::thunk< rep_info_options, string, &rep_info_options::directory_,
+ &rep_info_options::directory_specified_ >;
+ _cli_rep_info_options_map_["-d"] =
+ &::bpkg::cli::thunk< rep_info_options, string, &rep_info_options::directory_,
+ &rep_info_options::directory_specified_ >;
+ }
+ };
+
+ static _cli_rep_info_options_map_init _cli_rep_info_options_map_init_;
+
+ bool rep_info_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_rep_info_options_map::const_iterator i (_cli_rep_info_options_map_.find (o));
+
+ if (i != _cli_rep_info_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool rep_info_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_info_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg rep-info\033[0m [\033[4moptions\033[0m] \033[4mrep-loc\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mrep-info\033[0m command prints various information about the specified repository." << ::std::endl
+ << "By default it print the repository's name and location as the first line. If" << ::std::endl
+ << "the repository is signed, the certificate information (name/organization/email)" << ::std::endl
+ << "is printed as the next line followed by the certificate fingerprint. Then comes" << ::std::endl
+ << "the list of complement and prerequisite repositories followed by the list of" << ::std::endl
+ << "available packages." << ::std::endl
+ << ::std::endl
+ << "This default format can be altered in various ways using options listed below." << ::std::endl
+ << "Note also that the information is written to \033[1mstdout\033[0m, not \033[1mstderr\033[0m." << ::std::endl
+ << ::std::endl
+ << "If the current working directory contains a \033[1mbpkg\033[0m configuration, then \033[1mrep-info\033[0m" << ::std::endl
+ << "will use its certificate database for the repository authentication. That is," << ::std::endl
+ << "it will trust the repository's certificate if it is already trusted by the" << ::std::endl
+ << "configuration. Otherwise it will add the certificate to the configuration if" << ::std::endl
+ << "you confirm it is trusted. You can specify an alternative configuration" << ::std::endl
+ << "directory with the \033[1m--directory|-d\033[0m option. To disable using the configuration in" << ::std::endl
+ << "the current working directory pass this option with an empty path." << ::std::endl;
+
+ p = ::bpkg::rep_info_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "If the \033[1mrep-info\033[0m command uses an existing bpkg\033[0m configuration, then the start" << ::std::endl
+ << "directory is the configuration directory. Otherwise, only the predefined" << ::std::endl
+ << "directories (home, system, etc) are searched. The following options files are" << ::std::endl
+ << "searched for in each directory and, if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-rep-info.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mrep-info\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/rep-info-options.hxx b/bpkg/rep-info-options.hxx
new file mode 100644
index 0000000..8e040da
--- /dev/null
+++ b/bpkg/rep-info-options.hxx
@@ -0,0 +1,183 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_REP_INFO_OPTIONS_HXX
+#define BPKG_REP_INFO_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <libbpkg/manifest.hxx>
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class rep_info_options: public ::bpkg::common_options
+ {
+ public:
+ rep_info_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const rep_info_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ name () const;
+
+ const bool&
+ cert_fingerprint () const;
+
+ const bool&
+ cert_name () const;
+
+ const bool&
+ cert_organization () const;
+
+ const bool&
+ cert_email () const;
+
+ const bool&
+ repositories () const;
+
+ const bool&
+ packages () const;
+
+ const bool&
+ manifest () const;
+
+ const bool&
+ ignore_unknown () const;
+
+ const bool&
+ deep () const;
+
+ const path&
+ repositories_file () const;
+
+ bool
+ repositories_file_specified () const;
+
+ const path&
+ packages_file () const;
+
+ bool
+ packages_file_specified () const;
+
+ const repository_type&
+ type () const;
+
+ bool
+ type_specified () const;
+
+ const string&
+ directory () const;
+
+ bool
+ directory_specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool name_;
+ bool cert_fingerprint_;
+ bool cert_name_;
+ bool cert_organization_;
+ bool cert_email_;
+ bool repositories_;
+ bool packages_;
+ bool manifest_;
+ bool ignore_unknown_;
+ bool deep_;
+ path repositories_file_;
+ bool repositories_file_specified_;
+ path packages_file_;
+ bool packages_file_specified_;
+ repository_type type_;
+ bool type_specified_;
+ string directory_;
+ bool directory_specified_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_info_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/rep-info-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_REP_INFO_OPTIONS_HXX
diff --git a/bpkg/rep-info-options.ixx b/bpkg/rep-info-options.ixx
new file mode 100644
index 0000000..7aa219f
--- /dev/null
+++ b/bpkg/rep-info-options.ixx
@@ -0,0 +1,129 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // rep_info_options
+ //
+
+ inline const bool& rep_info_options::
+ name () const
+ {
+ return this->name_;
+ }
+
+ inline const bool& rep_info_options::
+ cert_fingerprint () const
+ {
+ return this->cert_fingerprint_;
+ }
+
+ inline const bool& rep_info_options::
+ cert_name () const
+ {
+ return this->cert_name_;
+ }
+
+ inline const bool& rep_info_options::
+ cert_organization () const
+ {
+ return this->cert_organization_;
+ }
+
+ inline const bool& rep_info_options::
+ cert_email () const
+ {
+ return this->cert_email_;
+ }
+
+ inline const bool& rep_info_options::
+ repositories () const
+ {
+ return this->repositories_;
+ }
+
+ inline const bool& rep_info_options::
+ packages () const
+ {
+ return this->packages_;
+ }
+
+ inline const bool& rep_info_options::
+ manifest () const
+ {
+ return this->manifest_;
+ }
+
+ inline const bool& rep_info_options::
+ ignore_unknown () const
+ {
+ return this->ignore_unknown_;
+ }
+
+ inline const bool& rep_info_options::
+ deep () const
+ {
+ return this->deep_;
+ }
+
+ inline const path& rep_info_options::
+ repositories_file () const
+ {
+ return this->repositories_file_;
+ }
+
+ inline bool rep_info_options::
+ repositories_file_specified () const
+ {
+ return this->repositories_file_specified_;
+ }
+
+ inline const path& rep_info_options::
+ packages_file () const
+ {
+ return this->packages_file_;
+ }
+
+ inline bool rep_info_options::
+ packages_file_specified () const
+ {
+ return this->packages_file_specified_;
+ }
+
+ inline const repository_type& rep_info_options::
+ type () const
+ {
+ return this->type_;
+ }
+
+ inline bool rep_info_options::
+ type_specified () const
+ {
+ return this->type_specified_;
+ }
+
+ inline const string& rep_info_options::
+ directory () const
+ {
+ return this->directory_;
+ }
+
+ inline bool rep_info_options::
+ directory_specified () const
+ {
+ return this->directory_specified_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/rep-list-options.cxx b/bpkg/rep-list-options.cxx
new file mode 100644
index 0000000..c1f456c
--- /dev/null
+++ b/bpkg/rep-list-options.cxx
@@ -0,0 +1,701 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/rep-list-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // rep_list_options
+ //
+
+ rep_list_options::
+ rep_list_options ()
+ : complements_ (),
+ prerequisites_ ()
+ {
+ }
+
+ bool rep_list_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_list_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_list_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_list_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_list_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void rep_list_options::
+ merge (const rep_list_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.complements_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->complements_, a.complements_);
+ }
+
+ if (a.prerequisites_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->prerequisites_, a.prerequisites_);
+ }
+ }
+
+ ::bpkg::cli::usage_para rep_list_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mREP-LIST OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--complements\033[0m|\033[1m-c\033[0m List complement repositories." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--prerequisites\033[0m|\033[1m-p\033[0m List prerequisite repositories." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (rep_list_options&, ::bpkg::cli::scanner&)>
+ _cli_rep_list_options_map;
+
+ static _cli_rep_list_options_map _cli_rep_list_options_map_;
+
+ struct _cli_rep_list_options_map_init
+ {
+ _cli_rep_list_options_map_init ()
+ {
+ _cli_rep_list_options_map_["--complements"] =
+ &::bpkg::cli::thunk< rep_list_options, &rep_list_options::complements_ >;
+ _cli_rep_list_options_map_["-c"] =
+ &::bpkg::cli::thunk< rep_list_options, &rep_list_options::complements_ >;
+ _cli_rep_list_options_map_["--prerequisites"] =
+ &::bpkg::cli::thunk< rep_list_options, &rep_list_options::prerequisites_ >;
+ _cli_rep_list_options_map_["-p"] =
+ &::bpkg::cli::thunk< rep_list_options, &rep_list_options::prerequisites_ >;
+ }
+ };
+
+ static _cli_rep_list_options_map_init _cli_rep_list_options_map_init_;
+
+ bool rep_list_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_rep_list_options_map::const_iterator i (_cli_rep_list_options_map_.find (o));
+
+ if (i != _cli_rep_list_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool rep_list_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_list_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg rep-list\033[0m|\033[1mlist\033[0m [\033[4moptions\033[0m]\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mrep-list\033[0m command lists the repositories in the configuration." << ::std::endl
+ << ::std::endl
+ << "For each repository a line containing the repository name and location is" << ::std::endl
+ << "printed to \033[1mstdout\033[0m. If the \033[1m--complements|-c\033[0m and/or \033[1m--prerequisites|-p\033[0m options" << ::std::endl
+ << "are specified, then it is followed by the list of complement and/or" << ::std::endl
+ << "prerequisite repositories, recursively." << ::std::endl;
+
+ p = ::bpkg::rep_list_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mrep-list\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-rep-list.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mrep-list\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/rep-list-options.hxx b/bpkg/rep-list-options.hxx
new file mode 100644
index 0000000..a736975
--- /dev/null
+++ b/bpkg/rep-list-options.hxx
@@ -0,0 +1,119 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_REP_LIST_OPTIONS_HXX
+#define BPKG_REP_LIST_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <libbpkg/manifest.hxx>
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class rep_list_options: public ::bpkg::configuration_options
+ {
+ public:
+ rep_list_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const rep_list_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ complements () const;
+
+ const bool&
+ prerequisites () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool complements_;
+ bool prerequisites_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_list_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/rep-list-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_REP_LIST_OPTIONS_HXX
diff --git a/bpkg/rep-list-options.ixx b/bpkg/rep-list-options.ixx
new file mode 100644
index 0000000..babc7a0
--- /dev/null
+++ b/bpkg/rep-list-options.ixx
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // rep_list_options
+ //
+
+ inline const bool& rep_list_options::
+ complements () const
+ {
+ return this->complements_;
+ }
+
+ inline const bool& rep_list_options::
+ prerequisites () const
+ {
+ return this->prerequisites_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/rep-remove-options.cxx b/bpkg/rep-remove-options.cxx
new file mode 100644
index 0000000..ffe44be
--- /dev/null
+++ b/bpkg/rep-remove-options.cxx
@@ -0,0 +1,704 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/rep-remove-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <utility>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ 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 bpkg
+{
+ // rep_remove_options
+ //
+
+ rep_remove_options::
+ rep_remove_options ()
+ : all_ (),
+ clean_ ()
+ {
+ }
+
+ bool rep_remove_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_remove_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool rep_remove_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_remove_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool rep_remove_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void rep_remove_options::
+ merge (const rep_remove_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // configuration_options base
+ //
+ ::bpkg::configuration_options::merge (a);
+
+ if (a.all_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->all_, a.all_);
+ }
+
+ if (a.clean_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->clean_, a.clean_);
+ }
+ }
+
+ ::bpkg::cli::usage_para rep_remove_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mREP-REMOVE OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--all\033[0m|\033[1m-a\033[0m Remove all the repositories." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--clean\033[0m Clean the repository state." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // configuration_options base
+ //
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (rep_remove_options&, ::bpkg::cli::scanner&)>
+ _cli_rep_remove_options_map;
+
+ static _cli_rep_remove_options_map _cli_rep_remove_options_map_;
+
+ struct _cli_rep_remove_options_map_init
+ {
+ _cli_rep_remove_options_map_init ()
+ {
+ _cli_rep_remove_options_map_["--all"] =
+ &::bpkg::cli::thunk< rep_remove_options, &rep_remove_options::all_ >;
+ _cli_rep_remove_options_map_["-a"] =
+ &::bpkg::cli::thunk< rep_remove_options, &rep_remove_options::all_ >;
+ _cli_rep_remove_options_map_["--clean"] =
+ &::bpkg::cli::thunk< rep_remove_options, &rep_remove_options::clean_ >;
+ }
+ };
+
+ static _cli_rep_remove_options_map_init _cli_rep_remove_options_map_init_;
+
+ bool rep_remove_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_rep_remove_options_map::const_iterator i (_cli_rep_remove_options_map_.find (o));
+
+ if (i != _cli_rep_remove_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // configuration_options base
+ //
+ if (::bpkg::configuration_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool rep_remove_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::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 ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_remove_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg rep-remove\033[0m|\033[1mremove\033[0m [\033[4moptions\033[0m] (\033[4mrep-name\033[0m|\033[4mrep-loc\033[0m)..." << ::std::endl
+ << "\033[1mbpkg rep-remove\033[0m|\033[1mremove\033[0m [\033[4moptions\033[0m] \033[1m--all\033[0m|\033[1m-a\033[0m" << ::std::endl
+ << "\033[1mbpkg rep-remove\033[0m|\033[1mremove\033[0m [\033[4moptions\033[0m] \033[1m--clean\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mrep-remove\033[0m command removes the specified package repositories from the" << ::std::endl
+ << "configuration. The repository to remove can be specified either as a repository" << ::std::endl
+ << "name or as a repository location (URL or a directory path)." << ::std::endl
+ << ::std::endl
+ << "Alternatively, the \033[1m--all|-a\033[0m option can be used to remove all the repositories" << ::std::endl
+ << "that were previously added (\033[1mbpkg-rep-add(1)\033[0m) to the configuration." << ::std::endl
+ << ::std::endl
+ << "Finally, the \033[1m--clean\033[0m option can be used to revert the repositories to the clean" << ::std::endl
+ << "state, as if they were added but never fetched." << ::std::endl;
+
+ p = ::bpkg::rep_remove_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mpkg-rep-remove\033[0m command the search start directory is the configuration" << ::std::endl
+ << "directory. The following options files are searched for in each directory and," << ::std::endl
+ << "if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-rep-remove.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mrep-remove\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/rep-remove-options.hxx b/bpkg/rep-remove-options.hxx
new file mode 100644
index 0000000..eedbe27
--- /dev/null
+++ b/bpkg/rep-remove-options.hxx
@@ -0,0 +1,119 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_REP_REMOVE_OPTIONS_HXX
+#define BPKG_REP_REMOVE_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <libbpkg/manifest.hxx>
+
+#include <bpkg/configuration-options.hxx>
+
+namespace bpkg
+{
+ class rep_remove_options: public ::bpkg::configuration_options
+ {
+ public:
+ rep_remove_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const rep_remove_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ all () const;
+
+ const bool&
+ clean () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool all_;
+ bool clean_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_rep_remove_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/rep-remove-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_REP_REMOVE_OPTIONS_HXX
diff --git a/bpkg/rep-remove-options.ixx b/bpkg/rep-remove-options.ixx
new file mode 100644
index 0000000..b8ec8ba
--- /dev/null
+++ b/bpkg/rep-remove-options.ixx
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // rep_remove_options
+ //
+
+ inline const bool& rep_remove_options::
+ all () const
+ {
+ return this->all_;
+ }
+
+ inline const bool& rep_remove_options::
+ clean () const
+ {
+ return this->clean_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/repository-signing.cxx b/bpkg/repository-signing.cxx
new file mode 100644
index 0000000..66366cb
--- /dev/null
+++ b/bpkg/repository-signing.cxx
@@ -0,0 +1,205 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/repository-signing.hxx>
+
+#include <map>
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_repository_signing_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg rep-create --key\033[0m ...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The purpose of signing a repository is to prevent tampering with packages" << ::std::endl
+ << "either during transmission or on the repository \033[4mhost machine\033[0m. Ideally, you" << ::std::endl
+ << "would generate and sign the repository manifests on a separate \033[4mbuild machine\033[0m" << ::std::endl
+ << "that is behind a firewall. This way, if (or, really, when) your host machine is" << ::std::endl
+ << "compromised, it will be difficult for an attacker to compromise the repository" << ::std::endl
+ << "packages without being noticed. Since the repository key is kept on the build" << ::std::endl
+ << "machine (or, better yet, on a \033[4mone-way\033[0m PIV/PKCS#11 device; see below) they will" << ::std::endl
+ << "not be able to re-sign the modified repository." << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg\033[0m uses X.509 public key cryptography for repository signing. Currently, only" << ::std::endl
+ << "the explicit \033[4mfirst use\033[0m certificate authentication is implemented. That is, for" << ::std::endl
+ << "an unknown (to this \033[1mbpkg\033[0m configuration) repository certificate its subject" << ::std::endl
+ << "information and fingerprint are presented to the user. If the user confirms the" << ::std::endl
+ << "authenticity of the certificate, then it is added to the configuration and any" << ::std::endl
+ << "repository that in the future presents this certificate is trusted without" << ::std::endl
+ << "further confirmations, provided its name matches the certificate's subject (see" << ::std::endl
+ << "below). In the future a certificate authority (CA)-based model may be added." << ::std::endl
+ << ::std::endl
+ << "The rest of this guide shows how to create a key/certificate pair for \033[1mpkg\033[0m" << ::std::endl
+ << "repository signing and use it to sign a repository. At the end it also briefly" << ::std::endl
+ << "explains how to store the private key on a PIV/PKCS#11 device using Yubikey 4" << ::std::endl
+ << "as an example." << ::std::endl
+ << ::std::endl
+ << "1. Generate Private Key" << ::std::endl
+ << ::std::endl
+ << " The first step is to generate the private key:" << ::std::endl
+ << ::std::endl
+ << " $ openssl genrsa -aes256 2048 >key.pem" << ::std::endl
+ << ::std::endl
+ << " If you would like to generate a key without password protection (not a good" << ::std::endl
+ << " idea except for testing), leave the \033[1m-aes256\033[0m option out. You may also need" << ::std::endl
+ << " to add \033[1m-nodes\033[0m depending on your \033[1mopenssl(1)\033[0m configuration." << ::std::endl
+ << ::std::endl
+ << "2. Generate Certificate" << ::std::endl
+ << ::std::endl
+ << " Next create the certificate configuration file by saving the following into" << ::std::endl
+ << " \033[1mcert.conf\033[0m. You may want to keep it around in case you need to renew an" << ::std::endl
+ << " expired certificate, etc." << ::std::endl
+ << ::std::endl
+ << " name = example.com" << ::std::endl
+ << " org = Example, Inc" << ::std::endl
+ << " email = admin@example.com" << ::std::endl
+ << ::std::endl
+ << " [req]" << ::std::endl
+ << " distinguished_name = req_distinguished_name" << ::std::endl
+ << " x509_extensions = v3_req" << ::std::endl
+ << " prompt = no" << ::std::endl
+ << " utf8 = yes" << ::std::endl
+ << ::std::endl
+ << " [req_distinguished_name]" << ::std::endl
+ << " O = $org" << ::std::endl
+ << " CN = name:$name" << ::std::endl
+ << ::std::endl
+ << " [v3_req]" << ::std::endl
+ << " keyUsage = critical,digitalSignature" << ::std::endl
+ << " extendedKeyUsage = critical,codeSigning" << ::std::endl
+ << " subjectAltName = email:$email" << ::std::endl
+ << ::std::endl
+ << " Adjust the first three lines to match your details. If the repository is" << ::std::endl
+ << " hosted by an organization, use the organization's name for \033[1morg\033[0m. If you host" << ::std::endl
+ << " it as an individual, put your full, real name there. Using any kind of" << ::std::endl
+ << " aliases or nicknames is a bad idea (except, again, for testing). Remember," << ::std::endl
+ << " users of your repository will be presented with this information and if" << ::std::endl
+ << " they see it was signed by someone named SmellySnook, they will unlikely" << ::std::endl
+ << " trust it. Also use a working email address in case users need to contact" << ::std::endl
+ << " you about issues with your certificate. Note that the \033[1mname:\033[0m prefix in the" << ::std::endl
+ << " \033[1mCN\033[0m value is not a typo." << ::std::endl
+ << ::std::endl
+ << " The \033[1mname\033[0m field is a canonical repository name prefix with the \033[1mpkg:\033[0m type" << ::std::endl
+ << " part stripped. Any repository with a canonical name that starts with this" << ::std::endl
+ << " prefix can be authenticated by this certificate (see the repository" << ::std::endl
+ << " manifest documentation for more information on canonical names). For" << ::std::endl
+ << " example, name \033[1mexample.com\033[0m will match any repository hosted on" << ::std::endl
+ << " \033[1m{,www.,pkg.,bpkg.}example.com\033[0m. While name \033[1mexample.com/math\033[0m will match" << ::std::endl
+ << " \033[1m{...}example.com/pkg/1/math\033[0m but not \033[1m{...}example.com/pkg/1/misc\033[0m." << ::std::endl
+ << ::std::endl
+ << " A certificate name can also contain a subdomain wildcard. A wildcard name" << ::std::endl
+ << " in the \033[1m*.example.com\033[0m form matches any single-level subdomain, for example" << ::std::endl
+ << " \033[1mfoo.example.com\033[0m but not \033[1mfoo.bar.example.com\033[0m while a wildcard name in the" << ::std::endl
+ << " \033[1m**.example.com\033[0m form matches any subdomain, including multi-level. The above" << ::std::endl
+ << " two forms do not match the domain itself (\033[1mexample.com\033[0m in the above" << ::std::endl
+ << " example). If this is desired, the \033[1m*example.com\033[0m and \033[1m**example.com\033[0m forms" << ::std::endl
+ << " should be used instead. Note that these forms still only match subdomains." << ::std::endl
+ << " In other words, they won't match \033[1mfooexample.com\033[0m. Wildcard names are less" << ::std::endl
+ << " secure and therefore are normally only used for testing and/or internal" << ::std::endl
+ << " repositories." << ::std::endl
+ << ::std::endl
+ << " Once the configuration file is ready, generate the certificate:" << ::std::endl
+ << ::std::endl
+ << " openssl req -x509 -new -sha256 -key key.pem \\" << ::std::endl
+ << " -config cert.conf -days 730 >cert.pem" << ::std::endl
+ << ::std::endl
+ << " To verify the certificate information, run:" << ::std::endl
+ << ::std::endl
+ << " openssl x509 -noout -nameopt RFC2253,sep_multiline \\" << ::std::endl
+ << " -subject -dates -email <cert.pem" << ::std::endl
+ << ::std::endl
+ << "3. Add Certificate to Repository" << ::std::endl
+ << ::std::endl
+ << " Add the \033[1mcertificate:\033[0m field for the base repository (\033[1mrole: base\033[0m) in the" << ::std::endl
+ << " \033[1mrepositories\033[0m manifest file(s):" << ::std::endl
+ << ::std::endl
+ << " certificate:" << ::std::endl
+ << " \\" << ::std::endl
+ << " <cert>" << ::std::endl
+ << " \\" << ::std::endl
+ << ::std::endl
+ << " Replace \033[4mcert\033[0m with the entire contents of \033[1mcert.pem\033[0m (including the BEGIN" << ::std::endl
+ << " CERTIFICATE\033[0m and END CERTIFICATE\033[0m lines). So you will have an entry like" << ::std::endl
+ << " this:" << ::std::endl
+ << ::std::endl
+ << " certificate:" << ::std::endl
+ << " \\" << ::std::endl
+ << " -----BEGIN CERTIFICATE-----" << ::std::endl
+ << " MIIDQjCCAiqgAwIBAgIJAIUgsIqSnesGMA0GCSqGSIb3DQEBCwUAMDkxFzAVBgNV" << ::std::endl
+ << " ." << ::std::endl
+ << " ." << ::std::endl
+ << " ." << ::std::endl
+ << " +NOVBamEvjn58ZcLfWh2oKee7ulIZg==" << ::std::endl
+ << " -----END CERTIFICATE-----" << ::std::endl
+ << " \\" << ::std::endl
+ << ::std::endl
+ << "4. Sign Repository" << ::std::endl
+ << ::std::endl
+ << " When generating the repository manifests with the \033[1mbpkg-rep-create(1)\033[0m" << ::std::endl
+ << " command, specify the path to \033[1mkey.pem\033[0m with the \033[1m--key\033[0m option:" << ::std::endl
+ << ::std::endl
+ << " bpkg rep-create --key /path/to/key.pem /path/to/repository" << ::std::endl
+ << ::std::endl
+ << " You will be prompted for a password to unlock the private key." << ::std::endl
+ << ::std::endl
+ << "5. Using PIV/PKCS#11 Device" << ::std::endl
+ << ::std::endl
+ << " This optional step shows how to load the private key into Yubikey 4 and" << ::std::endl
+ << " then use it instead of the private key itself for signing the repository." << ::std::endl
+ << " Note that you will need OpenSSL 1.0.2 or later for the signing part to" << ::std::endl
+ << " work." << ::std::endl
+ << ::std::endl
+ << " First change the Yubikey MKEY, PUK, and PIN if necessary. You should" << ::std::endl
+ << " definitely do this if it still has the factory defaults. Then import the" << ::std::endl
+ << " private key and the certificate into Yubikey (replace \033[4mmkey\033[0m with the" << ::std::endl
+ << " management key):" << ::std::endl
+ << ::std::endl
+ << " yubico-piv-tool --key=<mkey> -a import-key -s 9c <key.pem" << ::std::endl
+ << " yubico-piv-tool --key=<mkey> -a import-certificate -s 9c <cert.pem" << ::std::endl
+ << ::std::endl
+ << " After this you will normally save the certificate/private key onto backup" << ::std::endl
+ << " media, store it in a secure, offline location, and remove the key from the" << ::std::endl
+ << " build machine." << ::std::endl
+ << ::std::endl
+ << " To sign the repository with Yubikey specify the following options instead" << ::std::endl
+ << " of just \033[1m--key\033[0m as at step 4 (\"SIGN key\"\033[0m is the label for the slot 9c\033[0m private" << ::std::endl
+ << " key):" << ::std::endl
+ << ::std::endl
+ << " bpkg rep-create \\" << ::std::endl
+ << " --openssl-option pkeyutl:-engine --openssl-option pkeyutl:pkcs11 \\" << ::std::endl
+ << " --openssl-option pkeyutl:-keyform --openssl-option pkeyutl:engine \\" << ::std::endl
+ << " --key \"pkcs11:object=SIGN%20key\" /path/to/repository" << ::std::endl
+ << ::std::endl
+ << " Note that for \033[1mopenssl\033[0m versions prior to \033[1m3.0.0\033[0m \033[1mbpkg\033[0m uses the \033[1mrsautl\033[0m command" << ::std::endl
+ << " instead of \033[1mpkeyutl\033[0m for the data signing operation." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/repository-signing.hxx b/bpkg/repository-signing.hxx
new file mode 100644
index 0000000..d5338e1
--- /dev/null
+++ b/bpkg/repository-signing.hxx
@@ -0,0 +1,31 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_REPOSITORY_SIGNING_HXX
+#define BPKG_REPOSITORY_SIGNING_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_repository_signing_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_REPOSITORY_SIGNING_HXX
diff --git a/bpkg/repository-types.cxx b/bpkg/repository-types.cxx
new file mode 100644
index 0000000..90efcdd
--- /dev/null
+++ b/bpkg/repository-types.cxx
@@ -0,0 +1,206 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/repository-types.hxx>
+
+#include <map>
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_repository_types_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "This help topic describes the repository types recognized by \033[1mbpkg\033[0m, their" << ::std::endl
+ << "structure, and the format of their URLs. Currently three types of repositories" << ::std::endl
+ << "are supported: archive-based \033[1mpkg\033[0m, directory-based \033[1mdir\033[0m, and version" << ::std::endl
+ << "control-based \033[1mgit\033[0m." << ::std::endl
+ << ::std::endl
+ << "The repository location may specify the repository type as part of the URL" << ::std::endl
+ << "scheme component in the \033[4mtype\033[0m\033[1m+\033[0m\033[4mprotocol\033[0m\033[0m form. For example:" << ::std::endl
+ << ::std::endl
+ << "git+https://example.com/foo" << ::std::endl
+ << "dir+file:///tmp/repo" << ::std::endl
+ << ::std::endl
+ << "Note that the explicit specification is only needed when the correct type" << ::std::endl
+ << "cannot be guessed from the URL. See \033[1mbpkg-rep-add(1)\033[0m for details." << ::std::endl
+ << ::std::endl
+ << "\033[1mPKG REPOSITORIES\033[0m" << ::std::endl
+ << ::std::endl
+ << "A \033[1mpkg\033[0m repository is \033[4marchive\033[0m-based. That is, it contains a collection of various" << ::std::endl
+ << "packages/versions as archive files. For more information on the structure of" << ::std::endl
+ << "\033[1mpkg\033[0m repositories refer to The \033[1mbuild2\033[0m Package Manager Manual (bpkg). The \033[1mpkg\033[0m" << ::std::endl
+ << "repository location can be a local directory path or an \033[1mhttp(s)://\033[0m URL." << ::std::endl
+ << ::std::endl
+ << "\033[1mDIR REPOSITORIES\033[0m" << ::std::endl
+ << ::std::endl
+ << "A \033[1mdir\033[0m repository is \033[4mdirectory\033[0m-based. That is, it contains a collection of" << ::std::endl
+ << "various packages as directories but only a single version per package can be" << ::std::endl
+ << "present in such a repository. The \033[1mdir\033[0m repository location can be a local" << ::std::endl
+ << "directory path or a \033[1mfile://\033[0m URL." << ::std::endl
+ << ::std::endl
+ << "A \033[1mdir\033[0m repository is expected to contain either the \033[1mmanifest\033[0m or" << ::std::endl
+ << "\033[1mpackages.manifest\033[0m file in the root directory of the repository. If it only" << ::std::endl
+ << "contains \033[1mmanifest\033[0m, then it is assumed to be a simple, single-package repository" << ::std::endl
+ << "with the \033[1mmanifest\033[0m file being its package manifest. Otherwise, the" << ::std::endl
+ << "\033[1mpackages.manifest\033[0m file should list the locations of available packages as" << ::std::endl
+ << "described in Package List Manifest for \033[1mdir\033[0m Repositories" << ::std::endl
+ << "(bpkg#manifest-package-list-dir)." << ::std::endl
+ << ::std::endl
+ << "A \033[1mdir\033[0m repository may also contain the \033[1mrepositories.manifest\033[0m file in the root" << ::std::endl
+ << "directory of the repository. This file can be used to describe the repository" << ::std::endl
+ << "itself as well as specify its prerequisite and complement repositories. See" << ::std::endl
+ << "Repository List Manifest (bpkg#manifest-repository-list) for details on the" << ::std::endl
+ << "format and semantics of this file." << ::std::endl
+ << ::std::endl
+ << "\033[1mGIT REPOSITORIES\033[0m" << ::std::endl
+ << ::std::endl
+ << "A \033[1mgit\033[0m repository is \033[4mversion control\033[0m-based. That is, it normally contains" << ::std::endl
+ << "multiple versions of the same package (but can also contain several, usually" << ::std::endl
+ << "related, packages in the same repository)." << ::std::endl
+ << ::std::endl
+ << "A \033[1mgit\033[0m repository has the same structure and manifest files as the \033[1mdir\033[0m" << ::std::endl
+ << "repository. See Package List Manifest for \033[1mdir\033[0m Repositories" << ::std::endl
+ << "(bpkg#manifest-package-list-dir) and Repository List Manifest" << ::std::endl
+ << "(bpkg#manifest-repository-list) for details on their format and semantics." << ::std::endl
+ << ::std::endl
+ << "Theoretically, a \033[1mgit\033[0m repository may contain as many package versions as there" << ::std::endl
+ << "are commits. Practically, however, we are normally only interested in a small" << ::std::endl
+ << "subset of them while fetching and processing the necessary information for all" << ::std::endl
+ << "of them could be prohibitively expensive. As a result, by default, only" << ::std::endl
+ << "advertised tags in the \033[1mrefs/tags/v*\033[0m form where the part after \033[1mv\033[0m is also a valid" << ::std::endl
+ << "standard version (b#module-version) are considered to be sources of useful" << ::std::endl
+ << "package versions. These commits normally correspond to released versions and" << ::std::endl
+ << "are called the \033[4mdefault set\033[0m. Note that only the latest revision of each such" << ::std::endl
+ << "version is considered." << ::std::endl
+ << ::std::endl
+ << "Instead of the default set, it is possible to provide a custom set of available" << ::std::endl
+ << "versions by specifying one or more commit ids and/or references and/or" << ::std::endl
+ << "reference patterns in the repository URL fragment (see \033[1mgit-ls-remote(1)\033[0m for" << ::std::endl
+ << "details on advertised references). For example:" << ::std::endl
+ << ::std::endl
+ << "https://example.com/foo.git#v1.2.3" << ::std::endl
+ << "https://example.com/foo.git#master" << ::std::endl
+ << "https://example.com/foo.git#af234f56" << ::std::endl
+ << "https://example.com/foo.git#tags/releases/*" << ::std::endl
+ << "https://example.com/foo.git#HEAD,tags/v1.*.*,heads/feature-*" << ::std::endl
+ << ::std::endl
+ << "Furthermore, it is possible to expand (or narrow down) the default set using" << ::std::endl
+ << "the special \033[1m##\033[0m fragment notation. For example:" << ::std::endl
+ << ::std::endl
+ << "https://example.com/foo.git##HEAD - default set plus HEAD" << ::std::endl
+ << "https://example.com/foo.git##heads/* - default set plus branches" << ::std::endl
+ << "https://example.com/foo.git##-v1.* - default set minus v1.*" << ::std::endl
+ << ::std::endl
+ << "A \033[1mgit\033[0m repository URL fragment is a comma-separated list of reference filters in" << ::std::endl
+ << "the following form:" << ::std::endl
+ << ::std::endl
+ << "[\033[4mrefname\033[0m][\033[1m@\033[0m\033[4mcommit\033[0m]\033[0m" << ::std::endl
+ << ::std::endl
+ << "Either \033[4mrefname\033[0m, \033[4mcommit\033[0m, or both must be specified. If both are specified then" << ::std::endl
+ << "\033[4mrefname\033[0m is only used to minimize the amount of data fetched and \033[4mcommit\033[0m is" << ::std::endl
+ << "expected to belong to its history. For example:" << ::std::endl
+ << ::std::endl
+ << ".../foo.git#master@48fba3625d65941bb85a39061bcf795d4949c778" << ::std::endl
+ << ::std::endl
+ << "The \033[4mrefname\033[0m part can be an abbreviated commit id or an advertised reference or" << ::std::endl
+ << "reference pattern under \033[1mrefs/\033[0m. While \033[4mcommit\033[0m must be the complete, 40-characters" << ::std::endl
+ << "SHA1 that need not be advertised. For convenience, a 40-characters filter that" << ::std::endl
+ << "consists of only hexadecimal digits is assumed to be \033[4mcommit\033[0m even if not" << ::std::endl
+ << "prefixed with \033[1m@\033[0m. In an unlikely event this produces an incorrect result, the" << ::std::endl
+ << "\033[1m@\033[0m-form with omitted \033[4mcommit\033[0m can be used. For example:" << ::std::endl
+ << ::std::endl
+ << ".../foo.git#48fba3625d65941bb85a39061bcf795d4949c778 (commit id)" << ::std::endl
+ << ".../foo.git#deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@ (reference)" << ::std::endl
+ << ::std::endl
+ << "The \033[4mrefname\033[0m part can use the \033[1m*\033[0m and \033[1m?\033[0m wildcard pattern characters with the" << ::std::endl
+ << "standard semantics as well as the \033[1m**\033[0m character sequence which matches in" << ::std::endl
+ << "subdirectories, recursively. For example:" << ::std::endl
+ << ::std::endl
+ << ".../foo.git#tags/v* - tags/v1.2.3 but not tags/old/v0.1.0" << ::std::endl
+ << ".../foo.git#tags/v** - tags/v1.2.3 and tags/old/v0.1.0" << ::std::endl
+ << ::std::endl
+ << "A relative \033[4mrefname\033[0m is searched for in \033[1mrefs/\033[0m, \033[1mrefs/tags/\033[0m, and \033[1mrefs/heads/\033[0m as" << ::std::endl
+ << "well as among symbolic references like \033[1mHEAD\033[0m. To anchor it to \033[1mrefs/\033[0m make it" << ::std::endl
+ << "absolute, for example:" << ::std::endl
+ << ::std::endl
+ << ".../foo.git#tags/v* - refs/tags/v1.2.3 but also refs/heads/tags/voo" << ::std::endl
+ << ".../foo.git#/tags/v* - refs/tags/v1.2.3 only" << ::std::endl
+ << ::std::endl
+ << "While a \033[4mrefname\033[0m pattern is allowed not match any references, a non-pattern that" << ::std::endl
+ << "doesn't resolve to a reference is invalid." << ::std::endl
+ << ::std::endl
+ << "If a \033[4mrefname\033[0m starts with minus (\033[1m-\033[0m) then it is treated as an exclusion filter --" << ::std::endl
+ << "any references that it matches are excluded from the set included by the" << ::std::endl
+ << "preceding filters (or the default set). For example:" << ::std::endl
+ << ::std::endl
+ << ".../foo.git#v*,-v1.* - exclude v1.* from v*" << ::std::endl
+ << ".../foo.git##-v1.* - exclude v1.* from default set" << ::std::endl
+ << ::std::endl
+ << "To support specifying literal leading minus, a \033[4mrefname\033[0m that starts with plus" << ::std::endl
+ << "(\033[1m+\033[0m) is treated as an inclusion filter. For example:" << ::std::endl
+ << ::std::endl
+ << ".../foo.git#+x - include x" << ::std::endl
+ << ".../foo.git#+-x - include -x" << ::std::endl
+ << ".../foo.git#++x - include +x" << ::std::endl
+ << ::std::endl
+ << "Currently supported \033[1mgit\033[0m protocols are \033[1mgit://\033[0m, \033[1mssh://\033[0m (but not scp\033[0m pseudo-URL" << ::std::endl
+ << "syntax), \033[1mhttp://\033[0m, and \033[1mhttps://\033[0m for remote repositories and \033[1mfile://\033[0m for local" << ::std::endl
+ << "repositories. While \033[1mbpkg\033[0m tries to minimize the amount of information (history)" << ::std::endl
+ << "fetched, it is not always possible for some protocols and/or server" << ::std::endl
+ << "configurations, as discussed next." << ::std::endl
+ << ::std::endl
+ << "A \033[1mgit\033[0m repository accessible via \033[1mhttp(s)://\033[0m can use either \033[4mdumb\033[0m or \033[4msmart\033[0m" << ::std::endl
+ << "protocol (refer to the \033[1mgit\033[0m documentation for details). The dumb protocol" << ::std::endl
+ << "provides only limited support for fetch minimization and if this protocol is" << ::std::endl
+ << "used, then \033[1mbpkg\033[0m has no choice but to download a substantial amount of history." << ::std::endl
+ << ::std::endl
+ << "The smart protocol allows fetching of minimal history for tags and branches." << ::std::endl
+ << "Whether this is also possible for (all) commit ids depends on whether the" << ::std::endl
+ << "server is configured to allow fetching unadvertised commits. For details, refer" << ::std::endl
+ << "to the \033[1muploadpack.allowReachableSHA1InWant\033[0m and \033[1muploadpack.allowAnySHA1InWant\033[0m" << ::std::endl
+ << "\033[1mgit\033[0m configuration values." << ::std::endl
+ << ::std::endl
+ << "The \033[1mgit://\033[0m and \033[1mssh://\033[0m protocols are similar to smart \033[1mhttp://\033[0m in that they" << ::std::endl
+ << "support fetching minimal history for tags and branches and may or may not" << ::std::endl
+ << "support this for commit ids depending on the server configuration. Note," << ::std::endl
+ << "however, that unlike for \033[1mhttp(s)://\033[0m, for these protocols \033[1mbpkg\033[0m does not try to" << ::std::endl
+ << "sense if fetching unadvertised commits is allowed and always assumes that it is" << ::std::endl
+ << "not. Also note that the sensed or assumed protocol capabilities can be" << ::std::endl
+ << "overridden for a \033[1mgit\033[0m repository URL prefix using the \033[1m--git-capabilities\033[0m option" << ::std::endl
+ << "(\033[1mbpkg-common-options(1)\033[0m)." << ::std::endl
+ << ::std::endl
+ << "Based on this information, to achieve optimal results the recommended protocol" << ::std::endl
+ << "for remote repositories is smart \033[1mhttps://\033[0m. Additionally, if you are planning to" << ::std::endl
+ << "refer to unadvertised commit ids, then also consider configuring the server to" << ::std::endl
+ << "allow fetching unadvertised commits." << ::std::endl
+ << ::std::endl
+ << "The \033[1mfile://\033[0m protocol has the same fetch minimization support as \033[1mgit://\033[0m and is" << ::std::endl
+ << "therefore treated the same." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/repository-types.hxx b/bpkg/repository-types.hxx
new file mode 100644
index 0000000..b62deed
--- /dev/null
+++ b/bpkg/repository-types.hxx
@@ -0,0 +1,31 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_REPOSITORY_TYPES_HXX
+#define BPKG_REPOSITORY_TYPES_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_repository_types_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_REPOSITORY_TYPES_HXX
diff --git a/bpkg/system-package-manager-fedora.cxx b/bpkg/system-package-manager-fedora.cxx
index 61ded1a..b4e9e10 100644
--- a/bpkg/system-package-manager-fedora.cxx
+++ b/bpkg/system-package-manager-fedora.cxx
@@ -191,6 +191,104 @@ namespace bpkg
static process_path dnf_path;
static process_path sudo_path;
+ // Note that dnf5 introduces quite a lot of changes to the command line
+ // interface. See the full list of changes between dnf and dnf5 at
+ // https://dnf5.readthedocs.io/en/latest/changes_from_dnf4.7.html.
+ //
+
+ // Run `dnf --version`, parse the output, and return true for dnf of the
+ // version 5 and above. Cache the value returned on the first call.
+ //
+ static optional<bool> dnf_version_5;
+
+ static bool
+ dnf5 ()
+ {
+ // Note that `dnf --version` output looks as follows for dnf5:
+ //
+ // dnf5 version 5.2.6.2
+ // dnf5 plugin API version 2.0
+ // libdnf5 version 5.2.6.2
+ // libdnf5 plugin API version 2.0
+ //
+ // Loaded dnf5 plugins:
+ // ...
+ //
+ // and as follows for the earlier versions:
+ //
+ // 4.19.2
+ // Installed: dnf-0:4.19.2-1.fc39.noarch at Sat 15 Jun 2024 07:37:35 PM GMT
+ // Built : Fedora Project at Fri 29 Mar 2024 06:55:12 PM GMT
+ //
+ // Installed: rpm-0:4.19.1.1-1.fc39.x86_64 at Sat 15 Jun 2024 07:37:18 PM GMT
+ // Built : Fedora Project at Wed 07 Feb 2024 04:05:57 PM GMT
+ //
+ // We will return true if the first line of the output starts with "dnf",
+ // assuming (perhaps a bit optimistically) that the first line format will
+ // not change in the future.
+ //
+ if (!dnf_version_5)
+ {
+ cstrings args {"dnf", "--version", nullptr};
+ const char* evars[] = {"LC_ALL=C", nullptr};
+
+ try
+ {
+ process_path pp (process::path_search (args[0]));
+ process_env pe (pp, evars);
+
+ if (verb >= 3)
+ print_process (pe, args);
+
+ process pr (pp, args, -2 /* stdin */, -1 /* stdout */, 2);
+
+ string l;
+ try
+ {
+ ifdstream is (move (pr.in_ofd), fdstream_mode::skip);
+ getline (is, l);
+ is.close ();
+ }
+ catch (const io_error& e)
+ {
+ if (pr.wait ())
+ fail << "unable to read " << args[0] << " --version output: " << e;
+
+ // Fall through.
+ }
+
+ if (!pr.wait ())
+ {
+ diag_record dr (fail);
+ dr << args[0] << " exited with non-zero code";
+
+ if (verb < 3)
+ {
+ dr << info << "command line: ";
+ print_process (dr, pe, args);
+ }
+ }
+
+ if (l.empty ())
+ fail << "unable to retrieve dnf version from " << args[0]
+ << " --version output";
+
+ dnf_version_5 = (l.compare (0, 3, "dnf") == 0);
+ }
+ catch (const process_error& e)
+ {
+ error << "unable to execute " << args[0] << ": " << e;
+
+ if (e.child)
+ exit (1);
+
+ throw failed ();
+ }
+ }
+
+ return *dnf_version_5;
+ }
+
// Obtain the installed and candidate versions for the specified list of
// Fedora packages by executing `dnf list`.
//
@@ -204,13 +302,14 @@ namespace bpkg
assert (n != 0 && n <= pis.size ());
+ // Lists all packages: installed, available, or both.
+ //
// The --quiet option makes sure we don't get 'Last metadata expiration
// check: <timestamp>' printed to stderr. It does not appear to affect
// error diagnostics (try specifying a single unknown package).
//
cstrings args {
"dnf", "list",
- "--all", // Look for both installed and available.
"--cacheonly", // Don't automatically update the metadata.
"--quiet"};
@@ -262,6 +361,7 @@ namespace bpkg
//
process pr;
if (!simulate_)
+ {
pr = process (dnf_path,
args,
-2 /* stdin */,
@@ -269,6 +369,7 @@ namespace bpkg
2 /* stderr */,
nullptr /* cwd */,
evars);
+ }
else
{
strings k;
@@ -314,10 +415,11 @@ namespace bpkg
// The output of `dnf list <pkg1> <pkg2> ...` is the 2 groups of lines
// in the following form:
//
- // Installed Packages
+ // Installed packages
// <pkg1>.<arch1> 13.0.0-3.fc35 @<repo1>
// <pkg2>.<arch2> 69.1-6.fc35 @<repo2>
- // Available Packages
+ //
+ // Available packages
// <pkg1>.<arch1> 13.0.1-1.fc35 <repo1>
// <pkg3>.<arch3> 1.2.11-32.fc35 <repo3>
//
@@ -325,8 +427,8 @@ namespace bpkg
// necessarily match the order of the packages on the command line.
// It looks like there should be not blank lines but who really knows.
//
- // Note also that if a package appears in the 'Installed Packages'
- // group, then it only appears in the 'Available Packages' if the
+ // Note also that if a package appears in the 'Installed packages'
+ // group, then it only appears in the 'Available packages' if the
// candidate version is better. Only the single (best) available
// version is listed, which we call the candidate version.
//
@@ -338,14 +440,22 @@ namespace bpkg
print_process (dr, pe, args);
});
- // Keep track of whether we are inside of the 'Installed Packages'
- // or 'Available Packages' sections.
+ // Keep track of whether we are inside of the 'Installed packages'
+ // or 'Available packages' sections.
+ //
+ // Note that dnf prior to dnf5 prints "Installed Packages" and
+ // "Available Packages".
//
optional<bool> installed;
for (string l; !eof (getline (is, l)); )
{
- if (l == "Installed Packages")
+ // Skip empty lines.
+ //
+ if (l.empty ())
+ continue;
+
+ if (icasecmp (l, "Installed packages") == 0)
{
if (installed)
fail << "unexpected line '" << l << "'";
@@ -354,7 +464,7 @@ namespace bpkg
continue;
}
- if (l == "Available Packages")
+ if (icasecmp (l, "Available packages") == 0)
{
if (installed && !*installed)
fail << "duplicate line '" << l << "'";
@@ -506,7 +616,7 @@ namespace bpkg
// Note that if a Fedora package is installed but the repository doesn't
// contain a better version, then this package won't appear in the
- // 'Available Packages' section of the `dnf list` output and thus the
+ // 'Available packages' section of the `dnf list` output and thus the
// candidate_version will stay empty. Let's set it to the installed
// version in this case to be consistent with the Debian's semantics and
// keep the Fedora and Debian system package manager implementations
@@ -524,7 +634,8 @@ namespace bpkg
}
}
- // Execute `dnf repoquery --requires` for the specified
+ // Execute `dnf repoquery --providers-of=requires` (`dnf repoquery
+ // --requires` for dnf prior to dnf5) for the specified
// package/version/architecture and return its dependencies as a list of the
// name/version pairs.
//
@@ -567,11 +678,39 @@ namespace bpkg
// error diagnostics (try specifying an unknown option).
//
cstrings args {
- "dnf", "repoquery", "--requires",
+ "dnf", "repoquery",
"--quiet",
- "--cacheonly", // Don't automatically update the metadata.
- "--resolve", // Resolve requirements to packages/versions.
- "--qf", "%{name} %{arch} %{epoch}:%{version}-%{release}"};
+ "--cacheonly"}; // Don't automatically update the metadata.
+
+ // Resolve requirements to packages/versions.
+ //
+ // Note that dnf5 has dropped the --resolve option, but the semantics of
+ // the --requires --resolve options combination can now be achieved with
+ // the --providers-of=requires option.
+ //
+ // Also note that for dnf5 the newline character needs to be specified
+ // explicitly in the --queryformat option value.
+ //
+ // As a side note, the full list of macros that can be used in the
+ // --queryformat value can be retrieved by the `dnf repoquery --querytags`
+ // command.
+ //
+ if (simulate_ || dnf5 ())
+ {
+ args.push_back ("--providers-of");
+ args.push_back ("requires");
+
+ args.push_back ("--queryformat");
+ args.push_back ("%{name} %{arch} %{epoch}:%{version}-%{release}\\n");
+ }
+ else
+ {
+ args.push_back ("--requires");
+ args.push_back ("--resolve");
+
+ args.push_back ("--queryformat");
+ args.push_back ("%{name} %{arch} %{epoch}:%{version}-%{release}");
+ }
// Note that installed packages which are not available from configured
// repositories (e.g. packages installed from local rpm files or temporary
@@ -591,7 +730,19 @@ namespace bpkg
// --install to make sure that all installed packages will be listed and
// no configuration file may influence the result.
//
- args.push_back ("--disableexcludes=all");
+ // Note that dnf5 has dropped the --disableexcludes command line option
+ // but has invented the disable_excludes configuration option instead.
+ //
+ if (simulate_ || dnf5 ())
+ {
+ args.push_back ("--setopt");
+ args.push_back ("disable_excludes=*");
+ }
+ else
+ {
+ args.push_back ("--disableexcludes");
+ args.push_back ("all");
+ }
}
args.push_back (spec.c_str ());
@@ -661,9 +812,9 @@ namespace bpkg
ifdstream is (move (pr.in_ofd), fdstream_mode::skip, ifdstream::badbit);
// The output of the command will be the sequence of the package lines
- // in the `<name> <arc> <version>` form (per the -qf option above). So
- // for example for the libicu-devel-69.1-6.fc35.x86_64 package it is
- // as follows:
+ // in the `<name> <arc> <version>` form (per the --queryformat option
+ // above). So for example for the libicu-devel-69.1-6.fc35.x86_64
+ // package it is as follows:
//
// bash i686 0:5.1.8-3.fc35
// bash x86_64 0:5.1.8-3.fc35
@@ -731,8 +882,9 @@ namespace bpkg
catch (const io_error& e)
{
if (pr.wait ())
- fail << "unable to read " << args[0] << " repoquery --requires "
- << "output: " << e;
+ fail << "unable to read " << args[0] << " repoquery "
+ << (dnf5 () ? "--providers-of=requires" : "--requires")
+ << " output: " << e;
// Fall through.
}
@@ -766,6 +918,7 @@ namespace bpkg
//
pair<cstrings, const process_path&> system_package_manager_fedora::
dnf_common (const char* command,
+ const char* subcommand,
optional<size_t> fetch_timeout,
strings& args_storage)
{
@@ -782,6 +935,9 @@ namespace bpkg
args.push_back ("dnf");
args.push_back (command);
+ if (subcommand != nullptr)
+ args.push_back (subcommand);
+
// Map our verbosity/progress to dnf --quiet and --verbose options.
//
// Note that all the diagnostics, including the progress indication and
@@ -817,11 +973,12 @@ namespace bpkg
//
if (fetch_timeout)
{
- args_storage.push_back (
- "--setopt=timeout=" + to_string (*fetch_timeout));
-
+ args.push_back ("--setopt");
+ args_storage.push_back ("timeout=" + to_string (*fetch_timeout));
args.push_back (args_storage.back ().c_str ());
- args.push_back ("--setopt=minrate=0");
+
+ args.push_back ("--setopt");
+ args.push_back ("minrate=0");
}
try
@@ -851,6 +1008,17 @@ namespace bpkg
}
}
+ pair<cstrings, const process_path&> system_package_manager_fedora::
+ dnf_common (const char* command,
+ optional<size_t> fetch_timeout,
+ strings& args_storage)
+ {
+ return dnf_common (command,
+ nullptr /* subcommand */,
+ fetch_timeout,
+ args_storage);
+ }
+
// Execute `dnf makecache` to download and cache the repositories metadata.
//
void system_package_manager_fedora::
@@ -954,7 +1122,8 @@ namespace bpkg
// save us from attempting to download no longer existing packages).
//
#if 0
- args.push_back ("--setopt=metadata_expire=never");
+ args.push_back ("--setopt");
+ args.push_back ("metadata_expire=never");
#endif
for (const string& p: pkgs)
@@ -1011,18 +1180,19 @@ namespace bpkg
}
}
- // Execute `dnf mark install` to mark the installed packages as installed by
- // the user (see dnf_install() for details on the package specs).
+ // Execute `dnf mark user` (`dnf mark install` for dnf prior to dnf5) to
+ // mark the installed packages as installed by the user (see dnf_install()
+ // for details on the package specs).
//
// Note that an installed package may be marked as installed by the user
// rather than as a dependency. In particular, such a package will never be
// automatically removed as an unused dependency. This mark can be added and
- // removed by the `dnf mark install` and `dnf mark remove` commands,
- // respectively. Besides that, this mark is automatically added by `dnf
- // install` for a package specified on the command line, but only if it is
- // not yet installed. Note that this mark will not be added automatically
- // for an already installed package even if it is upgraded explicitly. For
- // example:
+ // removed by the `dnf mark user` and `dnf mark dependency` (`dnf mark
+ // remove` for dnf prior to dnf5) commands, respectively. Besides that, this
+ // mark is automatically added by `dnf install` for a package specified on
+ // the command line, but only if it is not yet installed. Note that this
+ // mark will not be added automatically for an already installed package
+ // even if it is upgraded explicitly. For example:
//
// $ sudo dnf install libsigc++30-devel-3.0.2-2.fc32 --repofrompath test,./repo --setopt=gpgcheck=0 --assumeyes
// Installed: libsigc++30-3.0.2-2.fc32.x86_64 libsigc++30-devel-3.0.2-2.fc32.x86_64
@@ -1040,12 +1210,14 @@ namespace bpkg
strings args_storage;
pair<cstrings, const process_path&> args_pp (
- dnf_common ("mark", nullopt /* fetch_timeout */, args_storage));
+ dnf_common ("mark",
+ (simulate_ || dnf5 () ? "user" : "install"),
+ nullopt /* fetch_timeout */,
+ args_storage));
cstrings& args (args_pp.first);
const process_path& pp (args_pp.second);
- args.push_back ("install");
args.push_back ("--cacheonly");
for (const string& p: pkgs)
@@ -1061,9 +1233,14 @@ namespace bpkg
process pr;
if (!simulate_)
{
- // Redirect stdout to stderr.
+ // Redirect stdout to /dev/null for dnf5 (which prints some useless
+ // information) and to stderr for the earlier versions (which issue
+ // diagnostics to stdout rather than to stderr).
//
- pr = process (pp, args, 0 /* stdin */, 2 /* stdout */);
+ pr = process (pp, args,
+ 0 /* stdin */,
+ (dnf5 () ? -2 : 2) /* stdout */,
+ 2 /* stderr */);
}
else
{
@@ -1737,18 +1914,18 @@ namespace bpkg
// packages, including the fully installed ones. But we must be careful
// not to force their upgrade. To achieve this we will specify the
// installed version as the desired version. Whether we run `dnf install`
- // or not we will also always run `dnf mark install` afterwards for all
- // the packages to mark them as installed by the user.
+ // or not we will also always run `dnf mark user` afterwards for all the
+ // packages to mark them as installed by the user.
//
// Note also that for partially/not installed packages we used to not
// specify the version, expecting the candidate version to always be
// installed (we did specify the candidate architecture though, since for
// reasons unknown dnf may install a package of a different architecture
- // otherwise). This, however, turned out to not always be the case.
- // Moreover, we have observed such an undocumented behavior, that if the
- // package versions are not specified, then the dnf-install command
- // outcome may depend on the order of the packages specified on the
- // command line:
+ // otherwise). This, however, turned out to not always be the case (at
+ // least for dnf prior to dnf5). Moreover, we have observed such an
+ // undocumented behavior, that if the package versions are not specified,
+ // then the dnf-install command outcome may depend on the order of the
+ // packages specified on the command line:
//
// $ dnf list expat.x86_64 expat-devel.x86_64
// Installed Packages
@@ -2699,12 +2876,18 @@ namespace bpkg
dir_path licensedir;
dir_path build2dir;
- // Note that the ~/rpmbuild/{.,BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
- // directory paths used by rpmbuild are actually defined as the
- // %{_topdir}, %{_builddir}, %{_buildrootdir}, %{_rpmdir}, %{_sourcedir},
- // %{_specdir}, and %{_srcrpmdir} RPM macros. These macros can potentially
- // be redefined in RPM configuration files, in particular, in
- // ~/.rpmmacros.
+ // Note that the ~/rpmbuild/{.,BUILD,RPMS,SOURCES,SPECS,SRPMS} directory
+ // paths used by rpmbuild are actually defined as the %{_topdir},
+ // %{_builddir}, %{_rpmdir}, %{_sourcedir}, %{_specdir}, and %{_srcrpmdir}
+ // RPM macros. These macros can potentially be redefined in RPM
+ // configuration files, in particular, in ~/.rpmmacros.
+ //
+ // Also note that the newer versions of rpmbuild don't create the
+ // ~/rpmbuild/BUILDROOT directory and don't support the %{_buildrootdir}
+ // macro anymore. Instead, they create the package-specific
+ // ~/rpmbuild/BUILD/<package>-<version>-build/BUILDROOT directory. Thus,
+ // we always use the $RPM_BUILD_ROOT environment variable in the %install
+ // section of the RPM spec file, rather than the %{_buildrootdir} macro.
//
dir_path topdir; // ~/rpmbuild/
dir_path specdir; // ~/rpmbuild/SPECS/
@@ -2746,7 +2929,6 @@ namespace bpkg
expressions.push_back ("%{?_rpmdir}");
expressions.push_back ("%{?_rpmfilename}");
expressions.push_back ("%{?_usrsrc}");
- expressions.push_back ("%{?buildroot}");
// Note that if the architecture passed with the --target option is
// invalid, then rpmbuild will fail with some ugly diagnostics since
@@ -2820,7 +3002,6 @@ namespace bpkg
// We only need the following macro expansions for the verification.
//
pop_string (); // %{?_arch}
- pop_dir (); // %{?buildroot}
pop_dir (); // %{?_usrsrc}
pop_string (); // %{?_rpmfilename}
pop_dir (); // %{?_rpmdir}
@@ -2859,9 +3040,10 @@ namespace bpkg
// won't fight with rpmbuild and will use this tree as the user would
// do while creating the binary package manually.
//
- // Specifially, we will create the RPM spec file in ~/rpmbuild/SPECS/,
- // install the package(s) under the ~/rpmbuild/BUILDROOT/<package-dir>/
- // chroot, and expect the generated RPM files under ~/rpmbuild/RPMS/.
+ // Specifically, we will create the RPM spec file in ~/rpmbuild/SPECS/,
+ // install the package(s) under the $RPM_BUILD_ROOT chroot (set by
+ // rpmbuild while executing the %install section of the RPM spec file),
+ // and expect the generated RPM files under ~/rpmbuild/RPMS/.
//
// That, in particular, means that we have no use for the --output-root
// directory. We will also make sure that we don't overwrite an existing
@@ -3671,8 +3853,7 @@ namespace bpkg
// debugsources.list file is piped as an input to the cpio program
// executed in the ~/rpmbuild/BUILD/foo-1.0.0 directory as its
// current working directory, which tries to copy these source files
- // to the
- // ~/rpmbuild/BUILDROOT/foo-1.0.0-1.fc35.x86_64/usr/src/debug/foo-1.0.0-1.fc35.x86_64
+ // to the $RPM_BUILD_ROOT/usr/src/debug/foo-1.0.0-1.fc35.x86_64
// directory. Given that these source files are actually located in
// the bpkg configuration directory rather than in the
// ~/rpmbuild/BUILD/foo-1.0.0 directory the cpio program fails to
@@ -3760,7 +3941,7 @@ namespace bpkg
os << " \\\\\\\n " << v;
};
- add_macro_line ("config.install.chroot='%{buildroot}/'");
+ add_macro_line ("config.install.chroot=\"$RPM_BUILD_ROOT/\"");
add_macro_line ("config.install.sudo='[null]'");
// If this is a C-based language, add rpath for private installation.
diff --git a/bpkg/system-package-manager-fedora.hxx b/bpkg/system-package-manager-fedora.hxx
index 3e68b98..986d203 100644
--- a/bpkg/system-package-manager-fedora.hxx
+++ b/bpkg/system-package-manager-fedora.hxx
@@ -274,7 +274,13 @@ namespace bpkg
dnf_mark_install (const strings&);
pair<cstrings, const process_path&>
- dnf_common (const char*,
+ dnf_common (const char* command,
+ optional<size_t> fetch_timeout,
+ strings& args_storage);
+
+ pair<cstrings, const process_path&>
+ dnf_common (const char* command,
+ const char* subcommand,
optional<size_t> fetch_timeout,
strings& args_storage);
diff --git a/bpkg/system-package-manager-fedora.test.testscript b/bpkg/system-package-manager-fedora.test.testscript
index 3655514..09731b1 100644
--- a/bpkg/system-package-manager-fedora.test.testscript
+++ b/bpkg/system-package-manager-fedora.test.testscript
@@ -28,7 +28,7 @@
rpm.x86_64 4.17.1-3.fc35 updates
rust-uuid+std-devel.noarch 1.2.1-1.fc35 updates
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet openssl-libs openssl-devel openssl1.1 openssl1.1-devel libsigc++40 libcurl lrmi rust-uuid+std-devel rpm <-
+ LC_ALL=C dnf list --cacheonly --quiet openssl-libs openssl-devel openssl1.1 openssl1.1-devel libsigc++40 libcurl lrmi rust-uuid+std-devel rpm <-
EOE
openssl-libs '1:1.1.1q-1.fc35' 'x86_64' '1:1.1.1q-1.fc35' 'x86_64'
openssl-devel '1:1.1.1q-1.fc35' 'x86_64' '1:1.1.1q-1.fc35' 'x86_64'
@@ -47,7 +47,7 @@
rpm.x86_64 4.17.1-3.fc35 updates
Available Packages
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++40 rpm <-
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++40 rpm <-
EOE
libsigc++40 '' '' '' ''
EOO
@@ -61,7 +61,7 @@
lrmi.i686 0.10-28.fc35 fedora
rpm.x86_64 4.17.1-3.fc35 updates
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet lrmi rpm <-
+ LC_ALL=C dnf list --cacheonly --quiet lrmi rpm <-
EOE
lrmi '' '' '' ''
EOO
@@ -74,7 +74,7 @@
Available Packages
rpm.x86_64 4.17.1-3.fc35 updates
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet rpm rpm <-
+ LC_ALL=C dnf list --cacheonly --quiet rpm rpm <-
EOE
rpm '4.17.1-2.fc35' 'x86_64' '4.17.1-3.fc35' 'x86_64'
EOO
@@ -86,7 +86,7 @@
openssl-libs.i686 1:1.1.1q-1.fc35 @updates
openssl-libs.x86_64 1:1.1.1q-1.fc35 @updates
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet openssl-libs rpm <-
+ LC_ALL=C dnf list --cacheonly --quiet openssl-libs rpm <-
error: rpm package doesn't exist
EOE
}
@@ -109,7 +109,7 @@
pkgconf-pkg-config i686 0:1.8.0-1.fc35
pkgconf-pkg-config x86_64 0:1.8.0-1.fc35
EOI
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" --installed --disableexcludes=all openssl-devel-1:1.1.1q-1.fc35.x86_64 <-
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" --installed --setopt disable_excludes=* openssl-devel-1:1.1.1q-1.fc35.x86_64 <-
EOE
opae-devel 2.0.0-2.3.fc35
openssl-libs 1:1.1.1q-1.fc35
@@ -124,7 +124,7 @@
cargo x86_64 0:1.65.0-1.fc35
rust-uuid-devel noarch 0:1.2.1-1.fc35
EOI
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" rust-uuid+std-devel-1.2.1-1.fc35.noarch <-
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" rust-uuid+std-devel-1.2.1-1.fc35.noarch <-
EOE
cargo 1.65.0-1.fc35
rust-uuid-devel 1.2.1-1.fc35
@@ -151,7 +151,7 @@
systemd i686 0:249.13-6.fc35
systemd x86_64 0:249.13-6.fc35
EOI
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" --installed --disableexcludes=all dhcp-client-12:4.4.3-4.P1.fc35.x86_64 <-
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" --installed --setopt disable_excludes=* dhcp-client-12:4.4.3-4.P1.fc35.x86_64 <-
EOE
bash 5.1.8-3.fc35
coreutils 8.32-36.fc35
@@ -171,13 +171,13 @@
: no-depends
:
$* glibc 2.34-38.fc35 x86_64 true <:'' 2>>EOE >:''
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" --installed --disableexcludes=all glibc-2.34-38.fc35.x86_64 <-
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" --installed --setopt disable_excludes=* glibc-2.34-38.fc35.x86_64 <-
EOE
: unknown
:
$* glibg 2.34-38.fc35 x86_64 false <:'' 2>>EOE >:''
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" glibg-2.34-38.fc35.x86_64 <-
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" glibg-2.34-38.fc35.x86_64 <-
EOE
}
@@ -461,10 +461,10 @@
dnf-repoquery-requires: libpq-devel 13.4-1.fc35 x86_64 true libpq-devel.requires
dnf-list: libpq libpq.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" --installed --disableexcludes=all libpq-devel-13.4-1.fc35.x86_64 <libpq-devel.requires
- LC_ALL=C dnf list --all --cacheonly --quiet libpq rpm <libpq.info
- sudo dnf mark --quiet --assumeno install --cacheonly libpq-13.4-1.fc35.x86_64 libpq-devel-13.4-1.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" --installed --setopt disable_excludes=* libpq-devel-13.4-1.fc35.x86_64 <libpq-devel.requires
+ LC_ALL=C dnf list --cacheonly --quiet libpq rpm <libpq.info
+ sudo dnf mark user --quiet --assumeno --cacheonly libpq-13.4-1.fc35.x86_64 libpq-devel-13.4-1.fc35.x86_64
EOE
libpq 13.4 (libpq 13.4-1.fc35) installed
EOO
@@ -500,14 +500,14 @@
dnf-repoquery-requires: libpq-devel 13.4-1.fc35 x86_64 false libpq-devel.requires
dnf-list: libpq libpq.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" libpq-devel-13.4-1.fc35.x86_64 <libpq-devel.requires
- LC_ALL=C dnf list --all --cacheonly --quiet libpq rpm <libpq.info
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" libpq-devel-13.4-1.fc35.x86_64 <libpq-devel.requires
+ LC_ALL=C dnf list --cacheonly --quiet libpq rpm <libpq.info
sudo dnf install --quiet --assumeno libpq-13.4-1.fc35.x86_64 libpq-devel-13.4-1.fc35.x86_64
- sudo dnf mark --quiet --assumeno install --cacheonly libpq-13.4-1.fc35.x86_64 libpq-devel-13.4-1.fc35.x86_64
- LC_ALL=C dnf list --all --cacheonly --quiet libpq rpm <libpq.info
+ sudo dnf mark user --quiet --assumeno --cacheonly libpq-13.4-1.fc35.x86_64 libpq-devel-13.4-1.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet libpq rpm <libpq.info
EOE
libpq 13.4 (libpq 13.4-1.fc35) part installed
EOO
@@ -562,14 +562,14 @@
dnf-list-fetched: libpq libpq.info-fetched
dnf-list-installed: libpq libpq.info-installed
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info-fetched
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" libpq-devel-13.4-1.fc35.x86_64 <libpq-devel.requires-fetched
- LC_ALL=C dnf list --all --cacheonly --quiet libpq rpm <libpq.info-fetched
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info-fetched
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" libpq-devel-13.4-1.fc35.x86_64 <libpq-devel.requires-fetched
+ LC_ALL=C dnf list --cacheonly --quiet libpq rpm <libpq.info-fetched
sudo dnf install --quiet --assumeno libpq-13.4-1.fc35.x86_64 libpq-devel-13.4-1.fc35.x86_64
- sudo dnf mark --quiet --assumeno install --cacheonly libpq-13.4-1.fc35.x86_64 libpq-devel-13.4-1.fc35.x86_64
- LC_ALL=C dnf list --all --cacheonly --quiet libpq rpm <libpq.info-installed
+ sudo dnf mark user --quiet --assumeno --cacheonly libpq-13.4-1.fc35.x86_64 libpq-devel-13.4-1.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet libpq rpm <libpq.info-installed
EOE
libpq 13.4 (libpq 13.4-1.fc35) part installed
EOO
@@ -618,12 +618,12 @@
dnf-list: libpq libpq.info
dnf-list-installed: libpq libpq.info-installed
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" libpq-devel-13.3-3.fc35.x86_64 <libpq-devel.requires
- LC_ALL=C dnf list --all --cacheonly --quiet libpq rpm <libpq.info
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" libpq-devel-13.3-3.fc35.x86_64 <libpq-devel.requires
+ LC_ALL=C dnf list --cacheonly --quiet libpq rpm <libpq.info
sudo dnf install --quiet --assumeno libpq-13.3-3.fc35.x86_64 libpq-devel-13.3-3.fc35.x86_64
- sudo dnf mark --quiet --assumeno install --cacheonly libpq-13.3-3.fc35.x86_64 libpq-devel-13.3-3.fc35.x86_64
- LC_ALL=C dnf list --all --cacheonly --quiet libpq rpm <libpq.info-installed
+ sudo dnf mark user --quiet --assumeno --cacheonly libpq-13.3-3.fc35.x86_64 libpq-devel-13.3-3.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet libpq rpm <libpq.info-installed
error: unexpected fedora package version for libpq
info: expected: 13.3-3.fc35
info: installed: 13.4-1.fc35
@@ -672,14 +672,14 @@
dnf-list: libpq libpq.info
dnf-list-installed: libpq libpq.info-installed
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" libpq-devel-13.4-1.fc35.x86_64 <libpq-devel.requires
- LC_ALL=C dnf list --all --cacheonly --quiet libpq rpm <libpq.info
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" libpq-devel-13.4-1.fc35.x86_64 <libpq-devel.requires
+ LC_ALL=C dnf list --cacheonly --quiet libpq rpm <libpq.info
sudo dnf install --quiet --assumeno libpq-13.4-1.fc35.x86_64 libpq-devel-13.4-1.fc35.x86_64
- sudo dnf mark --quiet --assumeno install --cacheonly libpq-13.4-1.fc35.x86_64 libpq-devel-13.4-1.fc35.x86_64
- LC_ALL=C dnf list --all --cacheonly --quiet libpq rpm <libpq.info-installed
+ sudo dnf mark user --quiet --assumeno --cacheonly libpq-13.4-1.fc35.x86_64 libpq-devel-13.4-1.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet libpq rpm <libpq.info-installed
EOE
libpq 13.4 (libpq 13.4-1.fc35) not installed
EOO
@@ -698,7 +698,7 @@
$* libpq <<EOI 2>>EOE != 0
dnf-list: libpq-devel pq-devel libpq-devel+pq-devel.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
error: no installed system package for libpq
EOE
@@ -714,9 +714,9 @@
$* libpq --install libpq <<EOI 2>>EOE != 0
dnf-list: libpq-devel pq-devel libpq-devel+pq-devel.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
error: no installed or available system package for libpq
EOE
@@ -732,7 +732,7 @@
$* libpq --install --no-fetch libpq <<EOI 2>>EOE != 0
dnf-list: libpq-devel pq-devel libpq-devel+pq-devel.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libpq-devel pq-devel rpm <libpq-devel+pq-devel.info
error: no installed or available system package for libpq
EOE
}
@@ -761,9 +761,9 @@
$* libsqlite3 --install libsqlite3 <<EOI 2>>EOE != 0
dnf-list: libsqlite3-devel sqlite3-devel libsqlite3-devel+sqlite3-devel.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libsqlite3-devel sqlite3-devel rpm <libsqlite3-devel+sqlite3-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsqlite3-devel sqlite3-devel rpm <libsqlite3-devel+sqlite3-devel.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet libsqlite3-devel sqlite3-devel rpm <libsqlite3-devel+sqlite3-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsqlite3-devel sqlite3-devel rpm <libsqlite3-devel+sqlite3-devel.info
error: no installed or available system package for libsqlite3
EOE
@@ -803,10 +803,10 @@
dnf-repoquery-requires: sqlite-devel 3.36.0-3.fc35 x86_64 true sqlite-devel.requires
dnf-list: sqlite-libs sqlite-libs.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libsqlite3-devel sqlite-devel rpm <libsqlite3-devel+sqlite-devel.info
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" --installed --disableexcludes=all sqlite-devel-3.36.0-3.fc35.x86_64 <sqlite-devel.requires
- LC_ALL=C dnf list --all --cacheonly --quiet sqlite-libs rpm <sqlite-libs.info
- sudo dnf mark --quiet --assumeno install --cacheonly sqlite-libs-3.36.0-3.fc35.x86_64 sqlite-devel-3.36.0-3.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet libsqlite3-devel sqlite-devel rpm <libsqlite3-devel+sqlite-devel.info
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" --installed --setopt disable_excludes=* sqlite-devel-3.36.0-3.fc35.x86_64 <sqlite-devel.requires
+ LC_ALL=C dnf list --cacheonly --quiet sqlite-libs rpm <sqlite-libs.info
+ sudo dnf mark user --quiet --assumeno --cacheonly sqlite-libs-3.36.0-3.fc35.x86_64 sqlite-devel-3.36.0-3.fc35.x86_64
EOE
libsqlite3 3.36.0 (sqlite-libs 3.36.0-3.fc35) installed
EOO
@@ -864,14 +864,14 @@
dnf-list-fetched: sqlite-libs sqlite-libs.info-fetched
dnf-list-installed: sqlite-libs sqlite-libs.info-installed
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libsqlite3-devel sqlite-devel rpm <libsqlite3-devel+sqlite-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsqlite3-devel sqlite-devel rpm <libsqlite3-devel+sqlite-devel.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet libsqlite3-devel sqlite-devel rpm <libsqlite3-devel+sqlite-devel.info-fetched
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" sqlite-devel-3.36.0-3.fc35.x86_64 <sqlite-devel.requires-fetched
- LC_ALL=C dnf list --all --cacheonly --quiet sqlite-libs rpm <sqlite-libs.info-fetched
+ LC_ALL=C dnf list --cacheonly --quiet libsqlite3-devel sqlite-devel rpm <libsqlite3-devel+sqlite-devel.info-fetched
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" sqlite-devel-3.36.0-3.fc35.x86_64 <sqlite-devel.requires-fetched
+ LC_ALL=C dnf list --cacheonly --quiet sqlite-libs rpm <sqlite-libs.info-fetched
sudo dnf install --quiet --assumeno sqlite-libs-3.36.0-3.fc35.x86_64 sqlite-devel-3.36.0-3.fc35.x86_64
- sudo dnf mark --quiet --assumeno install --cacheonly sqlite-libs-3.36.0-3.fc35.x86_64 sqlite-devel-3.36.0-3.fc35.x86_64
- LC_ALL=C dnf list --all --cacheonly --quiet sqlite-libs rpm <sqlite-libs.info-installed
+ sudo dnf mark user --quiet --assumeno --cacheonly sqlite-libs-3.36.0-3.fc35.x86_64 sqlite-devel-3.36.0-3.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet sqlite-libs rpm <sqlite-libs.info-installed
EOE
libsqlite3 3.36.0 (sqlite-libs 3.36.0-3.fc35) not installed
EOO
@@ -901,9 +901,9 @@
$* sqlite3 --install sqlite3 <<EOI 2>>EOE != 0
dnf-list: sqlite3 sqlite3.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet sqlite3 rpm <sqlite3.info
+ LC_ALL=C dnf list --cacheonly --quiet sqlite3 rpm <sqlite3.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet sqlite3 rpm <sqlite3.info
+ LC_ALL=C dnf list --cacheonly --quiet sqlite3 rpm <sqlite3.info
error: no installed or available system package for sqlite3
EOE
@@ -927,8 +927,8 @@
dnf-list: sqlite3 sqlite sqlite3+sqlite.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet sqlite3 sqlite rpm <sqlite3+sqlite.info
- sudo dnf mark --quiet --assumeno install --cacheonly sqlite-3.36.0-3.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet sqlite3 sqlite rpm <sqlite3+sqlite.info
+ sudo dnf mark user --quiet --assumeno --cacheonly sqlite-3.36.0-3.fc35.x86_64
EOE
sqlite3 3.36.0 (sqlite 3.36.0-3.fc35) installed
EOO
@@ -968,12 +968,12 @@
dnf-list-fetched: sqlite3 sqlite sqlite3+sqlite.info-fetched
dnf-list-installed: sqlite sqlite.info-installed
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet sqlite3 sqlite rpm <sqlite3+sqlite.info
+ LC_ALL=C dnf list --cacheonly --quiet sqlite3 sqlite rpm <sqlite3+sqlite.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet sqlite3 sqlite rpm <sqlite3+sqlite.info-fetched
+ LC_ALL=C dnf list --cacheonly --quiet sqlite3 sqlite rpm <sqlite3+sqlite.info-fetched
sudo dnf install --quiet --assumeno sqlite-3.36.0-3.fc35.x86_64
- sudo dnf mark --quiet --assumeno install --cacheonly sqlite-3.36.0-3.fc35.x86_64
- LC_ALL=C dnf list --all --cacheonly --quiet sqlite rpm <sqlite.info-installed
+ sudo dnf mark user --quiet --assumeno --cacheonly sqlite-3.36.0-3.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet sqlite rpm <sqlite.info-installed
EOE
sqlite3 3.36.0 (sqlite 3.36.0-3.fc35) not installed
EOO
@@ -1054,11 +1054,11 @@
dnf-list: ncurses-libs ncurses-libs.info
dnf-list: ncurses-c++-libs ncurses-devel ncurses-c++-libs+ncurses-devel.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libncurses-devel ncurses-devel rpm <libncurses-devel+ncurses-devel.info
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" --installed --disableexcludes=all ncurses-devel-6.2-8.20210508.fc35.x86_64 <ncurses-devel.requires
- LC_ALL=C dnf list --all --cacheonly --quiet ncurses-libs rpm <ncurses-libs.info
- LC_ALL=C dnf list --all --cacheonly --quiet ncurses-c++-libs ncurses-devel rpm <ncurses-c++-libs+ncurses-devel.info
- sudo dnf mark --quiet --assumeno install --cacheonly ncurses-libs-6.2-8.20210508.fc35.x86_64 ncurses-devel-6.2-8.20210508.fc35.x86_64 ncurses-c++-libs-6.2-8.20210508.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet libncurses-devel ncurses-devel rpm <libncurses-devel+ncurses-devel.info
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" --installed --setopt disable_excludes=* ncurses-devel-6.2-8.20210508.fc35.x86_64 <ncurses-devel.requires
+ LC_ALL=C dnf list --cacheonly --quiet ncurses-libs rpm <ncurses-libs.info
+ LC_ALL=C dnf list --cacheonly --quiet ncurses-c++-libs ncurses-devel rpm <ncurses-c++-libs+ncurses-devel.info
+ sudo dnf mark user --quiet --assumeno --cacheonly ncurses-libs-6.2-8.20210508.fc35.x86_64 ncurses-devel-6.2-8.20210508.fc35.x86_64 ncurses-c++-libs-6.2-8.20210508.fc35.x86_64
EOE
libncurses 6.2.0 (ncurses-libs 6.2-8.20210508.fc35) installed
libncurses-c++ 6.2.0 (ncurses-c++-libs 6.2-8.20210508.fc35) installed
@@ -1125,15 +1125,15 @@
dnf-list-fetched: ncurses-c++-libs ncurses-devel ncurses-c++-libs+ncurses-devel.info-fetched
dnf-list-installed: ncurses-libs ncurses-c++-libs ncurses-libs+ncurses-c++-libs.info-installed
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libncurses-devel ncurses-devel rpm <libncurses-devel+ncurses-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libncurses-devel ncurses-devel rpm <libncurses-devel+ncurses-devel.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet libncurses-devel ncurses-devel rpm <libncurses-devel+ncurses-devel.info
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" ncurses-devel-6.2-8.20210508.fc35.x86_64 <ncurses-devel.requires-fetched
- LC_ALL=C dnf list --all --cacheonly --quiet ncurses-libs rpm <ncurses-libs.info-fetched
- LC_ALL=C dnf list --all --cacheonly --quiet ncurses-c++-libs ncurses-devel rpm <ncurses-c++-libs+ncurses-devel.info-fetched
+ LC_ALL=C dnf list --cacheonly --quiet libncurses-devel ncurses-devel rpm <libncurses-devel+ncurses-devel.info
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" ncurses-devel-6.2-8.20210508.fc35.x86_64 <ncurses-devel.requires-fetched
+ LC_ALL=C dnf list --cacheonly --quiet ncurses-libs rpm <ncurses-libs.info-fetched
+ LC_ALL=C dnf list --cacheonly --quiet ncurses-c++-libs ncurses-devel rpm <ncurses-c++-libs+ncurses-devel.info-fetched
sudo dnf install --quiet --assumeno ncurses-libs-6.2-8.20210508.fc35.x86_64 ncurses-devel-6.2-8.20210508.fc35.x86_64 ncurses-c++-libs-6.2-8.20210508.fc35.x86_64
- sudo dnf mark --quiet --assumeno install --cacheonly ncurses-libs-6.2-8.20210508.fc35.x86_64 ncurses-devel-6.2-8.20210508.fc35.x86_64 ncurses-c++-libs-6.2-8.20210508.fc35.x86_64
- LC_ALL=C dnf list --all --cacheonly --quiet ncurses-libs ncurses-c++-libs rpm <ncurses-libs+ncurses-c++-libs.info-installed
+ sudo dnf mark user --quiet --assumeno --cacheonly ncurses-libs-6.2-8.20210508.fc35.x86_64 ncurses-devel-6.2-8.20210508.fc35.x86_64 ncurses-c++-libs-6.2-8.20210508.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet ncurses-libs ncurses-c++-libs rpm <ncurses-libs+ncurses-c++-libs.info-installed
EOE
libncurses 6.2.0 (ncurses-libs 6.2-8.20210508.fc35) part installed
libncurses-c++ 6.2.0 (ncurses-c++-libs 6.2-8.20210508.fc35) part installed
@@ -1209,15 +1209,15 @@
dnf-list-fetched: ncurses-c++-libs ncurses-devel ncurses-c++-libs+ncurses-devel.info-fetched
dnf-list-installed: ncurses-libs ncurses-c++-libs ncurses-libs+ncurses-c++-libs.info-installed
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libncurses-devel ncurses-devel rpm <libncurses-devel+ncurses-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libncurses-devel ncurses-devel rpm <libncurses-devel+ncurses-devel.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet libncurses-devel ncurses-devel rpm <libncurses-devel+ncurses-devel.info-fetched
- LC_ALL=C dnf repoquery --requires --quiet --cacheonly --resolve --qf "%{name} %{arch} %{epoch}:%{version}-%{release}" ncurses-devel-6.2-8.20210508.fc35.x86_64 <ncurses-devel.requires-fetched
- LC_ALL=C dnf list --all --cacheonly --quiet ncurses-libs rpm <ncurses-libs.info-fetched
- LC_ALL=C dnf list --all --cacheonly --quiet ncurses-c++-libs ncurses-devel rpm <ncurses-c++-libs+ncurses-devel.info-fetched
+ LC_ALL=C dnf list --cacheonly --quiet libncurses-devel ncurses-devel rpm <libncurses-devel+ncurses-devel.info-fetched
+ LC_ALL=C dnf repoquery --quiet --cacheonly --providers-of requires --queryformat "%{name} %{arch} %{epoch}:%{version}-%{release}\n" ncurses-devel-6.2-8.20210508.fc35.x86_64 <ncurses-devel.requires-fetched
+ LC_ALL=C dnf list --cacheonly --quiet ncurses-libs rpm <ncurses-libs.info-fetched
+ LC_ALL=C dnf list --cacheonly --quiet ncurses-c++-libs ncurses-devel rpm <ncurses-c++-libs+ncurses-devel.info-fetched
sudo dnf install --quiet --assumeno ncurses-libs-6.2-8.20210508.fc35.x86_64 ncurses-devel-6.2-8.20210508.fc35.x86_64 ncurses-c++-libs-6.2-8.20210508.fc35.x86_64
- sudo dnf mark --quiet --assumeno install --cacheonly ncurses-libs-6.2-8.20210508.fc35.x86_64 ncurses-devel-6.2-8.20210508.fc35.x86_64 ncurses-c++-libs-6.2-8.20210508.fc35.x86_64
- LC_ALL=C dnf list --all --cacheonly --quiet ncurses-libs ncurses-c++-libs rpm <ncurses-libs+ncurses-c++-libs.info-installed
+ sudo dnf mark user --quiet --assumeno --cacheonly ncurses-libs-6.2-8.20210508.fc35.x86_64 ncurses-devel-6.2-8.20210508.fc35.x86_64 ncurses-c++-libs-6.2-8.20210508.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet ncurses-libs ncurses-c++-libs rpm <ncurses-libs+ncurses-c++-libs.info-installed
EOE
libncurses 6.2.0 (ncurses-libs 6.2-8.20210508.fc35) not installed
libncurses-c++ 6.2.0 (ncurses-c++-libs 6.2-8.20210508.fc35) not installed
@@ -1267,9 +1267,9 @@
dnf-list: libsigc++30 libsigc++30-devel libsigc++30+libsigc++30-devel.info
dnf-list: libsigc++20 libsigc++20-devel libsigc++20+libsigc++20-devel.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
- sudo dnf mark --quiet --assumeno install --cacheonly libsigc++20-2.10.7-3.fc35.x86_64 libsigc++20-devel-2.10.7-3.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
+ sudo dnf mark user --quiet --assumeno --cacheonly libsigc++20-2.10.7-3.fc35.x86_64 libsigc++20-devel-2.10.7-3.fc35.x86_64
EOE
libsigc++ 2.10.7 (libsigc++20 2.10.7-3.fc35) installed
EOO
@@ -1313,14 +1313,14 @@
dnf-list: libsigc++20 libsigc++20-devel libsigc++20+libsigc++20-devel.info
dnf-list-installed: libsigc++20 libsigc++20.info-installed
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
sudo dnf install --quiet --assumeno libsigc++20-2.10.7-3.fc35.x86_64 libsigc++20-devel-2.10.7-3.fc35.x86_64
- sudo dnf mark --quiet --assumeno install --cacheonly libsigc++20-2.10.7-3.fc35.x86_64 libsigc++20-devel-2.10.7-3.fc35.x86_64
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++20 rpm <libsigc++20.info-installed
+ sudo dnf mark user --quiet --assumeno --cacheonly libsigc++20-2.10.7-3.fc35.x86_64 libsigc++20-devel-2.10.7-3.fc35.x86_64
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++20 rpm <libsigc++20.info-installed
EOE
libsigc++ 2.10.7 (libsigc++20 2.10.7-3.fc35) part installed
EOO
@@ -1355,11 +1355,11 @@
dnf-list: libsigc++30 libsigc++30-devel libsigc++30+libsigc++30-devel.info
dnf-list: libsigc++20 libsigc++20-devel libsigc++20+libsigc++20-devel.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
error: multiple available fedora packages for libsigc++
info: candidate: libsigc++30 3.0.7-2.fc35
info: candidate: libsigc++20 2.10.7-3.fc35
@@ -1396,11 +1396,11 @@
dnf-list: libsigc++30 libsigc++30-devel libsigc++30+libsigc++30-devel.info
dnf-list: libsigc++20 libsigc++20-devel libsigc++20+libsigc++20-devel.info
EOI
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
sudo dnf makecache --quiet --assumeno --refresh
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
- LC_ALL=C dnf list --all --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++30 libsigc++30-devel rpm <libsigc++30+libsigc++30-devel.info
+ LC_ALL=C dnf list --cacheonly --quiet libsigc++20 libsigc++20-devel rpm <libsigc++20+libsigc++20-devel.info
error: multiple partially installed fedora packages for libsigc++
info: candidate: libsigc++30 3.0.7-2.fc35, missing components: libsigc++30-devel
info: candidate: libsigc++20 2.10.7-3.fc35, missing components: libsigc++20-devel
diff --git a/buildfile b/buildfile
index da08ca9..09f1c20 100644
--- a/buildfile
+++ b/buildfile
@@ -1,7 +1,7 @@
# file : buildfile
# license : MIT; see accompanying LICENSE file
-./: {*/ -build/} \
+./: {*/ -build/ -doc/} \
doc{INSTALL NEWS README} legal{LICENSE AUTHORS LEGAL} \
manifest
diff --git a/doc/manual.cli b/doc/manual.cli
index 64275ce..e22cfd4 100644
--- a/doc/manual.cli
+++ b/doc/manual.cli
@@ -2576,7 +2576,11 @@ variables, and dependencies are passed to the \l{bpkg-pkg-build(1)} command at
the \c{bpkg.configure.build} step. The package-specific configuration
variables for this and/or the separate test packages are passed to
\l{bpkg-pkg-build(1)} at the \c{bpkg.configure.build} and
-\c{bpkg.test-separate-installed.configure.build} steps. For example:
+\c{bpkg.test-separate-installed.configure.build} steps. The dependencies of
+these packages can be configured at these steps in various configurations by
+specifying the package-specific \c{--config-uuid} option(s) and configuration
+variables or the \c{[?]sys:} prefix (see \l{bbot#arch-worker configuration
+UUIDs}). For example:
\
network-build-config: config.libfoo.network=true; Enable networking API.
@@ -2620,6 +2624,15 @@ load-tests-build-config:
;
Enable load testing.
\\
+
+default-build-config:
+\\
+# Configure libbar-tests package's dependency libfoo as system on the
+# bpkg.test-separate-installed.configure.build step, since it is
+# already installed as a dependency of libbar.
+#
+{ --config-uuid=00000000-0000-0000-0000-000000000005 }+ ?sys:libfoo/*
+\\
\
Note that options with values can only be specified using the single argument
diff --git a/repositories.manifest b/repositories.manifest
index 288344c..62acd9d 100644
--- a/repositories.manifest
+++ b/repositories.manifest
@@ -3,12 +3,5 @@ summary: build2 package dependency manager repository
:
role: prerequisite
-location: ../build2.git#HEAD
-
-:
-role: prerequisite
-location: ../libbutl.git#HEAD
-
-:
-role: prerequisite
-location: ../libbpkg.git#HEAD
+location: https://stage.build2.org/1
+trust: EC:50:13:E2:3D:F7:92:B4:50:0B:BF:2A:1F:7D:31:04:C6:57:6F:BC:BE:04:2E:E0:58:14:FA:66:66:21:1F:14