aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-05-27 19:02:13 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-05-27 19:02:13 +0000
commit8f84d3cdf5bb93004381a486f14283ed024e2d6d (patch)
treedbd9335ebd456c49afbf1d3b6539224f7596abf5
parentedeadc682990f7b755077f8dcef769059ca50e59 (diff)
downloadpaludis-8f84d3cdf5bb93004381a486f14283ed024e2d6d.tar.gz
paludis-8f84d3cdf5bb93004381a486f14283ed024e2d6d.tar.xz
Split out some of DepList.
-rw-r--r--paludis/dep_list/Makefile.am19
-rw-r--r--paludis/dep_list/dep_list.cc228
-rw-r--r--paludis/dep_list/dep_list.hh28
-rw-r--r--paludis/dep_list/query_visitor.cc164
-rw-r--r--paludis/dep_list/query_visitor.hh61
5 files changed, 305 insertions, 195 deletions
diff --git a/paludis/dep_list/Makefile.am b/paludis/dep_list/Makefile.am
index ce57f17..39187b6 100644
--- a/paludis/dep_list/Makefile.am
+++ b/paludis/dep_list/Makefile.am
@@ -16,10 +16,12 @@ DEFS= \
paludis_dep_list_includedir = $(includedir)/paludis/dep_list
paludis_dep_list_include_HEADERS = \
dep_list.hh \
+ query_visitor.hh \
uninstall_list.hh \
exceptions.hh \
options.hh \
dep_list-sr.hh \
+ dep_list-fwd.hh \
uninstall_list-sr.hh \
range_rewriter.hh \
options-se.hh
@@ -27,30 +29,19 @@ paludis_dep_list_include_HEADERS = \
libpaludisdeplist_la_SOURCES = \
options.cc options.hh \
exceptions.cc exceptions.hh \
- dep_list.cc dep_list.hh \
+ dep_list.cc dep_list.hh dep_list-fwd.hh \
uninstall_list.cc uninstall_list.hh \
- range_rewriter.cc range_rewriter.hh
+ range_rewriter.cc range_rewriter.hh \
+ query_visitor.cc query_visitor.hh
libpaludisdeplist_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
-if ! MONOLITHIC
-
libpaludisdeplist_la_LIBADD = \
$(top_builddir)/paludis/util/libpaludisutil.la \
$(top_builddir)/paludis/libpaludis.la
-endif
-
-if MONOLITHIC
-
-noinst_LTLIBRARIES = libpaludisdeplist.la
-
-else
-
lib_LTLIBRARIES = libpaludisdeplist.la
-endif
-
EXTRA_DIST = \
dep_list_TEST.cc \
dep_list_TEST.hh \
diff --git a/paludis/dep_list/dep_list.cc b/paludis/dep_list/dep_list.cc
index f452f70..5043b94 100644
--- a/paludis/dep_list/dep_list.cc
+++ b/paludis/dep_list/dep_list.cc
@@ -23,6 +23,7 @@
#include <paludis/dep_list/dep_list.hh>
#include <paludis/dep_list/exceptions.hh>
#include <paludis/dep_list/range_rewriter.hh>
+#include <paludis/dep_list/query_visitor.hh>
#include <paludis/match_package.hh>
#include <paludis/query.hh>
#include <paludis/hashed_containers.hh>
@@ -34,6 +35,7 @@
#include <paludis/util/stringify.hh>
#include <paludis/util/tokeniser.hh>
#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/make_shared_ptr.hh>
#include <paludis/util/tr1_functional.hh>
#include <algorithm>
@@ -275,16 +277,6 @@ namespace
}
};
- bool is_viable_any_child(const Environment & env, const PackageDatabaseEntry * const pde,
- const DependencySpecTree::ConstItem & i)
- {
- const UseDepSpec * const u(get_const_item(i)->as_use_dep_spec());
- if (0 != u)
- return (pde ? env.query_use(u->flag(), *pde) : false) ^ u->inverse();
- else
- return true;
- }
-
bool is_interesting_any_child(const Environment & env,
const DependencySpecTree::ConstItem & i)
{
@@ -300,164 +292,6 @@ namespace
}
}
-struct DepList::QueryVisitor :
- ConstVisitor<DependencySpecTree>
-{
- bool result;
- const DepList * const d;
- tr1::shared_ptr<const DestinationsCollection> destinations;
-
- QueryVisitor(const DepList * const dd, tr1::shared_ptr<const DestinationsCollection> ddd) :
- result(true),
- d(dd),
- destinations(ddd)
- {
- }
-
- void visit_sequence(const AllDepSpec &,
- DependencySpecTree::ConstSequenceIterator,
- DependencySpecTree::ConstSequenceIterator);
-
- void visit_sequence(const AnyDepSpec &,
- DependencySpecTree::ConstSequenceIterator,
- DependencySpecTree::ConstSequenceIterator);
-
- void visit_sequence(const UseDepSpec &,
- DependencySpecTree::ConstSequenceIterator,
- DependencySpecTree::ConstSequenceIterator);
-
- void visit_leaf(const PackageDepSpec &);
-
- void visit_leaf(const BlockDepSpec &);
-};
-
-void
-DepList::QueryVisitor::visit_leaf(const PackageDepSpec & a)
-{
- /* a pda matches if we'll be installed by the time we reach the current point. This
- * means that merely being installed is not enough, if we'll have our version changed
- * by something in the merge list. */
-
- result = false;
-
- // TODO: check destinations
- tr1::shared_ptr<const PackageDatabaseEntryCollection> matches(d->_imp->env->package_database()->query(
- a, is_installed_only, qo_whatever));
-
- for (PackageDatabaseEntryCollection::Iterator m(matches->begin()), m_end(matches->end()) ;
- m != m_end ; ++m)
- {
- /* check that we haven't been replaced by something in the same slot */
- tr1::shared_ptr<const VersionMetadata> vm(d->_imp->env->package_database()->fetch_repository(m->repository)->
- version_metadata(m->name, m->version));
- SlotName slot(vm->slot);
-
- std::pair<MergeListIndex::const_iterator, MergeListIndex::const_iterator> p(
- d->_imp->merge_list_index.equal_range(m->name));
-
- bool replaced(false);
- PackageDepSpec spec(tr1::shared_ptr<QualifiedPackageName>(new QualifiedPackageName(m->name)));
- while (p.second != ((p.first = std::find_if(p.first, p.second,
- MatchDepListEntryAgainstPackageDepSpec(d->_imp->env, spec)))))
- {
- if (p.first->second->metadata->slot != slot)
- p.first = next(p.first);
- else
- {
- replaced = true;
- break;
- }
- }
-
- if (! replaced)
- {
- result = true;
- return;
- }
- }
-
- /* check the merge list for any new packages that match */
- std::pair<MergeListIndex::const_iterator, MergeListIndex::const_iterator> p;
- if (a.package_ptr())
- p = d->_imp->merge_list_index.equal_range(*a.package_ptr());
- else
- p = std::make_pair(d->_imp->merge_list_index.begin(), d->_imp->merge_list_index.end());
-
- if (p.second != std::find_if(p.first, p.second,
- MatchDepListEntryAgainstPackageDepSpec(d->_imp->env, a)))
- {
- // TODO: check destination
- result = true;
- return;
- }
-}
-
-void
-DepList::QueryVisitor::visit_sequence(const UseDepSpec & a,
- DependencySpecTree::ConstSequenceIterator cur,
- DependencySpecTree::ConstSequenceIterator end)
-{
- /* for use? ( ) dep specs, return true if we're not enabled, so that
- * weird || ( ) cases work. */
- if ((d->_imp->current_pde() ? d->_imp->env->query_use(a.flag(), *d->_imp->current_pde()) : false) ^ a.inverse())
- {
- result = true;
- for ( ; cur != end ; ++cur)
- {
- cur->accept(*this);
- if (! result)
- return;
- }
- }
- else
- result = true;
-}
-
-void
-DepList::QueryVisitor::visit_sequence(const AnyDepSpec &,
- DependencySpecTree::ConstSequenceIterator cur,
- DependencySpecTree::ConstSequenceIterator end)
-{
- /* empty || ( ) must resolve to true */
- result = true;
-
- RangeRewriter r;
- std::for_each(cur, end, accept_visitor(r));
-
- if (r.spec())
- visit_leaf(*r.spec());
- else
- for ( ; cur != end ; ++cur)
- {
- if (! is_viable_any_child(*d->_imp->env, d->_imp->current_pde(), *cur))
- continue;
-
- cur->accept(*this);
- if (result)
- return;
- }
-}
-
-void
-DepList::QueryVisitor::visit_leaf(const BlockDepSpec & a)
-{
- visit_leaf(*a.blocked_spec());
- result = !result;
-}
-
-void
-DepList::QueryVisitor::visit_sequence(const AllDepSpec &,
- DependencySpecTree::ConstSequenceIterator cur,
- DependencySpecTree::ConstSequenceIterator end)
-{
- for ( ; cur != end ; ++cur)
- {
- cur->accept(*this);
- if (! result)
- return;
- }
-}
-
struct DepList::AddVisitor :
ConstVisitor<DependencySpecTree>,
ConstVisitor<DependencySpecTree>::VisitConstSequence<AddVisitor, AllDepSpec>
@@ -1144,6 +978,12 @@ DepList::options()
return _imp->opts;
}
+const tr1::shared_ptr<const DepListOptions>
+DepList::options() const
+{
+ return _imp->opts;
+}
+
void
DepList::clear()
{
@@ -1652,9 +1492,9 @@ bool
DepList::already_installed(const DependencySpecTree::ConstItem & spec,
tr1::shared_ptr<const DestinationsCollection> destinations) const
{
- QueryVisitor visitor(this, destinations);
+ QueryVisitor visitor(this, destinations, _imp->env, _imp->current_pde());
spec.accept(visitor);
- return visitor.result;
+ return visitor.result();
}
DepList::Iterator
@@ -1726,6 +1566,43 @@ DepList::find_destination(const PackageDatabaseEntry & p,
throw NoDestinationError(p, dd);
}
+bool
+DepList::replaced(const PackageDatabaseEntry & m) const
+{
+ tr1::shared_ptr<const VersionMetadata> vm(
+ _imp->env->package_database()->fetch_repository(
+ m.repository)->version_metadata(m.name, m.version));
+ SlotName slot(vm->slot);
+
+ std::pair<MergeListIndex::const_iterator, MergeListIndex::const_iterator> p(
+ _imp->merge_list_index.equal_range(m.name));
+
+ PackageDepSpec spec(tr1::shared_ptr<QualifiedPackageName>(new QualifiedPackageName(m.name)));
+ while (p.second != ((p.first = std::find_if(p.first, p.second,
+ MatchDepListEntryAgainstPackageDepSpec(_imp->env, spec)))))
+ {
+ if (p.first->second->metadata->slot != slot)
+ p.first = next(p.first);
+ else
+ return true;
+ }
+
+ return false;
+}
+
+bool
+DepList::match_on_list(const PackageDepSpec & a) const
+{
+ std::pair<MergeListIndex::const_iterator, MergeListIndex::const_iterator> p;
+ if (a.package_ptr())
+ p = _imp->merge_list_index.equal_range(*a.package_ptr());
+ else
+ p = std::make_pair(_imp->merge_list_index.begin(), _imp->merge_list_index.end());
+
+ return p.second != std::find_if(p.first, p.second,
+ MatchDepListEntryAgainstPackageDepSpec(_imp->env, a));
+}
+
tr1::shared_ptr<DestinationsCollection>
paludis::extract_dep_list_entry_destinations(tr1::shared_ptr<SortedCollection<DepListEntryDestination> > d)
{
@@ -1736,3 +1613,14 @@ paludis::extract_dep_list_entry_destinations(tr1::shared_ptr<SortedCollection<De
return result;
}
+bool
+paludis::is_viable_any_child(const Environment & env, const PackageDatabaseEntry * const pde,
+ const DependencySpecTree::ConstItem & i)
+{
+ const UseDepSpec * const u(get_const_item(i)->as_use_dep_spec());
+ if (0 != u)
+ return (pde ? env.query_use(u->flag(), *pde) : false) ^ u->inverse();
+ else
+ return true;
+}
+
diff --git a/paludis/dep_list/dep_list.hh b/paludis/dep_list/dep_list.hh
index ae44aa6..d25c3bc 100644
--- a/paludis/dep_list/dep_list.hh
+++ b/paludis/dep_list/dep_list.hh
@@ -20,9 +20,10 @@
#ifndef PALUDIS_GUARD_PALUDIS_DEP_LIST_HH
#define PALUDIS_GUARD_PALUDIS_DEP_LIST_HH 1
-#include <paludis/dep_spec.hh>
+#include <paludis/dep_spec-fwd.hh>
#include <paludis/dep_tag.hh>
#include <paludis/dep_list/options.hh>
+#include <paludis/dep_list/dep_list-fwd.hh>
#include <paludis/name.hh>
#include <paludis/environment.hh>
#include <paludis/util/instantiation_policy.hh>
@@ -52,11 +53,9 @@ namespace paludis
{
protected:
class AddVisitor;
- class QueryVisitor;
class ShowSuggestVisitor;
friend class AddVisitor;
- friend class QueryVisitor;
friend class ShowSuggestVisitor;
/**
@@ -138,6 +137,11 @@ namespace paludis
tr1::shared_ptr<DepListOptions> options();
/**
+ * Our options.
+ */
+ const tr1::shared_ptr<const DepListOptions> options() const;
+
+ /**
* Add the packages required to resolve an additional dependency
* spec.
*/
@@ -163,6 +167,16 @@ namespace paludis
tr1::shared_ptr<const DestinationsCollection> target_destinations) const;
/**
+ * Return whether a PackageDatabaseEntry has been replaced.
+ */
+ bool replaced(const PackageDatabaseEntry &) const;
+
+ /**
+ * Return whether a spec matches an item in the list.
+ */
+ bool match_on_list(const PackageDepSpec &) const;
+
+ /**
* Whether we have any errors.
*/
bool has_errors() const;
@@ -178,14 +192,6 @@ namespace paludis
///\}
};
-
- /**
- * Extract the destinations from a DepListEntry destinations member.
- *
- * \ingroup grpdepresolver
- */
- tr1::shared_ptr<DestinationsCollection> extract_dep_list_entry_destinations(
- tr1::shared_ptr<SortedCollection<DepListEntryDestination> >) PALUDIS_VISIBLE;
}
#endif
diff --git a/paludis/dep_list/query_visitor.cc b/paludis/dep_list/query_visitor.cc
new file mode 100644
index 0000000..0145190
--- /dev/null
+++ b/paludis/dep_list/query_visitor.cc
@@ -0,0 +1,164 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/dep_list/query_visitor.hh>
+#include <paludis/dep_list/dep_list.hh>
+#include <paludis/dep_list/range_rewriter.hh>
+#include <paludis/package_database.hh>
+#include <paludis/util/tr1_functional.hh>
+#include <algorithm>
+
+using namespace paludis;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<QueryVisitor>
+ {
+ bool result;
+ const DepList * const dep_list;
+ tr1::shared_ptr<const DestinationsCollection> destinations;
+ const Environment * const environment;
+ const PackageDatabaseEntry * const pde;
+
+ Implementation(const DepList * const d, tr1::shared_ptr<const DestinationsCollection> dd,
+ const Environment * const e, const PackageDatabaseEntry * const p) :
+ result(true),
+ dep_list(d),
+ destinations(dd),
+ environment(e),
+ pde(p)
+ {
+ }
+ };
+}
+
+QueryVisitor::QueryVisitor(const DepList * const d, tr1::shared_ptr<const DestinationsCollection> dd,
+ const Environment * const e, const PackageDatabaseEntry * const pde) :
+ PrivateImplementationPattern<QueryVisitor>(new Implementation<QueryVisitor>(d, dd, e, pde))
+{
+}
+
+QueryVisitor::~QueryVisitor()
+{
+}
+
+bool
+QueryVisitor::result() const
+{
+ return _imp->result;
+}
+
+void
+QueryVisitor::visit_leaf(const PackageDepSpec & a)
+{
+ using namespace tr1::placeholders;
+
+ /* a pda matches if we'll be installed by the time we reach the current point. This
+ * means that merely being installed is not enough, if we'll have our version changed
+ * by something in the merge list. */
+
+ _imp->result = false;
+
+ // TODO: check destinations
+ tr1::shared_ptr<const PackageDatabaseEntryCollection> matches(_imp->environment->package_database()->query(
+ a, is_installed_only, qo_whatever));
+
+ if (matches->end() != std::find_if(matches->begin(), matches->end(),
+ tr1::bind(tr1::mem_fn(&DepList::replaced), _imp->dep_list, _1)))
+ {
+ _imp->result = true;
+ return;
+ }
+
+ /* check the merge list for any new packages that match */
+ if (_imp->dep_list->match_on_list(a))
+ {
+ _imp->result = true;
+ return;
+ }
+}
+
+void
+QueryVisitor::visit_sequence(const UseDepSpec & a,
+ DependencySpecTree::ConstSequenceIterator cur,
+ DependencySpecTree::ConstSequenceIterator end)
+{
+ /* for use? ( ) dep specs, return true if we're not enabled, so that
+ * weird || ( ) cases work. */
+ if ((_imp->pde ? _imp->environment->query_use(a.flag(), *_imp->pde) : false) ^ a.inverse())
+ {
+ _imp->result = true;
+ for ( ; cur != end ; ++cur)
+ {
+ cur->accept(*this);
+ if (! _imp->result)
+ return;
+ }
+ }
+ else
+ _imp->result = true;
+}
+
+void
+QueryVisitor::visit_sequence(const AnyDepSpec &,
+ DependencySpecTree::ConstSequenceIterator cur,
+ DependencySpecTree::ConstSequenceIterator end)
+{
+ /* empty || ( ) must resolve to true */
+ _imp->result = true;
+
+ RangeRewriter r;
+ std::for_each(cur, end, accept_visitor(r));
+
+ if (r.spec())
+ visit_leaf(*r.spec());
+ else
+ for ( ; cur != end ; ++cur)
+ {
+ if (! is_viable_any_child(*_imp->environment, _imp->pde, *cur))
+ continue;
+
+ cur->accept(*this);
+ if (_imp->result)
+ return;
+ }
+}
+
+void
+QueryVisitor::visit_leaf(const BlockDepSpec & a)
+{
+ visit_leaf(*a.blocked_spec());
+ _imp->result = !_imp->result;
+}
+
+void
+QueryVisitor::visit_sequence(const AllDepSpec &,
+ DependencySpecTree::ConstSequenceIterator cur,
+ DependencySpecTree::ConstSequenceIterator end)
+{
+ for ( ; cur != end ; ++cur)
+ {
+ cur->accept(*this);
+ if (! _imp->result)
+ return;
+ }
+}
+
+
diff --git a/paludis/dep_list/query_visitor.hh b/paludis/dep_list/query_visitor.hh
new file mode 100644
index 0000000..77f7ee0
--- /dev/null
+++ b/paludis/dep_list/query_visitor.hh
@@ -0,0 +1,61 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_DEP_LIST_QUERY_VISITOR_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_LIST_QUERY_VISITOR_HH 1
+
+#include <paludis/dep_list/dep_list-fwd.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/dep_spec-fwd.hh>
+
+namespace paludis
+{
+ class PackageDatabaseEntry;
+
+ class QueryVisitor :
+ public ConstVisitor<DependencySpecTree>,
+ private PrivateImplementationPattern<QueryVisitor>
+ {
+ public:
+ QueryVisitor(const DepList * const, tr1::shared_ptr<const DestinationsCollection>,
+ const Environment * const, const PackageDatabaseEntry * const);
+
+ ~QueryVisitor();
+
+ void visit_sequence(const AllDepSpec &,
+ DependencySpecTree::ConstSequenceIterator,
+ DependencySpecTree::ConstSequenceIterator);
+
+ void visit_sequence(const AnyDepSpec &,
+ DependencySpecTree::ConstSequenceIterator,
+ DependencySpecTree::ConstSequenceIterator);
+
+ void visit_sequence(const UseDepSpec &,
+ DependencySpecTree::ConstSequenceIterator,
+ DependencySpecTree::ConstSequenceIterator);
+
+ void visit_leaf(const PackageDepSpec &);
+
+ void visit_leaf(const BlockDepSpec &);
+
+ bool result() const;
+ };
+}
+
+#endif