aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-08-03 21:10:49 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-08-03 21:10:49 +0100
commitd093ad94c0f353c9f267413fd7dfb4ed8a8a991f (patch)
treee2e4056ccb7b6f2a08c8a904f12ab0922e0ba8e5
parenta8081daa93c1d5b50e3489f99758a437b7b981ff (diff)
downloadpaludis-d093ad94c0f353c9f267413fd7dfb4ed8a8a991f.tar.gz
paludis-d093ad94c0f353c9f267413fd7dfb4ed8a8a991f.tar.xz
functionise qpn_s fetching
-rw-r--r--paludis/resolver/qpn_s-fwd.hh3
-rw-r--r--paludis/resolver/qpn_s.cc76
-rw-r--r--paludis/resolver/qpn_s.hh25
-rw-r--r--paludis/resolver/resolver.cc102
-rw-r--r--paludis/resolver/resolver.hh6
-rw-r--r--paludis/resolver/resolver_functions.hh13
-rw-r--r--paludis/resolver/sanitised_dependencies.cc2
-rw-r--r--src/clients/cave/cmd_resolve.cc123
8 files changed, 212 insertions, 138 deletions
diff --git a/paludis/resolver/qpn_s-fwd.hh b/paludis/resolver/qpn_s-fwd.hh
index 91e4d89..f89f645 100644
--- a/paludis/resolver/qpn_s-fwd.hh
+++ b/paludis/resolver/qpn_s-fwd.hh
@@ -21,6 +21,7 @@
#define PALUDIS_GUARD_PALUDIS_RESOLVER_QPN_S_FWD_HH 1
#include <paludis/util/attributes.hh>
+#include <paludis/util/sequence-fwd.hh>
#include <iosfwd>
namespace paludis
@@ -31,7 +32,7 @@ namespace paludis
std::ostream & operator<< (std::ostream & s, const QPN_S &) PALUDIS_VISIBLE;
- bool operator< (const QPN_S &, const QPN_S &) PALUDIS_VISIBLE;
+ typedef Sequence<QPN_S> QPN_S_Sequence;
}
}
diff --git a/paludis/resolver/qpn_s.cc b/paludis/resolver/qpn_s.cc
index ed3698d..2bb5820 100644
--- a/paludis/resolver/qpn_s.cc
+++ b/paludis/resolver/qpn_s.cc
@@ -18,31 +18,90 @@
*/
#include <paludis/resolver/qpn_s.hh>
+#include <paludis/util/sequence-impl.hh>
+#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/filter.hh>
+#include <paludis/dep_spec.hh>
+#include <paludis/package_id.hh>
+#include <paludis/metadata_key.hh>
#include <sstream>
using namespace paludis;
using namespace paludis::resolver;
+namespace paludis
+{
+ template <>
+ struct Implementation<QPN_S>
+ {
+ const QualifiedPackageName package;
+ const std::tr1::shared_ptr<const SlotName> slot_name_or_null;
+
+ Implementation(const QualifiedPackageName & q, const std::tr1::shared_ptr<const SlotName> & s) :
+ package(q),
+ slot_name_or_null(s)
+ {
+ }
+ };
+}
+
+QPN_S::QPN_S(const QualifiedPackageName & q, const std::tr1::shared_ptr<const SlotName> & s) :
+ PrivateImplementationPattern<QPN_S>(new Implementation<QPN_S>(q, s))
+{
+}
+
+QPN_S::QPN_S(const PackageDepSpec & p, const std::tr1::shared_ptr<const SlotName> & s) :
+ PrivateImplementationPattern<QPN_S>(new Implementation<QPN_S>(*p.package_ptr(), s))
+{
+}
+
+QPN_S::QPN_S(const std::tr1::shared_ptr<const PackageID> & id) :
+ PrivateImplementationPattern<QPN_S>(new Implementation<QPN_S>(id->name(),
+ id->slot_key() ? make_shared_ptr(new SlotName(id->slot_key()->value())) : make_null_shared_ptr()))
+{
+}
+
+QPN_S::QPN_S(const QPN_S & other) :
+ PrivateImplementationPattern<QPN_S>(new Implementation<QPN_S>(other.package(), other.slot_name_or_null()))
+{
+}
+
+QPN_S::~QPN_S()
+{
+}
+
+const QualifiedPackageName
+QPN_S::package() const
+{
+ return _imp->package;
+}
+
+const std::tr1::shared_ptr<const SlotName>
+QPN_S::slot_name_or_null() const
+{
+ return _imp->slot_name_or_null;
+}
+
bool
-paludis::resolver::operator< (const QPN_S & lhs, const QPN_S & rhs)
+QPN_S::operator< (const QPN_S & other) const
{
- if (lhs.package() < rhs.package())
+ if (package() < other.package())
return true;
- if (lhs.package() > rhs.package())
+ if (package() > other.package())
return false;
/* no slot orders before any slot */
- if (lhs.slot_name_or_null())
+ if (slot_name_or_null())
{
- if (rhs.slot_name_or_null())
- return *lhs.slot_name_or_null() < *rhs.slot_name_or_null();
+ if (other.slot_name_or_null())
+ return *slot_name_or_null() < *other.slot_name_or_null();
else
return false;
}
else
{
- if (rhs.slot_name_or_null())
+ if (other.slot_name_or_null())
return true;
else
return false;
@@ -72,3 +131,6 @@ QPN_S::make_slot_filter() const
return filter::NoSlot();
}
+template class PrivateImplementationPattern<QPN_S>;
+template class WrappedForwardIterator<QPN_S_Sequence::ConstIteratorTag, const QPN_S>;
+
diff --git a/paludis/resolver/qpn_s.hh b/paludis/resolver/qpn_s.hh
index 44c82d6..cf7a21a 100644
--- a/paludis/resolver/qpn_s.hh
+++ b/paludis/resolver/qpn_s.hh
@@ -23,8 +23,11 @@
#include <paludis/resolver/qpn_s-fwd.hh>
#include <paludis/util/named_value.hh>
#include <paludis/util/attributes.hh>
+#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/name.hh>
#include <paludis/filter-fwd.hh>
+#include <paludis/dep_spec-fwd.hh>
+#include <paludis/package_id-fwd.hh>
#include <tr1/memory>
namespace paludis
@@ -37,16 +40,28 @@ namespace paludis
namespace resolver
{
- struct PALUDIS_VISIBLE QPN_S
+ class PALUDIS_VISIBLE QPN_S :
+ private PrivateImplementationPattern<QPN_S>
{
- NamedValue<n::package, QualifiedPackageName> package;
- NamedValue<n::slot_name_or_null, std::tr1::shared_ptr<const SlotName> > slot_name_or_null;
+ public:
+ QPN_S(const QualifiedPackageName &, const std::tr1::shared_ptr<const SlotName> &);
+ QPN_S(const PackageDepSpec &, const std::tr1::shared_ptr<const SlotName> &);
+ QPN_S(const std::tr1::shared_ptr<const PackageID> &);
+ QPN_S(const QPN_S &);
+ ~QPN_S();
- Filter make_slot_filter() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const QualifiedPackageName package() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<const SlotName> slot_name_or_null() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
+ Filter make_slot_filter() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ bool operator< (const QPN_S & other) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
}
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class PrivateImplementationPattern<resolver::QPN_S>;
+#endif
}
#endif
diff --git a/paludis/resolver/resolver.cc b/paludis/resolver/resolver.cc
index be37016..9bab45a 100644
--- a/paludis/resolver/resolver.cc
+++ b/paludis/resolver/resolver.cc
@@ -258,12 +258,11 @@ Resolver::add_target_with_reason(const PackageDepSpec & spec, const std::tr1::sh
Context context("When adding target '" + stringify(spec) + "' with reason '" + stringify(*reason) + "':");
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStepEvent());
- std::list<QPN_S> qpn_s_s;
- _find_qpn_s_s_for_spec(spec, std::back_inserter(qpn_s_s));
- if (qpn_s_s.empty())
+ const std::tr1::shared_ptr<const QPN_S_Sequence> qpn_s_s(_imp->fns.get_qpn_s_s_for_fn()(spec, reason));
+ if (qpn_s_s->empty())
throw InternalError(PALUDIS_HERE, "not implemented: no slot for " + stringify(spec));
- for (std::list<QPN_S>::const_iterator qpn_s(qpn_s_s.begin()), qpn_s_end(qpn_s_s.end()) ;
+ for (QPN_S_Sequence::ConstIterator qpn_s(qpn_s_s->begin()), qpn_s_end(qpn_s_s->end()) ;
qpn_s != qpn_s_end ; ++qpn_s)
{
Context context_2("When adding constraints from target '" + stringify(spec) + "' to qpn:s '"
@@ -301,65 +300,6 @@ Resolver::add_target(const SetName & set_name)
add_target_with_reason(**s, reason);
}
-namespace
-{
- struct SlotNameFinder
- {
- std::tr1::shared_ptr<SlotName> visit(const SlotExactRequirement & s)
- {
- return make_shared_ptr(new SlotName(s.slot()));
- }
-
- std::tr1::shared_ptr<SlotName> visit(const SlotAnyUnlockedRequirement &)
- {
- return make_null_shared_ptr();
- }
-
- std::tr1::shared_ptr<SlotName> visit(const SlotAnyLockedRequirement &)
- {
- return make_null_shared_ptr();
- }
- };
-}
-
-template <typename I_>
-void
-Resolver::_find_qpn_s_s_for_spec(const PackageDepSpec & spec, I_ iter) const
-{
- std::tr1::shared_ptr<SlotName> exact_slot;
-
- if (spec.slot_requirement_ptr())
- {
- SlotNameFinder f;
- exact_slot = spec.slot_requirement_ptr()->accept_returning<std::tr1::shared_ptr<SlotName> >(f);
- }
-
- if (exact_slot)
- *iter++ = make_named_values<QPN_S>(
- value_for<n::package>(_package_from_spec(spec)),
- value_for<n::slot_name_or_null>(exact_slot)
- );
- else
- {
- const std::tr1::shared_ptr<const PackageIDSequence> ids((*_imp->env)[selection::BestVersionOnly(
- generator::Matches(spec, MatchPackageOptions() + mpo_ignore_additional_requirements) |
- filter::SupportsAction<InstallAction>() |
- filter::NotMasked())]);
-
- if (! ids->empty())
- *iter++ = qpn_s_from_id(*ids->begin());
- else
- {
- const std::tr1::shared_ptr<const PackageIDSequence> installed_ids((*_imp->env)[selection::BestVersionOnly(
- generator::Matches(spec, MatchPackageOptions() + mpo_ignore_additional_requirements) |
- filter::SupportsAction<InstalledAction>())]);
-
- if (! installed_ids->empty())
- *iter++ = qpn_s_from_id(*installed_ids->begin());
- }
- }
-}
-
QualifiedPackageName
Resolver::_package_from_spec(const PackageDepSpec & spec) const
{
@@ -407,15 +347,6 @@ Resolver::_resolution_for_qpn_s(const QPN_S & qpn_s) const
return i->second;
}
-QPN_S
-Resolver::qpn_s_from_id(const std::tr1::shared_ptr<const PackageID> & id) const
-{
- return make_named_values<QPN_S>(
- value_for<n::package>(id->name()),
- value_for<n::slot_name_or_null>(id->slot_key() ? make_shared_ptr(new SlotName(id->slot_key()->value())) : make_null_shared_ptr())
- );
-}
-
const std::tr1::shared_ptr<Constraint>
Resolver::_make_constraint_from_target(
const QPN_S & qpn_s,
@@ -432,10 +363,9 @@ Resolver::_make_constraint_from_target(
}
const std::tr1::shared_ptr<Constraint>
-Resolver::_make_constraint_from_dependency(const QPN_S & qpn_s, const SanitisedDependency & dep) const
+Resolver::_make_constraint_from_dependency(const QPN_S & qpn_s, const SanitisedDependency & dep,
+ const std::tr1::shared_ptr<const Reason> & reason) const
{
- const std::tr1::shared_ptr<DependencyReason> reason(new DependencyReason(qpn_s, dep));
-
return make_shared_ptr(new Constraint(make_named_values<Constraint>(
value_for<n::desire_strength>(_desire_strength_from_sanitised_dependency(qpn_s, dep)),
value_for<n::reason>(reason),
@@ -603,13 +533,13 @@ Resolver::_add_dependencies(const QPN_S & our_qpn_s, const std::tr1::shared_ptr<
{
Context context_2("When handling dependency '" + stringify(*s) + "':");
- std::list<QPN_S> qpn_s_s;
-
if (! _care_about_dependency_spec(our_qpn_s, our_resolution, *s))
continue;
- _find_qpn_s_s_for_spec(s->spec(), std::back_inserter(qpn_s_s));
- if (qpn_s_s.empty())
+ const std::tr1::shared_ptr<DependencyReason> reason(new DependencyReason(our_qpn_s, *s));
+
+ const std::tr1::shared_ptr<const QPN_S_Sequence> qpn_s_s(_imp->fns.get_qpn_s_s_for_fn()(s->spec(), reason));
+ if (qpn_s_s->empty())
{
if (our_resolution->decision()->is_installed())
Log::get_instance()->message("resolver.cannot_find_installed_dep", ll_warning, lc_context)
@@ -618,11 +548,11 @@ Resolver::_add_dependencies(const QPN_S & our_qpn_s, const std::tr1::shared_ptr<
throw InternalError(PALUDIS_HERE, "not implemented: no slot for " + stringify(s->spec()));
}
- for (std::list<QPN_S>::const_iterator qpn_s(qpn_s_s.begin()), qpn_s_end(qpn_s_s.end()) ;
+ for (QPN_S_Sequence::ConstIterator qpn_s(qpn_s_s->begin()), qpn_s_end(qpn_s_s->end()) ;
qpn_s != qpn_s_end ; ++qpn_s)
{
const std::tr1::shared_ptr<Resolution> dep_resolution(_resolution_for_qpn_s(*qpn_s, true));
- const std::tr1::shared_ptr<Constraint> constraint(_make_constraint_from_dependency(our_qpn_s, *s));
+ const std::tr1::shared_ptr<Constraint> constraint(_make_constraint_from_dependency(our_qpn_s, *s, reason));
_apply_resolution_constraint(*qpn_s, dep_resolution, constraint);
}
@@ -1117,12 +1047,12 @@ Resolver::find_any_score(const QPN_S & our_qpn_s, const SanitisedDependency & de
return 40 + operator_bias;
}
- std::list<QPN_S> qpn_s_s;
- _find_qpn_s_s_for_spec(dep.spec(), std::back_inserter(qpn_s_s));
+ const std::tr1::shared_ptr<DependencyReason> reason(new DependencyReason(our_qpn_s, dep));
+ const std::tr1::shared_ptr<const QPN_S_Sequence> qpn_s_s(_imp->fns.get_qpn_s_s_for_fn()(dep.spec(), reason));
/* next: will already be installing */
{
- for (std::list<QPN_S>::const_iterator qpn_s(qpn_s_s.begin()), qpn_s_end(qpn_s_s.end()) ;
+ for (QPN_S_Sequence::ConstIterator qpn_s(qpn_s_s->begin()), qpn_s_end(qpn_s_s->end()) ;
qpn_s != qpn_s_end ; ++qpn_s)
{
ResolutionsByQPN_SMap::const_iterator i(_imp->resolutions_by_qpn_s.find(*qpn_s));
@@ -1133,11 +1063,11 @@ Resolver::find_any_score(const QPN_S & our_qpn_s, const SanitisedDependency & de
/* next: could install */
{
- for (std::list<QPN_S>::const_iterator qpn_s(qpn_s_s.begin()), qpn_s_end(qpn_s_s.end()) ;
+ for (QPN_S_Sequence::ConstIterator qpn_s(qpn_s_s->begin()), qpn_s_end(qpn_s_s->end()) ;
qpn_s != qpn_s_end ; ++qpn_s)
{
const std::tr1::shared_ptr<Resolution> resolution(_create_resolution_for_qpn_s(*qpn_s));
- const std::tr1::shared_ptr<Constraint> constraint(_make_constraint_from_dependency(our_qpn_s, dep));
+ const std::tr1::shared_ptr<Constraint> constraint(_make_constraint_from_dependency(our_qpn_s, dep, reason));
resolution->constraints()->add(constraint);
const std::tr1::shared_ptr<Decision> decision(_try_to_find_decision_for(*qpn_s, resolution));
if (decision)
diff --git a/paludis/resolver/resolver.hh b/paludis/resolver/resolver.hh
index 0a43654..b73e3cb 100644
--- a/paludis/resolver/resolver.hh
+++ b/paludis/resolver/resolver.hh
@@ -48,8 +48,6 @@ namespace paludis
private PrivateImplementationPattern<Resolver>
{
private:
- template <typename I_> void _find_qpn_s_s_for_spec(const PackageDepSpec &, I_) const;
-
QualifiedPackageName _package_from_spec(const PackageDepSpec &) const;
const std::tr1::shared_ptr<Resolution> _create_resolution_for_qpn_s(const QPN_S &) const;
@@ -62,7 +60,8 @@ namespace paludis
const std::tr1::shared_ptr<const Reason> &) const;
const std::tr1::shared_ptr<Constraint> _make_constraint_from_dependency(
- const QPN_S &, const SanitisedDependency &) const;
+ const QPN_S &, const SanitisedDependency &,
+ const std::tr1::shared_ptr<const Reason> &) const;
const std::tr1::shared_ptr<Decision> _decision_from_package_id(
const QPN_S &, const std::tr1::shared_ptr<const PackageID> &) const;
@@ -169,7 +168,6 @@ namespace paludis
ConstIterator end() const PALUDIS_ATTRIBUTE((warn_unused_result));
int find_any_score(const QPN_S &, const SanitisedDependency &) const;
- QPN_S qpn_s_from_id(const std::tr1::shared_ptr<const PackageID> &) const;
};
}
diff --git a/paludis/resolver/resolver_functions.hh b/paludis/resolver/resolver_functions.hh
index ac3b604..45a6ecc 100644
--- a/paludis/resolver/resolver_functions.hh
+++ b/paludis/resolver/resolver_functions.hh
@@ -33,22 +33,31 @@ namespace paludis
namespace n
{
struct get_initial_constraints_for_fn;
+ struct get_qpn_s_s_for_fn;
struct get_use_installed_fn;
}
namespace resolver
{
typedef std::tr1::function<std::tr1::shared_ptr<Constraints> (
- const QPN_S &)> GetInitialConstraintsFunction;
+ const QPN_S &
+ )> GetInitialConstraintsFunction;
+
+ typedef std::tr1::function<std::tr1::shared_ptr<QPN_S_Sequence> (
+ const PackageDepSpec &,
+ const std::tr1::shared_ptr<const Reason> &
+ )> GetQPNSSForFunction;
typedef std::tr1::function<UseInstalled (
const QPN_S &,
const PackageDepSpec &,
- const std::tr1::shared_ptr<const Reason> &)> GetUseInstalledFunction;
+ const std::tr1::shared_ptr<const Reason> &
+ )> GetUseInstalledFunction;
struct ResolverFunctions
{
NamedValue<n::get_initial_constraints_for_fn, GetInitialConstraintsFunction> get_initial_constraints_for_fn;
+ NamedValue<n::get_qpn_s_s_for_fn, GetQPNSSForFunction> get_qpn_s_s_for_fn;
NamedValue<n::get_use_installed_fn, GetUseInstalledFunction> get_use_installed_fn;
};
}
diff --git a/paludis/resolver/sanitised_dependencies.cc b/paludis/resolver/sanitised_dependencies.cc
index 5735d01..cda5e1a 100644
--- a/paludis/resolver/sanitised_dependencies.cc
+++ b/paludis/resolver/sanitised_dependencies.cc
@@ -473,7 +473,7 @@ SanitisedDependencies::_populate_one(
{
Context context("When finding dependencies for '" + stringify(*id) + "' from key '" + ((*id).*pmf)()->raw_name() + "':");
- Finder f(resolver, resolver.qpn_s_from_id(id), *this, ((*id).*pmf)()->initial_labels());
+ Finder f(resolver, QPN_S(id), *this, ((*id).*pmf)()->initial_labels());
((*id).*pmf)()->value()->root()->accept(f);
}
diff --git a/src/clients/cave/cmd_resolve.cc b/src/clients/cave/cmd_resolve.cc
index b38835e..794f3a3 100644
--- a/src/clients/cave/cmd_resolve.cc
+++ b/src/clients/cave/cmd_resolve.cc
@@ -120,9 +120,9 @@ namespace
args::EnumArg a_reinstall_scm;
// args::SwitchArg a_reinstall_for_removals;
-// args::ArgsGroup g_slot_options;
-// args::EnumArg a_target_slots;
-// args::EnumArg a_slots;
+ args::ArgsGroup g_slot_options;
+ args::EnumArg a_target_slots;
+ args::EnumArg a_slots;
// args::ArgsGroup g_dependency_options;
// args::SwitchArg a_follow_installed_build_dependencies;
@@ -264,7 +264,7 @@ namespace
("if-necessary", 'i', "If necessary"),
"if-necessary"
),
- a_reinstall_scm(&g_reinstall_options, "reinstall-scm", 's',
+ a_reinstall_scm(&g_reinstall_options, "reinstall-scm", '\0',
"Select whether to reinstall SCM packages that would otherwise not be reinstalled",
args::EnumArg::EnumArgOptions
("always", 'a', "Always")
@@ -276,34 +276,34 @@ namespace
// a_reinstall_for_removals(&g_reinstall_options, "reinstall-for-removals", '\0',
// "Select whether to rebuild packages if rebuilding would avoid an unsafe removal", true),
//
-// g_slot_options(this, "Slot Options", "Control which slots are considered."),
-// a_target_slots(&g_slot_options, "target-slots", 'S',
-// "Which slots to consider for targets",
-// args::EnumArg::EnumArgOptions
-// ("best-or-installed", 'x', "Consider the best slot, if it is not installed, "
-// "or all installed slots otherwise")
-// ("installed-or-best", 'i', "Consider all installed slots, or the best "
-// "installable slot if nothing is installed")
-// ("all", 'a', "Consider all installed slots and the best installable slot"
-// " (default if --complete or --everything)")
-// ("best", 'b', "Consider the best installable slot only"
-// " (default if --lazy)"),
-// "best-or-installed"
-// ),
-// a_slots(&g_slot_options, "slots", 's',
-// "Which slots to consider for packages that are not targets",
-// args::EnumArg::EnumArgOptions
-// ("best-or-installed", 'x', "Consider the best slot, if it is not installed, "
-// "or all installed slots otherwise")
-// ("installed-or-best", 'i', "Consider all installed slots, or the best "
-// "installable slot if nothing is installed")
-// ("all", 'a', "Consider all installed slots and the best installable slot"
-// " (default if --complete or --everything)")
-// ("best", 'b', "Consider the best installable slot only"
-// " (default if --lazy)"),
-// "best-or-installed"
-// ),
-//
+ g_slot_options(this, "Slot Options", "Control which slots are considered."),
+ a_target_slots(&g_slot_options, "target-slots", 'S',
+ "Which slots to consider for targets",
+ args::EnumArg::EnumArgOptions
+ ("best-or-installed", 'x', "Consider the best slot, if it is not installed, "
+ "or all installed slots otherwise")
+ ("installed-or-best", 'i', "Consider all installed slots, or the best "
+ "installable slot if nothing is installed")
+ ("all", 'a', "Consider all installed slots and the best installable slot"
+ " (default if --complete or --everything)")
+ ("best", 'b', "Consider the best installable slot only"
+ " (default if --lazy)"),
+ "best-or-installed"
+ ),
+ a_slots(&g_slot_options, "slots", 's',
+ "Which slots to consider for packages that are not targets",
+ args::EnumArg::EnumArgOptions
+ ("best-or-installed", 'x', "Consider the best slot, if it is not installed, "
+ "or all installed slots otherwise")
+ ("installed-or-best", 'i', "Consider all installed slots, or the best "
+ "installable slot if nothing is installed")
+ ("all", 'a', "Consider all installed slots and the best installable slot"
+ " (default if --complete or --everything)")
+ ("best", 'b', "Consider the best installable slot only"
+ " (default if --lazy)"),
+ "best-or-installed"
+ ),
+
// g_dependency_options(this, "Dependency Options", "Control which dependencies are followed."),
// a_follow_installed_build_dependencies(&g_dependency_options, "follow-installed-build-dependencies", 'D',
// "Follow build dependencies for installed packages (default if --complete or --everything", true),
@@ -659,6 +659,63 @@ namespace
else
return i->second;
}
+
+ struct SlotNameFinder
+ {
+ std::tr1::shared_ptr<SlotName> visit(const SlotExactRequirement & s)
+ {
+ return make_shared_ptr(new SlotName(s.slot()));
+ }
+
+ std::tr1::shared_ptr<SlotName> visit(const SlotAnyUnlockedRequirement &)
+ {
+ return make_null_shared_ptr();
+ }
+
+ std::tr1::shared_ptr<SlotName> visit(const SlotAnyLockedRequirement &)
+ {
+ return make_null_shared_ptr();
+ }
+ };
+
+ const std::tr1::shared_ptr<QPN_S_Sequence>
+ get_qpn_s_s_for_fn(const Environment * const env, const ResolveCommandLine &, const PackageDepSpec & spec,
+ const std::tr1::shared_ptr<const Reason> &)
+ {
+ std::tr1::shared_ptr<QPN_S_Sequence> result(new QPN_S_Sequence);
+
+ std::tr1::shared_ptr<SlotName> exact_slot;
+
+ if (spec.slot_requirement_ptr())
+ {
+ SlotNameFinder f;
+ exact_slot = spec.slot_requirement_ptr()->accept_returning<std::tr1::shared_ptr<SlotName> >(f);
+ }
+
+ if (exact_slot)
+ result->push_back(QPN_S(spec, exact_slot));
+ else
+ {
+ const std::tr1::shared_ptr<const PackageIDSequence> ids((*env)[selection::BestVersionOnly(
+ generator::Matches(spec, MatchPackageOptions() + mpo_ignore_additional_requirements) |
+ filter::SupportsAction<InstallAction>() |
+ filter::NotMasked())]);
+
+ if (! ids->empty())
+ result->push_back(QPN_S(*ids->begin()));
+ else
+ {
+ const std::tr1::shared_ptr<const PackageIDSequence> installed_ids((*env)[selection::BestVersionOnly(
+ generator::Matches(spec, MatchPackageOptions() + mpo_ignore_additional_requirements) |
+ filter::SupportsAction<InstalledAction>())]);
+
+ if (! installed_ids->empty())
+ result->push_back(QPN_S(*installed_ids->begin()));
+ }
+ }
+
+ return result;
+ }
}
@@ -690,6 +747,8 @@ ResolveCommand::run(
ResolverFunctions resolver_functions(make_named_values<ResolverFunctions>(
value_for<n::get_initial_constraints_for_fn>(std::tr1::bind(&initial_constraints_for_fn,
env.get(), std::tr1::cref(cmdline), std::tr1::cref(initial_constraints), std::tr1::placeholders::_1)),
+ value_for<n::get_qpn_s_s_for_fn>(std::tr1::bind(&get_qpn_s_s_for_fn,
+ env.get(), std::tr1::cref(cmdline), std::tr1::placeholders::_1, std::tr1::placeholders::_2)),
value_for<n::get_use_installed_fn>(std::tr1::bind(&use_installed_fn,
std::tr1::cref(cmdline), std::tr1::placeholders::_1, std::tr1::placeholders::_2, std::tr1::placeholders::_3))
));