aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-10-07 07:49:36 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-10-07 07:49:36 +0000
commit84451d51c2b34fcfc9cd1fddbb6cf7987a971686 (patch)
tree5d8d9903988c70b80b1e367e46c1d615ec206254
parent6faddfce5e7e803e2f456a497d8f8686952c2635 (diff)
downloadpaludis-84451d51c2b34fcfc9cd1fddbb6cf7987a971686.tar.gz
paludis-84451d51c2b34fcfc9cd1fddbb6cf7987a971686.tar.xz
NamedSetDepSpec. Fixes: ticket:305
-rw-r--r--doc/examples/example_dep_spec_flattener.cc6
-rw-r--r--doc/examples/example_dep_tag.cc2
-rw-r--r--doc/examples/example_dep_tree.cc32
-rw-r--r--paludis/condition_tracker.cc6
-rw-r--r--paludis/condition_tracker.hh1
-rw-r--r--paludis/dep_list.cc26
-rw-r--r--paludis/dep_spec-fwd.hh9
-rw-r--r--paludis/dep_spec.cc25
-rw-r--r--paludis/dep_spec.hh26
-rw-r--r--paludis/dep_spec_flattener.cc82
-rw-r--r--paludis/dep_spec_flattener.hh76
-rw-r--r--paludis/dep_tag.cc6
-rw-r--r--paludis/dep_tree.hh10
-rw-r--r--paludis/environment_implementation.cc11
-rw-r--r--paludis/formatter-fwd.hh8
-rw-r--r--paludis/formatter.hh32
-rw-r--r--paludis/install_task.cc55
-rw-r--r--paludis/match_package.cc57
-rw-r--r--paludis/query_visitor.cc30
-rw-r--r--paludis/query_visitor.hh2
-rw-r--r--paludis/range_rewriter.cc7
-rw-r--r--paludis/range_rewriter.hh2
-rw-r--r--paludis/report_task.cc23
-rw-r--r--paludis/repositories/cran/dep_spec_pretty_printer.cc16
-rw-r--r--paludis/repositories/cran/dep_spec_pretty_printer.hh2
-rw-r--r--paludis/repositories/e/dep_spec_pretty_printer.cc16
-rw-r--r--paludis/repositories/e/dep_spec_pretty_printer.hh2
-rw-r--r--paludis/repositories/e/e_key.cc2
-rw-r--r--paludis/repositories/e/e_repository_profile.cc20
-rw-r--r--paludis/repositories/e/ebuild_entries.cc6
-rw-r--r--paludis/repositories/e/qa/extractors.cc8
-rw-r--r--paludis/repositories/e/qa/spec_keys.cc4
-rw-r--r--paludis/repositories/e/qa/visibility.cc4
-rw-r--r--paludis/repositories/e/vdb_repository.cc4
-rw-r--r--paludis/repositories/fake/fake_installed_repository.cc2
-rw-r--r--paludis/set_file.cc11
-rw-r--r--paludis/set_file_TEST.cc5
-rw-r--r--paludis/show_suggest_visitor.cc26
-rw-r--r--paludis/show_suggest_visitor.hh2
-rw-r--r--paludis/stringify_formatter-impl.hh4
-rw-r--r--paludis/stringify_formatter.cc11
-rw-r--r--paludis/stringify_formatter.hh3
-rw-r--r--paludis/uninstall_list.cc26
-rw-r--r--paludis/uninstall_task.cc40
-rw-r--r--paludis/util/visitor.hh74
-rw-r--r--paludis/util/visitor_TEST.cc7
-rw-r--r--python/dep_spec.cc66
-rw-r--r--python/dep_spec.hh22
-rwxr-xr-xpython/dep_spec_TEST.py6
-rw-r--r--src/clients/adjutrix/find_insecure_packages.cc24
-rw-r--r--src/clients/adjutrix/find_reverse_deps.cc35
-rw-r--r--src/clients/gtkpaludis/libgtkpaludis/markup_formatter.cc6
-rw-r--r--src/clients/gtkpaludis/libgtkpaludis/markup_formatter.hh3
-rw-r--r--src/clients/gtkpaludis/libgtkpaludis/packages_list_model.cc2
-rw-r--r--src/clients/paludis/query.cc5
-rw-r--r--src/output/colour_formatter.cc6
-rw-r--r--src/output/colour_formatter.hh3
-rw-r--r--src/output/console_query_task.cc5
58 files changed, 861 insertions, 151 deletions
diff --git a/doc/examples/example_dep_spec_flattener.cc b/doc/examples/example_dep_spec_flattener.cc
index dcbfbf3..1974bce 100644
--- a/doc/examples/example_dep_spec_flattener.cc
+++ b/doc/examples/example_dep_spec_flattener.cc
@@ -58,7 +58,7 @@ int main(int argc, char * argv[])
if ((*i)->provide_key())
{
/* Create our flattener... */
- DepSpecFlattener<ProvideSpecTree, PackageDepSpec> provides(env.get(), *i);
+ DepSpecFlattener<ProvideSpecTree, PackageDepSpec> provides(env.get(), **i);
/* Populate it by making it visit the key's value */
(*i)->provide_key()->value()->accept(provides);
@@ -74,7 +74,7 @@ int main(int argc, char * argv[])
/* Again for homepage */
if ((*i)->homepage_key())
{
- DepSpecFlattener<SimpleURISpecTree, SimpleURIDepSpec> homepages(env.get(), *i);
+ DepSpecFlattener<SimpleURISpecTree, SimpleURIDepSpec> homepages(env.get(), **i);
(*i)->homepage_key()->value()->accept(homepages);
cout << " " << left << setw(24) << "Homepages:" << " "
@@ -91,7 +91,7 @@ int main(int argc, char * argv[])
if ((*i)->end_metadata() != (*i)->find_metadata("RESTRICT") &&
visitor_cast<const MetadataSpecTreeKey<RestrictSpecTree> >(**(*i)->find_metadata("RESTRICT")))
{
- DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(env.get(), *i);
+ DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(env.get(), **i);
visitor_cast<const MetadataSpecTreeKey<RestrictSpecTree> >(
**(*i)->find_metadata("RESTRICT"))->value()->accept(restricts);
diff --git a/doc/examples/example_dep_tag.cc b/doc/examples/example_dep_tag.cc
index e511ffb..17e1a3d 100644
--- a/doc/examples/example_dep_tag.cc
+++ b/doc/examples/example_dep_tag.cc
@@ -91,7 +91,7 @@ namespace
/* The set isn't necessarily flat. We use DepSpecFlattener to make it
* so, rather than writing a full visitor ourselves. We don't need to
* supply a package, since a SetSpecTree cannot contain a UseDepSpec. */
- DepSpecFlattener<SetSpecTree, PackageDepSpec> set_flat(env.get(), tr1::shared_ptr<const PackageID>());
+ DepSpecFlattener<SetSpecTree, PackageDepSpec> set_flat(env.get());
set->accept(set_flat);
cout << "Set '" << name << "':" << endl;
diff --git a/doc/examples/example_dep_tree.cc b/doc/examples/example_dep_tree.cc
index 335da1b..48fa6a5 100644
--- a/doc/examples/example_dep_tree.cc
+++ b/doc/examples/example_dep_tree.cc
@@ -26,6 +26,7 @@
#include <cstdlib>
#include <list>
#include <map>
+#include <set>
using namespace paludis;
using namespace examples;
@@ -54,6 +55,7 @@ namespace
const tr1::shared_ptr<const Environment> _env;
const tr1::shared_ptr<const PackageID> _id;
ResultsMap & _results;
+ std::set<SetName> _recursing_sets;
public:
DependenciesCollector(
@@ -87,6 +89,36 @@ namespace
_results[stringify(*_id)].first = true;
}
+ void visit_leaf(const NamedSetDepSpec & spec)
+ {
+ /* For named set specs, we visit the set. */
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(_env->set(spec.name()));
+
+ /* First complication: we might have a name referring to a set
+ * that doesn't exist. */
+ if (! set)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Unknown set '" << spec << "'";
+ return;
+ }
+
+ /* Second complication: we need to handle sets that contain
+ * themselves. Although this shouldn't happen, user-defined
+ * sets can be made to include themselves, possibly with
+ * other sets inbetween (a includes b includes a). */
+ if (! _recursing_sets.insert(spec.name()).second)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Recursively defined set '" << spec << "'";
+ return;
+ }
+
+ /* Now that we have the set, we can handle it simply by
+ * visiting it. */
+ set->accept(*this);
+
+ _recursing_sets.erase(spec.name());
+ }
+
void visit_leaf(const BlockDepSpec &)
{
/* Not interested */
diff --git a/paludis/condition_tracker.cc b/paludis/condition_tracker.cc
index 3c84371..b915198 100644
--- a/paludis/condition_tracker.cc
+++ b/paludis/condition_tracker.cc
@@ -138,3 +138,9 @@ ConditionTracker::visit_leaf(const DependencyLabelsDepSpec &)
throw InternalError(PALUDIS_HERE, "ConditionTracker saw a DependencyLabelsDepSpec");
}
+void
+ConditionTracker::visit_leaf(const NamedSetDepSpec &)
+{
+ throw InternalError(PALUDIS_HERE, "ConditionTracker saw a NamedSetDepSpec");
+}
+
diff --git a/paludis/condition_tracker.hh b/paludis/condition_tracker.hh
index 3b9b99d..95c421f 100644
--- a/paludis/condition_tracker.hh
+++ b/paludis/condition_tracker.hh
@@ -64,6 +64,7 @@ namespace paludis
void visit_leaf(const PackageDepSpec &) PALUDIS_ATTRIBUTE((noreturn));
void visit_leaf(const BlockDepSpec &) PALUDIS_ATTRIBUTE((noreturn));
void visit_leaf(const DependencyLabelsDepSpec &) PALUDIS_ATTRIBUTE((noreturn));
+ void visit_leaf(const NamedSetDepSpec &) PALUDIS_ATTRIBUTE((noreturn));
};
}
diff --git a/paludis/dep_list.cc b/paludis/dep_list.cc
index 1a86efd..a55d7f1 100644
--- a/paludis/dep_list.cc
+++ b/paludis/dep_list.cc
@@ -286,6 +286,7 @@ struct DepList::AddVisitor :
DepList * const d;
tr1::shared_ptr<const DestinationsSet> destinations;
tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > conditions;
+ std::set<SetName> recursing_sets;
AddVisitor(DepList * const dd, tr1::shared_ptr<const DestinationsSet> ddd,
tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > c =
@@ -313,6 +314,8 @@ struct DepList::AddVisitor :
void visit_leaf(const BlockDepSpec &);
void visit_leaf(const DependencyLabelsDepSpec &);
+
+ void visit_leaf(const NamedSetDepSpec &);
};
void
@@ -585,6 +588,27 @@ DepList::AddVisitor::visit_leaf(const PackageDepSpec & a)
}
void
+DepList::AddVisitor::visit_leaf(const NamedSetDepSpec & a)
+{
+ Context context("When adding NamedSetDepSpec '" + stringify(a) + "':");
+
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(d->_imp->env->set(a.name()));
+
+ if (! set)
+ throw NoSuchPackageError(stringify(a.name()));
+
+ if (! recursing_sets.insert(a.name()).second)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Recursively defined set '" << a.name() << "'";
+ throw NoSuchPackageError(stringify(a.name()));
+ }
+
+ set->accept(*this);
+
+ recursing_sets.erase(a.name());
+}
+
+void
DepList::AddVisitor::visit_sequence(const UseDepSpec & a,
DependencySpecTree::ConstSequenceIterator cur,
DependencySpecTree::ConstSequenceIterator end)
@@ -1004,7 +1028,7 @@ DepList::add_package(const tr1::shared_ptr<const PackageID> & p, tr1::shared_ptr
/* add provides */
if (p->provide_key())
{
- DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(_imp->env, _imp->current_package_id());
+ DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(_imp->env, *_imp->current_package_id());
p->provide_key()->value()->accept(f);
if (f.begin() != f.end() && ! DistributionData::get_instance()->distribution_from_string(
diff --git a/paludis/dep_spec-fwd.hh b/paludis/dep_spec-fwd.hh
index ba9dd9c..6866128 100644
--- a/paludis/dep_spec-fwd.hh
+++ b/paludis/dep_spec-fwd.hh
@@ -46,6 +46,7 @@ namespace paludis
class UseDepSpec;
class BlockDepSpec;
class StringDepSpec;
+ class NamedSetDepSpec;
template <typename T_> class LabelsDepSpec;
/**
@@ -137,6 +138,14 @@ namespace paludis
* \since 0.26
*/
std::ostream & operator<< (std::ostream &, const UseDepSpec &) PALUDIS_VISIBLE;
+
+ /**
+ * A NamedSetDepSpec can be written to an ostream.
+ *
+ * \ingroup g_dep_spec
+ * \since 0.26
+ */
+ std::ostream & operator<< (std::ostream &, const NamedSetDepSpec &) PALUDIS_VISIBLE;
}
#endif
diff --git a/paludis/dep_spec.cc b/paludis/dep_spec.cc
index af3ad5f..9c266dc 100644
--- a/paludis/dep_spec.cc
+++ b/paludis/dep_spec.cc
@@ -158,6 +158,24 @@ StringDepSpec::text() const
return _str;
}
+NamedSetDepSpec::NamedSetDepSpec(const SetName & n) :
+ StringDepSpec(stringify(n)),
+ _name(n)
+{
+}
+
+const SetName
+NamedSetDepSpec::name() const
+{
+ return _name;
+}
+
+tr1::shared_ptr<DepSpec>
+NamedSetDepSpec::clone() const
+{
+ return tr1::shared_ptr<NamedSetDepSpec>(new NamedSetDepSpec(_name));
+}
+
const PackageDepSpec *
PackageDepSpec::as_package_dep_spec() const
{
@@ -591,6 +609,13 @@ paludis::operator<< (std::ostream & s, const LicenseDepSpec & a)
}
std::ostream &
+paludis::operator<< (std::ostream & s, const NamedSetDepSpec & a)
+{
+ s << a.name();
+ return s;
+}
+
+std::ostream &
paludis::operator<< (std::ostream & s, const BlockDepSpec & a)
{
s << "!" << *a.blocked_spec();
diff --git a/paludis/dep_spec.hh b/paludis/dep_spec.hh
index 644e3c2..0be8196 100644
--- a/paludis/dep_spec.hh
+++ b/paludis/dep_spec.hh
@@ -396,6 +396,32 @@ namespace paludis
};
/**
+ * A NamedSetDepSpec represents a named package set.
+ *
+ * \ingroup g_dep_spec
+ * \nosubgrouping
+ */
+ class PALUDIS_VISIBLE NamedSetDepSpec :
+ public StringDepSpec
+ {
+ private:
+ const SetName _name;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ NamedSetDepSpec(const SetName &);
+
+ ///\}
+
+ /// Fetch the name of our set.
+ const SetName name() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual tr1::shared_ptr<DepSpec> clone() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ /**
* A LicenseDepSpec represents a license entry.
*
* \ingroup g_dep_spec
diff --git a/paludis/dep_spec_flattener.cc b/paludis/dep_spec_flattener.cc
index 93a82fd..5eb0759 100644
--- a/paludis/dep_spec_flattener.cc
+++ b/paludis/dep_spec_flattener.cc
@@ -23,9 +23,12 @@
#include <paludis/environment.hh>
#include <paludis/util/visitor-impl.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/stringify.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <list>
#include <algorithm>
+#include <set>
using namespace paludis;
@@ -36,12 +39,11 @@ namespace paludis
struct Implementation<DepSpecFlattener<Heirarchy_, Item_> >
{
const Environment * const env;
- const tr1::shared_ptr<const PackageID> pkg;
+ const PackageID * const pkg;
std::list<tr1::shared_ptr<const Item_> > specs;
- Implementation(const Environment * const e,
- const tr1::shared_ptr<const PackageID> p) :
+ Implementation(const Environment * const e, const PackageID * const p) :
env(e),
pkg(p)
{
@@ -52,9 +54,22 @@ namespace paludis
template <typename Heirarchy_, typename Item_>
DepSpecFlattener<Heirarchy_, Item_>::DepSpecFlattener(
const Environment * const env,
- const tr1::shared_ptr<const PackageID> & pkg) :
+ const PackageID & pkg) :
PrivateImplementationPattern<DepSpecFlattener<Heirarchy_, Item_> >(
- new Implementation<DepSpecFlattener<Heirarchy_, Item_> >(env, pkg))
+ new Implementation<DepSpecFlattener<Heirarchy_, Item_> >(env, &pkg)),
+ _imp(PrivateImplementationPattern<DepSpecFlattener<Heirarchy_, Item_> >::_imp.get())
+{
+}
+
+template <typename Heirarchy_, typename Item_>
+DepSpecFlattener<Heirarchy_, Item_>::DepSpecFlattener(
+ const Environment * const e,
+ const typename Select<ConstVisitor<Heirarchy_>::template
+ Contains<const ConstTreeSequence<Heirarchy_, UseDepSpec> >::value,
+ NoType<0u>, Empty>::Type &) :
+ PrivateImplementationPattern<DepSpecFlattener<Heirarchy_, Item_> >(
+ new Implementation<DepSpecFlattener<Heirarchy_, Item_> >(e, 0)),
+ _imp(PrivateImplementationPattern<DepSpecFlattener<Heirarchy_, Item_> >::_imp.get())
{
}
@@ -79,12 +94,63 @@ DepSpecFlattener<Heirarchy_, Item_>::end() const
template <typename Heirarchy_, typename Item_>
void
-DepSpecFlattener<Heirarchy_, Item_>::visit_sequence(const UseDepSpec & u,
+dep_spec_flattener_internals::VisitUseDepSpec<Heirarchy_, Item_, true>::visit_sequence(const UseDepSpec & u,
typename Heirarchy_::ConstSequenceIterator cur,
typename Heirarchy_::ConstSequenceIterator e)
{
- if (_imp->env->query_use(u.flag(), *_imp->pkg) ^ u.inverse())
- std::for_each(cur, e, accept_visitor(*this));
+ DepSpecFlattener<Heirarchy_, Item_> * const f(static_cast<DepSpecFlattener<Heirarchy_, Item_> *>(this));
+
+ if (f->_imp->env->query_use(u.flag(), *f->_imp->pkg) ^ u.inverse())
+ std::for_each(cur, e, accept_visitor(*f));
+}
+
+namespace paludis
+{
+ template <>
+ template <typename Heirarchy_, typename Item_>
+ struct Implementation<dep_spec_flattener_internals::VisitNamedSetDepSpec<Heirarchy_, Item_, true> >
+ {
+ std::set<SetName> recursing_sets;
+ };
+}
+
+template <typename Heirarchy_, typename Item_>
+dep_spec_flattener_internals::VisitNamedSetDepSpec<Heirarchy_, Item_, true>::VisitNamedSetDepSpec() :
+ PrivateImplementationPattern<dep_spec_flattener_internals::VisitNamedSetDepSpec<Heirarchy_, Item_, true> >(
+ new Implementation<dep_spec_flattener_internals::VisitNamedSetDepSpec<Heirarchy_, Item_, true> >)
+{
+}
+
+template <typename Heirarchy_, typename Item_>
+dep_spec_flattener_internals::VisitNamedSetDepSpec<Heirarchy_, Item_, true>::~VisitNamedSetDepSpec()
+{
+}
+
+template <typename Heirarchy_, typename Item_>
+void
+dep_spec_flattener_internals::VisitNamedSetDepSpec<Heirarchy_, Item_, true>::visit_leaf(const NamedSetDepSpec & s)
+{
+ DepSpecFlattener<Heirarchy_, Item_> * const f(static_cast<DepSpecFlattener<Heirarchy_, Item_> *>(this));
+
+ Context context("When expanding named set '" + stringify(s) + "':");
+
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(f->_imp->env->set(s.name()));
+
+ if (! set)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Unknown set '" << s.name() << "'";
+ return;
+ }
+
+ if (! _imp->recursing_sets.insert(s.name()).second)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Recursively defined set '" << s.name() << "'";
+ return;
+ }
+
+ set->accept(*f);
+
+ _imp->recursing_sets.erase(s.name());
}
template <typename Heirarchy_, typename Item_>
diff --git a/paludis/dep_spec_flattener.hh b/paludis/dep_spec_flattener.hh
index a32f12b..2e797e8 100644
--- a/paludis/dep_spec_flattener.hh
+++ b/paludis/dep_spec_flattener.hh
@@ -28,6 +28,8 @@
#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/util/tr1_memory.hh>
#include <paludis/util/visitor.hh>
+#include <paludis/util/no_type.hh>
+#include <paludis/util/sr.hh>
#include <libwrapiter/libwrapiter_forward_iterator-fwd.hh>
@@ -43,9 +45,50 @@
namespace paludis
{
+ namespace dep_spec_flattener_internals
+ {
+ template <typename H_, typename I_, bool b_>
+ struct VisitNamedSetDepSpec
+ {
+ void visit_leaf(const NoType<0u> &);
+ };
+
+ template <typename H_, typename I_>
+ class VisitNamedSetDepSpec<H_, I_, true> :
+ public virtual visitor_internals::Visits<const TreeLeaf<H_, NamedSetDepSpec> >,
+ private PrivateImplementationPattern<VisitNamedSetDepSpec<H_, I_, true> >
+ {
+ private:
+ using PrivateImplementationPattern<VisitNamedSetDepSpec<H_, I_, true> >::_imp;
+
+ protected:
+ VisitNamedSetDepSpec();
+ ~VisitNamedSetDepSpec();
+
+ public:
+ void visit_leaf(const NamedSetDepSpec &);
+ };
+
+ template <typename H_, typename I_, bool b_>
+ struct VisitUseDepSpec
+ {
+ void visit_sequence(const NoType<0u> &);
+ };
+
+ template <typename H_, typename I_>
+ struct VisitUseDepSpec<H_, I_, true> :
+ virtual visitor_internals::Visits<const ConstTreeSequence<H_, UseDepSpec> >
+ {
+ void visit_sequence(
+ const UseDepSpec &,
+ typename H_::ConstSequenceIterator,
+ typename H_::ConstSequenceIterator);
+ };
+ }
+
/**
* Extract the enabled components of a dep heirarchy for a particular
- * package.
+ * package. Sets, via NamedSetDepSpec, are automatically expanded.
*
* This template can be instantiated as:
*
@@ -66,10 +109,19 @@ namespace paludis
private InstantiationPolicy<DepSpecFlattener<Heirarchy_, Item_>, instantiation_method::NonCopyableTag>,
private PrivateImplementationPattern<DepSpecFlattener<Heirarchy_, Item_> >,
public ConstVisitor<Heirarchy_>,
- public ConstVisitor<Heirarchy_>::template VisitConstSequence<DepSpecFlattener<Heirarchy_, Item_>, AllDepSpec>
+ public ConstVisitor<Heirarchy_>::template VisitConstSequence<DepSpecFlattener<Heirarchy_, Item_>, AllDepSpec>,
+ public dep_spec_flattener_internals::VisitNamedSetDepSpec<
+ Heirarchy_, Item_, ConstVisitor<Heirarchy_>::template Contains<const TreeLeaf<Heirarchy_, NamedSetDepSpec> >::value>,
+ public dep_spec_flattener_internals::VisitUseDepSpec<
+ Heirarchy_, Item_, ConstVisitor<Heirarchy_>::template Contains<const ConstTreeSequence<Heirarchy_, UseDepSpec> >::value>
{
+ friend class dep_spec_flattener_internals::VisitNamedSetDepSpec<
+ Heirarchy_, Item_, ConstVisitor<Heirarchy_>::template Contains<const TreeLeaf<Heirarchy_, NamedSetDepSpec> >::value>;
+ friend class dep_spec_flattener_internals::VisitUseDepSpec<
+ Heirarchy_, Item_, ConstVisitor<Heirarchy_>::template Contains<const ConstTreeSequence<Heirarchy_, UseDepSpec> >::value>;
+
private:
- using PrivateImplementationPattern<DepSpecFlattener<Heirarchy_, Item_> >::_imp;
+ Implementation<DepSpecFlattener<Heirarchy_, Item_> > * const _imp;
public:
///\name Visit methods
@@ -77,9 +129,11 @@ namespace paludis
using ConstVisitor<Heirarchy_>::template VisitConstSequence<DepSpecFlattener<Heirarchy_, Item_>, AllDepSpec>::visit_sequence;
- void visit_sequence(const UseDepSpec &,
- typename Heirarchy_::ConstSequenceIterator,
- typename Heirarchy_::ConstSequenceIterator);
+ using dep_spec_flattener_internals::VisitUseDepSpec<Heirarchy_, Item_,
+ ConstVisitor<Heirarchy_>::template Contains<const ConstTreeSequence<Heirarchy_, UseDepSpec> >::value>::visit_sequence;
+
+ using dep_spec_flattener_internals::VisitNamedSetDepSpec<Heirarchy_, Item_,
+ ConstVisitor<Heirarchy_>::template Contains<const TreeLeaf<Heirarchy_, NamedSetDepSpec> >::value>::visit_leaf;
void visit_leaf(const Item_ &);
@@ -88,8 +142,16 @@ namespace paludis
///\name Basic operations
///\{
+ /**
+ * This constructor only works if we can't contain a UseDepSpec. The second
+ * parameter is ignored.
+ */
DepSpecFlattener(const Environment * const,
- const tr1::shared_ptr<const PackageID> &);
+ const typename Select<ConstVisitor<Heirarchy_>::template
+ Contains<const ConstTreeSequence<Heirarchy_, UseDepSpec> >::value,
+ NoType<0u>, Empty>::Type & t = Empty::instance);
+
+ DepSpecFlattener(const Environment * const, const PackageID &);
~DepSpecFlattener();
diff --git a/paludis/dep_tag.cc b/paludis/dep_tag.cc
index 1510f40..5a23077 100644
--- a/paludis/dep_tag.cc
+++ b/paludis/dep_tag.cc
@@ -217,6 +217,12 @@ namespace
std::ostream_iterator<DependencyLabelVisitorTypes::BasicNode>(s, ","));
s << ":";
}
+
+ void
+ visit_leaf(const NamedSetDepSpec & p)
+ {
+ s << p << " ";
+ }
};
struct DepTagComparator :
diff --git a/paludis/dep_tree.hh b/paludis/dep_tree.hh
index 7f6cf09..00d2c7a 100644
--- a/paludis/dep_tree.hh
+++ b/paludis/dep_tree.hh
@@ -62,6 +62,7 @@ namespace paludis
TreeLeaf<GenericSpecTree, BlockDepSpec>,
TreeLeaf<GenericSpecTree, URILabelsDepSpec>,
TreeLeaf<GenericSpecTree, DependencyLabelsDepSpec>,
+ TreeLeaf<GenericSpecTree, NamedSetDepSpec>,
ConstTreeSequence<GenericSpecTree, AllDepSpec>,
ConstTreeSequence<GenericSpecTree, AnyDepSpec>,
ConstTreeSequence<GenericSpecTree, UseDepSpec>
@@ -84,7 +85,8 @@ namespace paludis
PackageDepSpec,
BlockDepSpec,
URILabelsDepSpec,
- DependencyLabelsDepSpec
+ DependencyLabelsDepSpec,
+ NamedSetDepSpec
> Formatter;
};
@@ -255,6 +257,7 @@ namespace paludis
TreeLeaf<DependencySpecTree, PackageDepSpec>,
TreeLeaf<DependencySpecTree, BlockDepSpec>,
TreeLeaf<DependencySpecTree, DependencyLabelsDepSpec>,
+ TreeLeaf<DependencySpecTree, NamedSetDepSpec>,
ConstTreeSequence<DependencySpecTree, AllDepSpec>,
ConstTreeSequence<DependencySpecTree, AnyDepSpec>,
ConstTreeSequence<DependencySpecTree, UseDepSpec>
@@ -272,6 +275,7 @@ namespace paludis
UseDepSpec,
PackageDepSpec,
BlockDepSpec,
+ NamedSetDepSpec,
DependencyLabelsDepSpec
> Formatter;
};
@@ -288,6 +292,7 @@ namespace paludis
SetSpecTree,
DepSpec,
TreeLeaf<SetSpecTree, PackageDepSpec>,
+ TreeLeaf<SetSpecTree, NamedSetDepSpec>,
ConstTreeSequence<SetSpecTree, AllDepSpec>
>
{
@@ -300,7 +305,8 @@ namespace paludis
* \nosubgrouping
*/
typedef Formatter<
- PackageDepSpec
+ PackageDepSpec,
+ NamedSetDepSpec
> Formatter;
};
}
diff --git a/paludis/environment_implementation.cc b/paludis/environment_implementation.cc
index 771e098..295d622 100644
--- a/paludis/environment_implementation.cc
+++ b/paludis/environment_implementation.cc
@@ -122,15 +122,12 @@ EnvironmentImplementation::set(const SetName & s) const
result.reset(new ConstTreeSequence<SetSpecTree, AllDepSpec>(tr1::shared_ptr<AllDepSpec>(new AllDepSpec)));
result->add(add);
}
-
- if ("everything" == s.data() || "world" == s.data())
- {
- add = (*r)->sets_interface->package_set(SetName("system"));
- if (add)
- result->add(add);
- }
}
+ if ("everything" == s.data() || "world" == s.data())
+ result->add(make_shared_ptr(new TreeLeaf<SetSpecTree, NamedSetDepSpec>(
+ make_shared_ptr(new NamedSetDepSpec(SetName("system"))))));
+
if (! result)
Log::get_instance()->message(ll_debug, lc_context) << "No match for set '" << s << "'";
return result;
diff --git a/paludis/formatter-fwd.hh b/paludis/formatter-fwd.hh
index a7904a5..0a02836 100644
--- a/paludis/formatter-fwd.hh
+++ b/paludis/formatter-fwd.hh
@@ -33,7 +33,13 @@ namespace paludis
typename T6_ = NoType<6u>,
typename T7_ = NoType<7u>,
typename T8_ = NoType<8u>,
- typename T9_ = NoType<9u>
+ typename T9_ = NoType<9u>,
+ typename T10_ = NoType<10u>,
+ typename T11_ = NoType<11u>,
+ typename T12_ = NoType<12u>,
+ typename T13_ = NoType<13u>,
+ typename T14_ = NoType<14u>,
+ typename T15_ = NoType<15u>
>
class Formatter;
}
diff --git a/paludis/formatter.hh b/paludis/formatter.hh
index e38a500..ccbc6c0 100644
--- a/paludis/formatter.hh
+++ b/paludis/formatter.hh
@@ -496,7 +496,13 @@ namespace paludis
typename T6_,
typename T7_,
typename T8_,
- typename T9_
+ typename T9_,
+ typename T10_,
+ typename T11_,
+ typename T12_,
+ typename T13_,
+ typename T14_,
+ typename T15_
>
class PALUDIS_VISIBLE Formatter :
public FormatFunctionsByProxy<T1_, typename format::CategorySelector<T1_>::Category, 1>,
@@ -508,6 +514,12 @@ namespace paludis
public FormatFunctionsByProxy<T7_, typename format::CategorySelector<T7_>::Category, 7>,
public FormatFunctionsByProxy<T8_, typename format::CategorySelector<T8_>::Category, 8>,
public FormatFunctionsByProxy<T9_, typename format::CategorySelector<T9_>::Category, 9>,
+ public FormatFunctionsByProxy<T10_, typename format::CategorySelector<T10_>::Category, 10>,
+ public FormatFunctionsByProxy<T11_, typename format::CategorySelector<T11_>::Category, 11>,
+ public FormatFunctionsByProxy<T12_, typename format::CategorySelector<T12_>::Category, 12>,
+ public FormatFunctionsByProxy<T13_, typename format::CategorySelector<T13_>::Category, 13>,
+ public FormatFunctionsByProxy<T14_, typename format::CategorySelector<T14_>::Category, 14>,
+ public FormatFunctionsByProxy<T15_, typename format::CategorySelector<T15_>::Category, 15>,
public CanSpace
{
private:
@@ -525,6 +537,12 @@ namespace paludis
FormatFunctionsByProxy<T7_, typename format::CategorySelector<T7_>::Category, 7>(&t),
FormatFunctionsByProxy<T8_, typename format::CategorySelector<T8_>::Category, 8>(&t),
FormatFunctionsByProxy<T9_, typename format::CategorySelector<T9_>::Category, 9>(&t),
+ FormatFunctionsByProxy<T10_, typename format::CategorySelector<T10_>::Category, 10>(&t),
+ FormatFunctionsByProxy<T11_, typename format::CategorySelector<T11_>::Category, 11>(&t),
+ FormatFunctionsByProxy<T12_, typename format::CategorySelector<T12_>::Category, 12>(&t),
+ FormatFunctionsByProxy<T13_, typename format::CategorySelector<T13_>::Category, 13>(&t),
+ FormatFunctionsByProxy<T14_, typename format::CategorySelector<T14_>::Category, 14>(&t),
+ FormatFunctionsByProxy<T15_, typename format::CategorySelector<T15_>::Category, 15>(&t),
_proxy(&t)
{
}
@@ -539,6 +557,12 @@ namespace paludis
FormatFunctionsByProxy<T7_, typename format::CategorySelector<T7_>::Category, 7>(other),
FormatFunctionsByProxy<T8_, typename format::CategorySelector<T8_>::Category, 8>(other),
FormatFunctionsByProxy<T9_, typename format::CategorySelector<T9_>::Category, 9>(other),
+ FormatFunctionsByProxy<T10_, typename format::CategorySelector<T10_>::Category, 10>(other),
+ FormatFunctionsByProxy<T11_, typename format::CategorySelector<T11_>::Category, 11>(other),
+ FormatFunctionsByProxy<T12_, typename format::CategorySelector<T12_>::Category, 12>(other),
+ FormatFunctionsByProxy<T13_, typename format::CategorySelector<T13_>::Category, 13>(other),
+ FormatFunctionsByProxy<T14_, typename format::CategorySelector<T14_>::Category, 14>(other),
+ FormatFunctionsByProxy<T15_, typename format::CategorySelector<T15_>::Category, 15>(other),
CanSpace(other),
_proxy(other._proxy)
{
@@ -553,6 +577,12 @@ namespace paludis
using FormatFunctionsByProxy<T7_, typename format::CategorySelector<T7_>::Category, 7>::format;
using FormatFunctionsByProxy<T8_, typename format::CategorySelector<T8_>::Category, 8>::format;
using FormatFunctionsByProxy<T9_, typename format::CategorySelector<T9_>::Category, 9>::format;
+ using FormatFunctionsByProxy<T10_, typename format::CategorySelector<T10_>::Category, 10>::format;
+ using FormatFunctionsByProxy<T11_, typename format::CategorySelector<T11_>::Category, 11>::format;
+ using FormatFunctionsByProxy<T12_, typename format::CategorySelector<T12_>::Category, 12>::format;
+ using FormatFunctionsByProxy<T13_, typename format::CategorySelector<T13_>::Category, 13>::format;
+ using FormatFunctionsByProxy<T14_, typename format::CategorySelector<T14_>::Category, 14>::format;
+ using FormatFunctionsByProxy<T15_, typename format::CategorySelector<T15_>::Category, 15>::format;
virtual std::string newline() const
{
diff --git a/paludis/install_task.cc b/paludis/install_task.cc
index 894eb46..15e0dbe 100644
--- a/paludis/install_task.cc
+++ b/paludis/install_task.cc
@@ -42,6 +42,7 @@
#include <functional>
#include <algorithm>
#include <list>
+#include <set>
using namespace paludis;
@@ -910,15 +911,12 @@ namespace
{
using ConstVisitor<SetSpecTree>::VisitConstSequence<WorldTargetFinder, AllDepSpec>::visit_sequence;
+ Environment * const env;
InstallTask * const task;
- std::list<const PackageDepSpec *> items;
- bool inside_any;
- bool inside_use;
- WorldTargetFinder(InstallTask * const t) :
- task(t),
- inside_any(false),
- inside_use(false)
+ WorldTargetFinder(Environment * const e, InstallTask * const t) :
+ env(e),
+ task(t)
{
}
@@ -930,27 +928,26 @@ namespace
task->on_update_world_skip(a, "version restrictions");
else
{
- items.push_back(&a);
+ for (PackageDatabase::RepositoryConstIterator r(env->package_database()->begin_repositories()),
+ r_end(env->package_database()->end_repositories()) ;
+ r != r_end ; ++r)
+ if ((*r)->world_interface && a.package_ptr())
+ (*r)->world_interface->add_to_world(*a.package_ptr());
task->on_update_world(a);
}
}
+
+ void visit_leaf(const NamedSetDepSpec &)
+ {
+ }
};
}
void
InstallTask::world_update_packages(tr1::shared_ptr<const SetSpecTree::ConstItem> a)
{
- WorldTargetFinder w(this);
+ WorldTargetFinder w(_imp->env, this);
a->accept(w);
- for (std::list<const PackageDepSpec *>::const_iterator i(w.items.begin()),
- i_end(w.items.end()) ; i != i_end ; ++i)
- {
- for (PackageDatabase::RepositoryConstIterator r(_imp->env->package_database()->begin_repositories()),
- r_end(_imp->env->package_database()->end_repositories()) ;
- r != r_end ; ++r)
- if ((*r)->world_interface && (*i)->package_ptr())
- (*r)->world_interface->add_to_world(*(*i)->package_ptr());
- }
}
bool
@@ -982,6 +979,7 @@ namespace
const Environment * const env;
const PackageID & id;
tr1::shared_ptr<const PackageDepSpec> failure;
+ std::set<SetName> recursing_sets;
CheckSatisfiedVisitor(const Environment * const e,
const PackageID & i) :
@@ -1029,6 +1027,27 @@ namespace
break;
}
}
+
+ void visit_leaf(const NamedSetDepSpec & s)
+ {
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(env->set(s.name()));
+
+ if (! set)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Unknown set '" << s.name() << "'";
+ return;
+ }
+
+ if (! recursing_sets.insert(s.name()).second)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Recursively defined set '" << s.name() << "'";
+ return;
+ }
+
+ set->accept(*this);
+
+ recursing_sets.erase(s.name());
+ }
};
}
diff --git a/paludis/match_package.cc b/paludis/match_package.cc
index 4acaf43..950d473 100644
--- a/paludis/match_package.cc
+++ b/paludis/match_package.cc
@@ -19,11 +19,13 @@
#include <paludis/match_package.hh>
#include <paludis/dep_spec.hh>
+#include <paludis/dep_spec_flattener.hh>
#include <paludis/environment.hh>
#include <paludis/version_requirements.hh>
#include <paludis/package_database.hh>
#include <paludis/package_id.hh>
#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/tr1_functional.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <algorithm>
@@ -112,59 +114,18 @@ paludis::match_package(
return true;
}
-namespace
-{
- struct IsInHeirarchy :
- ConstVisitor<SetSpecTree>
- {
- const Environment & env;
- const SetSpecTree::ConstItem & target;
- const PackageID * id;
- bool matched;
-
- IsInHeirarchy(const Environment & e, const SetSpecTree::ConstItem & t) :
- env(e),
- target(t),
- matched(false)
- {
- }
-
- bool operator() (const PackageID & e)
- {
- id = &e;
- matched = false;
- target.accept(*this);
- return matched;
- }
-
- void visit_sequence(const AllDepSpec &,
- SetSpecTree::ConstSequenceIterator begin,
- SetSpecTree::ConstSequenceIterator end)
- {
- if (matched)
- return;
-
- std::for_each(begin, end, accept_visitor(*this));
- }
-
- void visit_leaf(const PackageDepSpec & a)
- {
- if (matched)
- return;
-
- if (match_package(env, a, *id))
- matched = true;
- }
- };
-}
-
bool
paludis::match_package_in_set(
const Environment & env,
const SetSpecTree::ConstItem & target,
const PackageID & entry)
{
- IsInHeirarchy h(env, target);
- return h(entry);
+ using namespace tr1::placeholders;
+
+ DepSpecFlattener<SetSpecTree, PackageDepSpec> f(&env, entry);
+ target.accept(f);
+ return indirect_iterator(f.end()) != std::find_if(
+ indirect_iterator(f.begin()), indirect_iterator(f.end()),
+ tr1::bind(&match_package, tr1::cref(env), _1, tr1::cref(entry)));
}
diff --git a/paludis/query_visitor.cc b/paludis/query_visitor.cc
index c279b11..51f3679 100644
--- a/paludis/query_visitor.cc
+++ b/paludis/query_visitor.cc
@@ -25,9 +25,12 @@
#include <paludis/util/tr1_functional.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/visitor-impl.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
#include <algorithm>
+#include <set>
using namespace paludis;
@@ -41,6 +44,7 @@ namespace paludis
tr1::shared_ptr<const DestinationsSet> destinations;
const Environment * const environment;
const tr1::shared_ptr<const PackageID> id;
+ std::set<SetName> recursing_sets;
Implementation(const DepList * const d, tr1::shared_ptr<const DestinationsSet> dd,
const Environment * const e, const tr1::shared_ptr<const PackageID> & p) :
@@ -101,6 +105,31 @@ QueryVisitor::visit_leaf(const PackageDepSpec & a)
}
void
+QueryVisitor::visit_leaf(const NamedSetDepSpec & s)
+{
+ Context context("When expanding named set '" + stringify(s) + "':");
+
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(_imp->environment->set(s.name()));
+
+ if (! set)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Unknown set '" << s.name() << "'";
+ _imp->result = false;
+ return;
+ }
+
+ if (! _imp->recursing_sets.insert(s.name()).second)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Recursively defined set '" << s.name() << "'";
+ return;
+ }
+
+ set->accept(*this);
+
+ _imp->recursing_sets.erase(s.name());
+}
+
+void
QueryVisitor::visit_sequence(const UseDepSpec & a,
DependencySpecTree::ConstSequenceIterator cur,
DependencySpecTree::ConstSequenceIterator end)
@@ -171,3 +200,4 @@ QueryVisitor::visit_leaf(const DependencyLabelsDepSpec &)
{
// XXX implement
}
+
diff --git a/paludis/query_visitor.hh b/paludis/query_visitor.hh
index 5d30a71..d666869 100644
--- a/paludis/query_visitor.hh
+++ b/paludis/query_visitor.hh
@@ -68,6 +68,8 @@ namespace paludis
void visit_leaf(const DependencyLabelsDepSpec &);
+ void visit_leaf(const NamedSetDepSpec &);
+
///\}
/**
diff --git a/paludis/range_rewriter.cc b/paludis/range_rewriter.cc
index 758597a..5a52538 100644
--- a/paludis/range_rewriter.cc
+++ b/paludis/range_rewriter.cc
@@ -109,3 +109,10 @@ RangeRewriter::visit_leaf(const DependencyLabelsDepSpec &)
{
_invalid = true;
}
+
+void
+RangeRewriter::visit_leaf(const NamedSetDepSpec &)
+{
+ _invalid = true;
+}
+
diff --git a/paludis/range_rewriter.hh b/paludis/range_rewriter.hh
index ed7e6e9..64e2569 100644
--- a/paludis/range_rewriter.hh
+++ b/paludis/range_rewriter.hh
@@ -81,6 +81,8 @@ namespace paludis
void visit_leaf(const DependencyLabelsDepSpec &);
+ void visit_leaf(const NamedSetDepSpec &);
+
///\}
};
}
diff --git a/paludis/report_task.cc b/paludis/report_task.cc
index 9923ef4..c1e8c67 100644
--- a/paludis/report_task.cc
+++ b/paludis/report_task.cc
@@ -45,6 +45,7 @@ namespace
private:
std::multimap<tr1::shared_ptr<const PackageID>, tr1::shared_ptr<const DepTag>, PackageIDSetComparator> _found;
const Environment & _env;
+ std::set<SetName> _recursing_sets;
public:
typedef std::multimap<tr1::shared_ptr<const PackageID>, tr1::shared_ptr<const DepTag>,
@@ -65,6 +66,28 @@ namespace
void visit_leaf(const PackageDepSpec &);
+ void visit_leaf(const NamedSetDepSpec & s)
+ {
+ Context context("When expanding named set '" + stringify(s) + "':");
+
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(_env.set(s.name()));
+ if (! set)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Unknown set '" << s.name() << "'";
+ return;
+ }
+
+ if (! _recursing_sets.insert(s.name()).second)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Recursively defined set '" << s.name() << "'";
+ return;
+ }
+
+ set->accept(*this);
+
+ _recursing_sets.erase(s.name());
+ }
+
///}
/**
diff --git a/paludis/repositories/cran/dep_spec_pretty_printer.cc b/paludis/repositories/cran/dep_spec_pretty_printer.cc
index 6b67513..06f20ac 100644
--- a/paludis/repositories/cran/dep_spec_pretty_printer.cc
+++ b/paludis/repositories/cran/dep_spec_pretty_printer.cc
@@ -105,6 +105,22 @@ DepSpecPrettyPrinter::visit_leaf(const DependencyLabelsDepSpec &)
{
}
+void
+DepSpecPrettyPrinter::visit_leaf(const NamedSetDepSpec & p)
+{
+ if (_imp->multiline)
+ _imp->s << _imp->formatter.indent(_imp->indent);
+ else if (_imp->need_comma)
+ _imp->s << ", ";
+ else
+ _imp->need_comma = true;
+
+ _imp->s << _imp->formatter.format(p, format::Plain());
+
+ if (_imp->multiline)
+ _imp->s << _imp->formatter.newline();
+}
+
std::ostream &
paludis::cranrepository::operator<< (std::ostream & s, const DepSpecPrettyPrinter & p)
{
diff --git a/paludis/repositories/cran/dep_spec_pretty_printer.hh b/paludis/repositories/cran/dep_spec_pretty_printer.hh
index 5db77fc..2bb8641 100644
--- a/paludis/repositories/cran/dep_spec_pretty_printer.hh
+++ b/paludis/repositories/cran/dep_spec_pretty_printer.hh
@@ -79,6 +79,8 @@ namespace paludis
void visit_leaf(const BlockDepSpec &);
void visit_leaf(const DependencyLabelsDepSpec &);
+
+ void visit_leaf(const NamedSetDepSpec &);
};
std::ostream & operator<< (std::ostream & s, const DepSpecPrettyPrinter & p) PALUDIS_VISIBLE;
diff --git a/paludis/repositories/e/dep_spec_pretty_printer.cc b/paludis/repositories/e/dep_spec_pretty_printer.cc
index 3d62593..3fa6c97 100644
--- a/paludis/repositories/e/dep_spec_pretty_printer.cc
+++ b/paludis/repositories/e/dep_spec_pretty_printer.cc
@@ -257,6 +257,22 @@ DepSpecPrettyPrinter::visit_leaf(const PlainTextDepSpec & p)
}
void
+DepSpecPrettyPrinter::visit_leaf(const NamedSetDepSpec & p)
+{
+ if (_imp->use_newlines)
+ _imp->s << _imp->formatter.indent(_imp->indent);
+ else if (_imp->need_space)
+ _imp->s << " ";
+
+ _imp->s << _imp->formatter.format(p, format::Plain());
+
+ if (_imp->use_newlines)
+ _imp->s << _imp->formatter.newline();
+ else
+ _imp->need_space = true;
+}
+
+void
DepSpecPrettyPrinter::visit_leaf(const LicenseDepSpec & p)
{
if (_imp->use_newlines)
diff --git a/paludis/repositories/e/dep_spec_pretty_printer.hh b/paludis/repositories/e/dep_spec_pretty_printer.hh
index f2641d6..14bc0ec 100644
--- a/paludis/repositories/e/dep_spec_pretty_printer.hh
+++ b/paludis/repositories/e/dep_spec_pretty_printer.hh
@@ -112,6 +112,8 @@ namespace paludis
void visit_leaf(const DependencyLabelsDepSpec &);
+ void visit_leaf(const NamedSetDepSpec &);
+
///}
};
diff --git a/paludis/repositories/e/e_key.cc b/paludis/repositories/e/e_key.cc
index 4d8ec55..9ba9854 100644
--- a/paludis/repositories/e/e_key.cc
+++ b/paludis/repositories/e/e_key.cc
@@ -362,7 +362,7 @@ EFetchableURIKey::initial_label() const
if (! _imp->initial_label)
{
- DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> f(_imp->env, _imp->id);
+ DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> f(_imp->env, *_imp->id);
if (_imp->id->restrict_key())
_imp->id->restrict_key()->value()->accept(f);
for (DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec>::ConstIterator i(f.begin()), i_end(f.end()) ;
diff --git a/paludis/repositories/e/e_repository_profile.cc b/paludis/repositories/e/e_repository_profile.cc
index d033409..21e8f31 100644
--- a/paludis/repositories/e/e_repository_profile.cc
+++ b/paludis/repositories/e/e_repository_profile.cc
@@ -427,16 +427,18 @@ Implementation<ERepositoryProfile>::make_vars_from_file_vars()
{
try
{
- for (erepository::ProfileFile<LineConfigFile>::ConstIterator i(packages_file.begin()), i_end(packages_file.end()) ; i != i_end ; ++i)
- {
- if (0 != i->compare(0, 1, "*", 0, 1))
- continue;
+ if (! repository->params().master_repository)
+ for (erepository::ProfileFile<LineConfigFile>::ConstIterator i(packages_file.begin()),
+ i_end(packages_file.end()) ; i != i_end ; ++i)
+ {
+ if (0 != i->compare(0, 1, "*", 0, 1))
+ continue;
- Context context_spec("When parsing '" + *i + "':");
- tr1::shared_ptr<PackageDepSpec> spec(new PackageDepSpec(i->substr(1), pds_pm_eapi_0));
- spec->set_tag(system_tag);
- system_packages->add(tr1::shared_ptr<SetSpecTree::ConstItem>(new TreeLeaf<SetSpecTree, PackageDepSpec>(spec)));
- }
+ Context context_spec("When parsing '" + *i + "':");
+ tr1::shared_ptr<PackageDepSpec> spec(new PackageDepSpec(i->substr(1), pds_pm_eapi_0));
+ spec->set_tag(system_tag);
+ system_packages->add(tr1::shared_ptr<SetSpecTree::ConstItem>(new TreeLeaf<SetSpecTree, PackageDepSpec>(spec)));
+ }
}
catch (const Exception & e)
{
diff --git a/paludis/repositories/e/ebuild_entries.cc b/paludis/repositories/e/ebuild_entries.cc
index e00b2ab..b929ffd 100644
--- a/paludis/repositories/e/ebuild_entries.cc
+++ b/paludis/repositories/e/ebuild_entries.cc
@@ -281,7 +281,7 @@ EbuildEntries::fetch(const tr1::shared_ptr<const ERepositoryID> & id,
bool fetch_restrict(false);
{
- DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(_imp->params.environment, id);
+ DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(_imp->params.environment, *id);
if (id->restrict_key())
id->restrict_key()->value()->accept(restricts);
@@ -443,7 +443,7 @@ EbuildEntries::install(const tr1::shared_ptr<const ERepositoryID> & id,
bool userpriv_restrict;
{
- DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(_imp->params.environment, id);
+ DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(_imp->params.environment, *id);
if (id->restrict_key())
id->restrict_key()->value()->accept(restricts);
@@ -637,7 +637,7 @@ EbuildEntries::info(const tr1::shared_ptr<const ERepositoryID> & id,
bool userpriv_restrict;
{
- DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(_imp->params.environment, id);
+ DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(_imp->params.environment, *id);
if (id->restrict_key())
id->restrict_key()->value()->accept(restricts);
diff --git a/paludis/repositories/e/qa/extractors.cc b/paludis/repositories/e/qa/extractors.cc
index a4675cf..08dc835 100644
--- a/paludis/repositories/e/qa/extractors.cc
+++ b/paludis/repositories/e/qa/extractors.cc
@@ -125,6 +125,10 @@ namespace
{
}
+ void visit_leaf(const NamedSetDepSpec &)
+ {
+ }
+
using ConstVisitor<GenericSpecTree>::VisitConstSequence<FlagExtractor, AllDepSpec>::visit_sequence;
using ConstVisitor<GenericSpecTree>::VisitConstSequence<FlagExtractor, AnyDepSpec>::visit_sequence;
};
@@ -215,6 +219,10 @@ namespace
{
}
+ void visit_leaf(const NamedSetDepSpec &)
+ {
+ }
+
using ConstVisitor<GenericSpecTree>::VisitConstSequence<Requirements, AllDepSpec>::visit_sequence;
void visit_sequence(const UseDepSpec & u,
diff --git a/paludis/repositories/e/qa/spec_keys.cc b/paludis/repositories/e/qa/spec_keys.cc
index 01f3fe9..555512c 100644
--- a/paludis/repositories/e/qa/spec_keys.cc
+++ b/paludis/repositories/e/qa/spec_keys.cc
@@ -158,6 +158,10 @@ namespace
{
}
+ void visit_leaf(const NamedSetDepSpec &)
+ {
+ }
+
void visit_sequence(const UseDepSpec & u,
GenericSpecTree::ConstSequenceIterator cur,
GenericSpecTree::ConstSequenceIterator end)
diff --git a/paludis/repositories/e/qa/visibility.cc b/paludis/repositories/e/qa/visibility.cc
index db17339..bc139ca 100644
--- a/paludis/repositories/e/qa/visibility.cc
+++ b/paludis/repositories/e/qa/visibility.cc
@@ -96,6 +96,10 @@ namespace
{
}
+ void visit_leaf(const NamedSetDepSpec &)
+ {
+ }
+
void visit_leaf(const PackageDepSpec & orig_p)
{
success = false;
diff --git a/paludis/repositories/e/vdb_repository.cc b/paludis/repositories/e/vdb_repository.cc
index 26edb50..3aaccb8 100644
--- a/paludis/repositories/e/vdb_repository.cc
+++ b/paludis/repositories/e/vdb_repository.cc
@@ -876,7 +876,7 @@ VDBRepository::load_provided_using_cache() const
continue;
}
- DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(_imp->params.environment, id);
+ DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(_imp->params.environment, *id);
tr1::shared_ptr<ProvideSpecTree::ConstItem> pp(parse_provide(
join(next(next(tokens.begin())), tokens.end(), " "), *EAPIData::get_instance()->eapi_from_string("paludis-1")));
pp->accept(f);
@@ -925,7 +925,7 @@ VDBRepository::load_provided_the_slow_way() const
continue;
tr1::shared_ptr<const ProvideSpecTree::ConstItem> provide((*e)->provide_key()->value());;
- DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(_imp->params.environment, *e);
+ DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(_imp->params.environment, **e);
provide->accept(f);
for (DepSpecFlattener<ProvideSpecTree, PackageDepSpec>::ConstIterator
diff --git a/paludis/repositories/fake/fake_installed_repository.cc b/paludis/repositories/fake/fake_installed_repository.cc
index 7a87d69..b6be618 100644
--- a/paludis/repositories/fake/fake_installed_repository.cc
+++ b/paludis/repositories/fake/fake_installed_repository.cc
@@ -87,7 +87,7 @@ FakeInstalledRepository::provided_packages() const
if (! (*v)->provide_key())
continue;
- DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(environment(), *v);
+ DepSpecFlattener<ProvideSpecTree, PackageDepSpec> f(environment(), **v);
(*v)->provide_key()->value()->accept(f);
for (DepSpecFlattener<ProvideSpecTree, PackageDepSpec>::ConstIterator q(f.begin()), q_end(f.end()) ; q != q_end ; ++q)
diff --git a/paludis/set_file.cc b/paludis/set_file.cc
index 6f6aa76..a2dc371 100644
--- a/paludis/set_file.cc
+++ b/paludis/set_file.cc
@@ -272,14 +272,11 @@ SimpleHandler::_create_contents() const
try
{
- if (_p.environment && std::string::npos == i->find('/'))
+ if (std::string::npos == i->find('/'))
{
- tr1::shared_ptr<SetSpecTree::ConstItem> p(_p.environment->set(SetName(*i)));
- if (p)
- _contents->add(p);
- else
- Log::get_instance()->message(ll_warning, lc_context, "Ignoring line '" + stringify(*i) +
- "' because it does not contain a known set name");
+ tr1::shared_ptr<NamedSetDepSpec> p(new NamedSetDepSpec(SetName(*i)));
+ _contents->add(tr1::shared_ptr<TreeLeaf<SetSpecTree, NamedSetDepSpec> >(
+ new TreeLeaf<SetSpecTree, NamedSetDepSpec>(p)));
}
else
{
diff --git a/paludis/set_file_TEST.cc b/paludis/set_file_TEST.cc
index 5f97be2..f4260db 100644
--- a/paludis/set_file_TEST.cc
+++ b/paludis/set_file_TEST.cc
@@ -51,6 +51,11 @@ namespace
s << p << " ";
}
+ void
+ visit_leaf(const NamedSetDepSpec & p)
+ {
+ s << p << " ";
+ }
};
}
diff --git a/paludis/show_suggest_visitor.cc b/paludis/show_suggest_visitor.cc
index 59f9724..6c07606 100644
--- a/paludis/show_suggest_visitor.cc
+++ b/paludis/show_suggest_visitor.cc
@@ -30,6 +30,7 @@
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
+#include <set>
using namespace paludis;
@@ -44,6 +45,7 @@ namespace paludis
const tr1::shared_ptr<const PackageID> id;
bool dependency_tags;
tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > conditions;
+ std::set<SetName> recursing_sets;
Implementation(DepList * const d, tr1::shared_ptr<const DestinationsSet> dd,
const Environment * const e, const tr1::shared_ptr<const PackageID> & p, bool t) :
@@ -137,3 +139,27 @@ ShowSuggestVisitor::visit_leaf(const DependencyLabelsDepSpec &)
// XXX implement
}
+void
+ShowSuggestVisitor::visit_leaf(const NamedSetDepSpec & s)
+{
+ Context context("When expanding named set '" + stringify(s) + "':");
+
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(_imp->environment->set(s.name()));
+
+ if (! set)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Unknown set '" << s.name() << "'";
+ return;
+ }
+
+ if (! _imp->recursing_sets.insert(s.name()).second)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Recursively defined set '" << s.name() << "'";
+ return;
+ }
+
+ set->accept(*this);
+
+ _imp->recursing_sets.erase(s.name());
+}
+
diff --git a/paludis/show_suggest_visitor.hh b/paludis/show_suggest_visitor.hh
index 3c730b2..1efc8da 100644
--- a/paludis/show_suggest_visitor.hh
+++ b/paludis/show_suggest_visitor.hh
@@ -57,6 +57,8 @@ namespace paludis
void visit_leaf(const DependencyLabelsDepSpec &);
+ void visit_leaf(const NamedSetDepSpec &);
+
void visit_sequence(const UseDepSpec &,
DependencySpecTree::ConstSequenceIterator,
DependencySpecTree::ConstSequenceIterator);
diff --git a/paludis/stringify_formatter-impl.hh b/paludis/stringify_formatter-impl.hh
index c42e947..e4fd166 100644
--- a/paludis/stringify_formatter-impl.hh
+++ b/paludis/stringify_formatter-impl.hh
@@ -41,6 +41,7 @@ namespace paludis
const CanFormat<URILabelsDepSpec> * const f_uri_label;
const CanFormat<PlainTextDepSpec> * const f_plain;
const CanFormat<UseDepSpec> * const f_use_dep;
+ const CanFormat<NamedSetDepSpec> * const f_named;
const CanSpace * const f_space;
Implementation(
@@ -56,6 +57,7 @@ namespace paludis
const CanFormat<URILabelsDepSpec> * const f_uri_label_v,
const CanFormat<PlainTextDepSpec> * const f_plain_v,
const CanFormat<UseDepSpec> * const f_use_dep_v,
+ const CanFormat<NamedSetDepSpec> * const f_named_v,
const CanSpace * const f_space_v
) :
f_iuse(f_iuse_v),
@@ -70,6 +72,7 @@ namespace paludis
f_uri_label(f_uri_label_v),
f_plain(f_plain_v),
f_use_dep(f_use_dep_v),
+ f_named(f_named_v),
f_space(f_space_v)
{
}
@@ -138,6 +141,7 @@ namespace paludis
tr1::is_convertible<T_ *, CanFormat<PlainTextDepSpec> *>::value,
PlainTextDepSpec>::get(&t),
StringifyFormatterGetForwarder<tr1::is_convertible<T_ *, CanFormat<UseDepSpec> *>::value, UseDepSpec>::get(&t),
+ StringifyFormatterGetForwarder<tr1::is_convertible<T_ *, CanFormat<NamedSetDepSpec> *>::value, NamedSetDepSpec>::get(&t),
StringifyFormatterGetSpaceForwarder<tr1::is_convertible<T_ *, CanSpace *>::value>::get(&t)
))
{
diff --git a/paludis/stringify_formatter.cc b/paludis/stringify_formatter.cc
index 2fd6585..8eb4d8f 100644
--- a/paludis/stringify_formatter.cc
+++ b/paludis/stringify_formatter.cc
@@ -27,7 +27,8 @@
using namespace paludis;
StringifyFormatter::StringifyFormatter() :
- PrivateImplementationPattern<StringifyFormatter>(new Implementation<StringifyFormatter>(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
+ PrivateImplementationPattern<StringifyFormatter>(new Implementation<StringifyFormatter>(
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
{
}
@@ -292,6 +293,14 @@ StringifyFormatter::format(const UseDepSpec & s, const format::Plain & k) const
}
std::string
+StringifyFormatter::format(const NamedSetDepSpec & s, const format::Plain & k) const
+{
+ if (_imp->f_named)
+ return _imp->f_named->format(s, k);
+ return stringify(s);
+}
+
+std::string
StringifyFormatter::newline() const
{
if (_imp->f_space)
diff --git a/paludis/stringify_formatter.hh b/paludis/stringify_formatter.hh
index 3b5fae7..7f231e2 100644
--- a/paludis/stringify_formatter.hh
+++ b/paludis/stringify_formatter.hh
@@ -42,6 +42,7 @@ namespace paludis
public CanFormat<PlainTextDepSpec>,
public CanFormat<LicenseDepSpec>,
public CanFormat<UseDepSpec>,
+ public CanFormat<NamedSetDepSpec>,
public CanSpace
{
private:
@@ -84,6 +85,8 @@ namespace paludis
virtual std::string format(const DependencyLabelsDepSpec &, const format::Plain &) const;
+ virtual std::string format(const NamedSetDepSpec &, const format::Plain &) const;
+
virtual std::string format(const URILabelsDepSpec &, const format::Plain &) const;
virtual std::string format(const PlainTextDepSpec &, const format::Plain &) const;
diff --git a/paludis/uninstall_list.cc b/paludis/uninstall_list.cc
index 442ea8a..d2b97a7 100644
--- a/paludis/uninstall_list.cc
+++ b/paludis/uninstall_list.cc
@@ -40,6 +40,7 @@
#include <libwrapiter/libwrapiter_output_iterator.hh>
#include <list>
#include <algorithm>
+#include <set>
using namespace paludis;
@@ -256,7 +257,7 @@ namespace
const tr1::shared_ptr<const PackageID> pkg;
tr1::shared_ptr<DepListEntryTags> matches;
tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > conditions;
-
+ std::set<SetName> recursing_sets;
DepCollector(const Environment * const ee, const tr1::shared_ptr<const PackageID> & e) :
env(ee),
@@ -308,6 +309,29 @@ namespace
void visit_leaf(const DependencyLabelsDepSpec &)
{
}
+
+ void visit_leaf(const NamedSetDepSpec & s)
+ {
+ Context context("When expanding named set '" + stringify(s) + "':");
+
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(env->set(s.name()));
+
+ if (! set)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Unknown set '" << s.name() << "'";
+ return;
+ }
+
+ if (! recursing_sets.insert(s.name()).second)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Recursively defined set '" << s.name() << "'";
+ return;
+ }
+
+ set->accept(*this);
+
+ recursing_sets.erase(s.name());
+ }
};
}
diff --git a/paludis/uninstall_task.cc b/paludis/uninstall_task.cc
index d47877f..0dcfc00 100644
--- a/paludis/uninstall_task.cc
+++ b/paludis/uninstall_task.cc
@@ -175,7 +175,7 @@ UninstallTask::add_target(const std::string & target)
throw MultipleSetTargetsSpecified();
_imp->had_set_targets = true;
- DepSpecFlattener<SetSpecTree, PackageDepSpec> f(_imp->env, tr1::shared_ptr<const PackageID>());
+ DepSpecFlattener<SetSpecTree, PackageDepSpec> f(_imp->env);
spec->accept(f);
std::copy(f.begin(), f.end(), std::back_inserter(_imp->targets));
}
@@ -425,43 +425,39 @@ namespace
{
using ConstVisitor<SetSpecTree>::VisitConstSequence<WorldTargetFinder, AllDepSpec>::visit_sequence;
+ Environment * const env;
UninstallTask * const task;
- std::list<const PackageDepSpec *> items;
- bool inside_any;
- bool inside_use;
-
- WorldTargetFinder(UninstallTask * const t) :
- task(t),
- inside_any(false),
- inside_use(false)
+
+ WorldTargetFinder(Environment * const e, UninstallTask * const t) :
+ env(e),
+ task(t)
{
}
void visit_leaf(const PackageDepSpec & a)
{
- if (! (inside_any || inside_use || a.slot_ptr() ||
- (a.version_requirements_ptr() && ! a.version_requirements_ptr()->empty())))
+ if (! (a.slot_ptr() || (a.version_requirements_ptr() && ! a.version_requirements_ptr()->empty())))
{
- items.push_back(&a);
+ for (PackageDatabase::RepositoryConstIterator r(env->package_database()->begin_repositories()),
+ r_end(env->package_database()->end_repositories()) ;
+ r != r_end ; ++r)
+ if ((*r)->world_interface && a.package_ptr())
+ (*r)->world_interface->remove_from_world(*a.package_ptr());
+
task->on_update_world(a);
}
}
+
+ void visit_leaf(const NamedSetDepSpec &)
+ {
+ }
};
}
void
UninstallTask::world_remove_packages(tr1::shared_ptr<const SetSpecTree::ConstItem> a)
{
- WorldTargetFinder w(this);
+ WorldTargetFinder w(_imp->env, this);
a->accept(w);
- for (std::list<const PackageDepSpec *>::const_iterator i(w.items.begin()),
- i_end(w.items.end()) ; i != i_end ; ++i)
- {
- for (PackageDatabase::RepositoryConstIterator r(_imp->env->package_database()->begin_repositories()),
- r_end(_imp->env->package_database()->end_repositories()) ;
- r != r_end ; ++r)
- if ((*r)->world_interface && (*i)->package_ptr())
- (*r)->world_interface->remove_from_world(*(*i)->package_ptr());
- }
}
diff --git a/paludis/util/visitor.hh b/paludis/util/visitor.hh
index 3d90978..587bcf3 100644
--- a/paludis/util/visitor.hh
+++ b/paludis/util/visitor.hh
@@ -1138,6 +1138,43 @@ namespace paludis
///\}
};
+ /**
+ * Query whether we contain a particular type.
+ *
+ * \ingroup grpvisitor
+ * \nosubgrouping
+ */
+ template <typename A_>
+ struct Contains
+ {
+ /**
+ * Do we contain the queried type?
+ */
+ enum {
+ value =
+ (tr1::is_same<const A_, const typename H_::ContainedItem1>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem2>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem3>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem4>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem5>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem6>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem7>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem8>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem9>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem10>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem11>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem12>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem13>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem14>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem15>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem16>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem17>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem18>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem19>::value ? 1 : 0) |
+ (tr1::is_same<const A_, const typename H_::ContainedItem20>::value ? 1 : 0)
+ };
+ };
+
///\}
};
@@ -1199,6 +1236,43 @@ namespace paludis
///\}
};
+ /**
+ * Query whether we contain a particular type.
+ *
+ * \ingroup grpvisitor
+ * \nosubgrouping
+ */
+ template <typename A_>
+ struct Contains
+ {
+ /**
+ * Do we contain the queried type?
+ */
+ enum {
+ value =
+ (tr1::is_same<A_, typename H_::ContainedItem1>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem2>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem3>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem4>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem5>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem6>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem7>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem8>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem9>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem10>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem11>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem12>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem13>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem14>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem15>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem16>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem17>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem18>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem19>::value ? 1 : 0) |
+ (tr1::is_same<A_, typename H_::ContainedItem20>::value ? 1 : 0)
+ };
+ };
+
///\}
};
diff --git a/paludis/util/visitor_TEST.cc b/paludis/util/visitor_TEST.cc
index 69f1edb..42ba177 100644
--- a/paludis/util/visitor_TEST.cc
+++ b/paludis/util/visitor_TEST.cc
@@ -21,6 +21,7 @@
#include <paludis/util/iterator.hh>
#include <paludis/util/visitor.hh>
#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/no_type.hh>
#include <test/test_framework.hh>
#include <test/test_runner.hh>
#include <algorithm>
@@ -139,6 +140,9 @@ namespace test_cases
TEST_CHECK_EQUAL(c.r, "");
std::for_each(indirect_iterator(v.begin()), indirect_iterator(v.end()), accept_visitor(c));
TEST_CHECK_EQUAL(c.r, "c_fooc_barc_foo");
+
+ TEST_CHECK((ConstVisitor<NodeVisitorTypes>::Contains<const TreeLeaf<NodeVisitorTypes, FooNode> >::value));
+ TEST_CHECK((! ConstVisitor<NodeVisitorTypes>::Contains<const TreeLeaf<NodeVisitorTypes, NoType<12345u> > >::value));
}
} test_const_visitor;
@@ -165,6 +169,9 @@ namespace test_cases
TEST_CHECK_EQUAL(c.r, "");
std::for_each(indirect_iterator(v.begin()), indirect_iterator(v.end()), accept_visitor(c));
TEST_CHECK_EQUAL(c.r, "foobarfoo");
+
+ TEST_CHECK((ConstVisitor<NodeVisitorTypes>::Contains<TreeLeaf<NodeVisitorTypes, FooNode> >::value));
+ TEST_CHECK((! ConstVisitor<NodeVisitorTypes>::Contains<TreeLeaf<NodeVisitorTypes, NoType<12345u> > >::value));
}
} test_visitor;
}
diff --git a/python/dep_spec.cc b/python/dep_spec.cc
index 54abcce..6d9e3d9 100644
--- a/python/dep_spec.cc
+++ b/python/dep_spec.cc
@@ -51,6 +51,7 @@ template class ConstAcceptInterfaceVisitsThis<PythonDepSpecVisitorTypes, PythonF
template class ConstAcceptInterfaceVisitsThis<PythonDepSpecVisitorTypes, PythonLicenseDepSpec>;
template class ConstAcceptInterfaceVisitsThis<PythonDepSpecVisitorTypes, PythonURILabelsDepSpec>;
template class ConstAcceptInterfaceVisitsThis<PythonDepSpecVisitorTypes, PythonDependencyLabelsDepSpec>;
+template class ConstAcceptInterfaceVisitsThis<PythonDepSpecVisitorTypes, PythonNamedSetDepSpec>;
template class Visits<const PythonAllDepSpec>;
template class Visits<const PythonAnyDepSpec>;
@@ -63,6 +64,7 @@ template class Visits<const PythonFetchableURIDepSpec>;
template class Visits<const PythonLicenseDepSpec>;
template class Visits<const PythonURILabelsDepSpec>;
template class Visits<const PythonDependencyLabelsDepSpec>;
+template class Visits<const PythonNamedSetDepSpec>;
PythonDepSpec::PythonDepSpec()
{
@@ -402,6 +404,24 @@ PythonPlainTextDepSpec::PythonPlainTextDepSpec(const PlainTextDepSpec & d) :
{
}
+PythonNamedSetDepSpec::PythonNamedSetDepSpec(const SetName & s) :
+ PythonStringDepSpec(stringify(s)),
+ _name(s)
+{
+}
+
+const SetName
+PythonNamedSetDepSpec::name() const
+{
+ return _name;
+}
+
+PythonNamedSetDepSpec::PythonNamedSetDepSpec(const NamedSetDepSpec & d) :
+ PythonStringDepSpec(d.text()),
+ _name(d.name())
+{
+}
+
PythonLicenseDepSpec::PythonLicenseDepSpec(const std::string & s) :
PythonStringDepSpec(s)
{
@@ -541,6 +561,12 @@ SpecTreeToPython::visit_leaf(const PlainTextDepSpec & d)
}
void
+SpecTreeToPython::visit_leaf(const NamedSetDepSpec & d)
+{
+ _current_parent->add_child(tr1::shared_ptr<PythonNamedSetDepSpec>(new PythonNamedSetDepSpec(d)));
+}
+
+void
SpecTreeToPython::visit_leaf(const LicenseDepSpec & d)
{
_current_parent->add_child(tr1::shared_ptr<PythonLicenseDepSpec>(new PythonLicenseDepSpec(d)));
@@ -658,6 +684,7 @@ struct AllowedTypes<DependencySpecTree>
AllowedTypes(const PackageDepSpec &) {};
AllowedTypes(const BlockDepSpec &) {};
AllowedTypes(const DependencyLabelsDepSpec &) {};
+ AllowedTypes(const NamedSetDepSpec &) {};
};
template<>
@@ -665,6 +692,7 @@ struct AllowedTypes<SetSpecTree>
{
AllowedTypes(const AllDepSpec &) {};
AllowedTypes(const PackageDepSpec &) {};
+ AllowedTypes(const NamedSetDepSpec &) {};
};
@@ -714,6 +742,13 @@ struct NiceClassNames<PlainTextDepSpec>
const char * NiceClassNames<PlainTextDepSpec>::name = "PlainTextDepSpec";
template<>
+struct NiceClassNames<NamedSetDepSpec>
+{
+ static const char * name;
+};
+const char * NiceClassNames<NamedSetDepSpec>::name = "NamedSetDepSpec";
+
+template<>
struct NiceClassNames<LicenseDepSpec>
{
static const char * name;
@@ -924,6 +959,13 @@ SpecTreeFromPython<H_>::visit(const PythonPlainTextDepSpec & d)
template <typename H_>
void
+SpecTreeFromPython<H_>::visit(const PythonNamedSetDepSpec & d)
+{
+ dispatch<H_, NamedSetDepSpec>(this, d);
+}
+
+template <typename H_>
+void
SpecTreeFromPython<H_>::visit(const PythonFetchableURIDepSpec & d)
{
dispatch<H_, FetchableURIDepSpec>(this, d);
@@ -1037,6 +1079,15 @@ SpecTreeFromPython<H_>::real_visit(const PythonPlainTextDepSpec & d)
template <typename H_>
void
+SpecTreeFromPython<H_>::real_visit(const PythonNamedSetDepSpec & d)
+{
+ _add(tr1::shared_ptr<TreeLeaf<H_, NamedSetDepSpec> >(
+ new TreeLeaf<H_, NamedSetDepSpec>(tr1::shared_ptr<NamedSetDepSpec>(
+ new NamedSetDepSpec(d.name())))));
+}
+
+template <typename H_>
+void
SpecTreeFromPython<H_>::real_visit(const PythonFetchableURIDepSpec & d)
{
_add(tr1::shared_ptr<TreeLeaf<H_, FetchableURIDepSpec> >(
@@ -1465,6 +1516,21 @@ void expose_dep_spec()
;
/**
+ * NamedSetDepSpec
+ */
+ bp::class_<PythonNamedSetDepSpec, bp::bases<PythonStringDepSpec>, boost::noncopyable>
+ (
+ "NamedSetDepSpec",
+ "A NamedSetDepSpec represents a named package set.",
+ bp::init<const SetName &>("__init__(SetName)")
+ )
+ .def("__str__", &PythonNamedSetDepSpec::text)
+ .add_property("name", &PythonNamedSetDepSpec::name,
+ "[ro] SetName"
+ )
+ ;
+
+ /**
* LicenseDepSpec
*/
bp::class_<PythonLicenseDepSpec, bp::bases<PythonStringDepSpec>, boost::noncopyable>
diff --git a/python/dep_spec.hh b/python/dep_spec.hh
index d529b46..23e9aa3 100644
--- a/python/dep_spec.hh
+++ b/python/dep_spec.hh
@@ -42,6 +42,7 @@ namespace paludis
class PythonBlockDepSpec;
class PythonURILabelsDepSpec;
class PythonDependencyLabelsDepSpec;
+ class PythonNamedSetDepSpec;
struct PythonDepSpecVisitorTypes :
VisitorTypes<
@@ -57,7 +58,8 @@ namespace paludis
PythonFetchableURIDepSpec,
PythonSimpleURIDepSpec,
PythonURILabelsDepSpec,
- PythonDependencyLabelsDepSpec
+ PythonDependencyLabelsDepSpec,
+ PythonNamedSetDepSpec
>
{
};
@@ -192,6 +194,20 @@ namespace paludis
PythonPlainTextDepSpec(const PlainTextDepSpec &);
};
+ class PALUDIS_VISIBLE PythonNamedSetDepSpec :
+ public PythonStringDepSpec,
+ public ConstAcceptInterfaceVisitsThis<PythonDepSpecVisitorTypes, PythonNamedSetDepSpec>
+ {
+ private:
+ const SetName _name;
+
+ public:
+ PythonNamedSetDepSpec(const SetName &);
+ PythonNamedSetDepSpec(const NamedSetDepSpec &);
+
+ const SetName name() const;
+ };
+
class PALUDIS_VISIBLE PythonSimpleURIDepSpec :
public PythonStringDepSpec,
public ConstAcceptInterfaceVisitsThis<PythonDepSpecVisitorTypes, PythonSimpleURIDepSpec>
@@ -298,6 +314,8 @@ namespace paludis
void visit_leaf(const URILabelsDepSpec &);
void visit_leaf(const DependencyLabelsDepSpec &);
+
+ void visit_leaf(const NamedSetDepSpec &);
};
/**
@@ -330,6 +348,7 @@ namespace paludis
void visit(const PythonLicenseDepSpec &);
void visit(const PythonURILabelsDepSpec &);
void visit(const PythonDependencyLabelsDepSpec &);
+ void visit(const PythonNamedSetDepSpec &);
void real_visit(const PythonAllDepSpec &);
void real_visit(const PythonAnyDepSpec &);
@@ -342,6 +361,7 @@ namespace paludis
void real_visit(const PythonURILabelsDepSpec &);
void real_visit(const PythonDependencyLabelsDepSpec &);
void real_visit(const PythonLicenseDepSpec &);
+ void real_visit(const PythonNamedSetDepSpec &);
};
}
}
diff --git a/python/dep_spec_TEST.py b/python/dep_spec_TEST.py
index 053cbe5..dc0f800 100755
--- a/python/dep_spec_TEST.py
+++ b/python/dep_spec_TEST.py
@@ -26,6 +26,7 @@ class TestCase_1_DepSpecs(unittest.TestCase):
self.ptds = PlainTextDepSpec("foo")
self.pds = PackageDepSpec(">=foo/bar-1:100::testrepo", PackageDepSpecParseMode.PERMISSIVE)
self.bds = BlockDepSpec(self.pds)
+ self.nds = NamedSetDepSpec("system")
def test_01_init(self):
self.get_depspecs()
@@ -41,6 +42,7 @@ class TestCase_1_DepSpecs(unittest.TestCase):
self.assertEqual(str(self.ptds), "foo")
self.assertEqual(str(self.pds), ">=foo/bar-1:100::testrepo")
self.assertEqual(str(self.bds.blocked_spec), ">=foo/bar-1:100::testrepo")
+ self.assertEqual(str(self.nds), "system")
def test_04_slot(self):
self.get_depspecs()
@@ -78,6 +80,10 @@ class TestCase_1_DepSpecs(unittest.TestCase):
self.assertEquals(pds.use_requirements, None)
self.assertEquals(str(pds), "foo/monkey")
+ def test_11_name(self):
+ self.get_depspecs()
+ self.assertEqual(str(self.nds.text), "system")
+
### def test_11_composites(self):
### eapi = EAPIData.instance.eapi_from_string("0")
### spec = PortageDepParser.parse_depend("|| ( foo/bar foo/baz ) foo/monkey", eapi)
diff --git a/src/clients/adjutrix/find_insecure_packages.cc b/src/clients/adjutrix/find_insecure_packages.cc
index c191367..02b1e8b 100644
--- a/src/clients/adjutrix/find_insecure_packages.cc
+++ b/src/clients/adjutrix/find_insecure_packages.cc
@@ -71,6 +71,7 @@ namespace
private:
const Environment & _env;
std::multimap<tr1::shared_ptr<const PackageID>, std::string, PackageIDSetComparator> _found;
+ std::set<SetName> recursing_sets;
public:
using ConstVisitor<SetSpecTree>::VisitConstSequence<ListInsecureVisitor, AllDepSpec>::visit;
@@ -92,6 +93,29 @@ namespace
throw InternalError(PALUDIS_HERE, "didn't get a tag");
}
+ void visit_leaf(const NamedSetDepSpec & s)
+ {
+ Context context("When expanding named set '" + stringify(s) + "':");
+
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(_env.set(s.name()));
+
+ if (! set)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Unknown set '" << s.name() << "'";
+ return;
+ }
+
+ if (! recursing_sets.insert(s.name()).second)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Recursively defined set '" << s.name() << "'";
+ return;
+ }
+
+ set->accept(*this);
+
+ recursing_sets.erase(s.name());
+ }
+
friend std::ostream & operator<< (std::ostream &, const ListInsecureVisitor &);
};
diff --git a/src/clients/adjutrix/find_reverse_deps.cc b/src/clients/adjutrix/find_reverse_deps.cc
index ffb7ed1..ae66ec2 100644
--- a/src/clients/adjutrix/find_reverse_deps.cc
+++ b/src/clients/adjutrix/find_reverse_deps.cc
@@ -52,7 +52,7 @@ namespace
public ConstVisitor<DependencySpecTree>::VisitConstSequence<ReverseDepChecker, AllDepSpec>
{
private:
- tr1::shared_ptr<const PackageDatabase> _db;
+ const Environment * const _env;
const PackageIDSequence & _entries;
std::string _depname;
std::string _p;
@@ -63,13 +63,15 @@ namespace
bool _found_matches;
+ std::set<SetName> _recursing_sets;
+
public:
using ConstVisitor<DependencySpecTree>::VisitConstSequence<ReverseDepChecker, AllDepSpec>::visit_sequence;
- ReverseDepChecker(tr1::shared_ptr<const PackageDatabase> db,
+ ReverseDepChecker(const Environment * const e,
const PackageIDSequence & entries,
const std::string & p) :
- _db(db),
+ _env(e),
_entries(entries),
_depname(""),
_p(p),
@@ -107,6 +109,29 @@ namespace
void visit_leaf(const DependencyLabelsDepSpec &)
{
}
+
+ void visit_leaf(const NamedSetDepSpec & s)
+ {
+ Context context("When expanding named set '" + stringify(s) + "':");
+
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(_env->set(s.name()));
+
+ if (! set)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Unknown set '" << s.name() << "'";
+ return;
+ }
+
+ if (! _recursing_sets.insert(s.name()).second)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Recursively defined set '" << s.name() << "'";
+ return;
+ }
+
+ set->accept(*this);
+
+ _recursing_sets.erase(s.name());
+ }
};
void
@@ -136,7 +161,7 @@ namespace
void
ReverseDepChecker::visit_leaf(const PackageDepSpec & a)
{
- tr1::shared_ptr<const PackageIDSequence> dep_entries(_db->query(
+ tr1::shared_ptr<const PackageIDSequence> dep_entries(_env->package_database()->query(
query::Matches(a), qo_order_by_version));
tr1::shared_ptr<PackageIDSequence> matches(new PackageIDSequence);
@@ -197,7 +222,7 @@ namespace
{
try
{
- ReverseDepChecker checker(env.package_database(), entries, stringify(p) + "-" + stringify(e->canonical_form(idcf_version)));
+ ReverseDepChecker checker(&env, entries, stringify(p) + "-" + stringify(e->canonical_form(idcf_version)));
if (e->build_dependencies_key())
checker.check(e->build_dependencies_key()->value(), e->build_dependencies_key()->raw_name());
diff --git a/src/clients/gtkpaludis/libgtkpaludis/markup_formatter.cc b/src/clients/gtkpaludis/libgtkpaludis/markup_formatter.cc
index 456e1cb..1bf6d88 100644
--- a/src/clients/gtkpaludis/libgtkpaludis/markup_formatter.cc
+++ b/src/clients/gtkpaludis/libgtkpaludis/markup_formatter.cc
@@ -191,6 +191,12 @@ MarkupFormatter::format(const DependencyLabelsDepSpec & f, const format::Plain &
}
std::string
+MarkupFormatter::format(const NamedSetDepSpec & f, const format::Plain &) const
+{
+ return markup_escape(stringify(f));
+}
+
+std::string
MarkupFormatter::format(const FetchableURIDepSpec & f, const format::Plain &) const
{
return markup_escape(stringify(f));
diff --git a/src/clients/gtkpaludis/libgtkpaludis/markup_formatter.hh b/src/clients/gtkpaludis/libgtkpaludis/markup_formatter.hh
index ba438db..57cfc6b 100644
--- a/src/clients/gtkpaludis/libgtkpaludis/markup_formatter.hh
+++ b/src/clients/gtkpaludis/libgtkpaludis/markup_formatter.hh
@@ -22,6 +22,7 @@ namespace gtkpaludis
public paludis::CanFormat<paludis::SimpleURIDepSpec>,
public paludis::CanFormat<paludis::FetchableURIDepSpec>,
public paludis::CanFormat<paludis::LicenseDepSpec>,
+ public paludis::CanFormat<paludis::NamedSetDepSpec>,
public paludis::CanFormat<paludis::tr1::shared_ptr<const paludis::PackageID> >,
public paludis::CanFormat<std::string>,
public paludis::CanSpace
@@ -67,6 +68,8 @@ namespace gtkpaludis
std::string format(const paludis::DependencyLabelsDepSpec &, const paludis::format::Plain &) const;
+ std::string format(const paludis::NamedSetDepSpec &, const paludis::format::Plain &) const;
+
std::string format(const paludis::SimpleURIDepSpec &, const paludis::format::Plain &) const;
std::string format(const paludis::FetchableURIDepSpec &, const paludis::format::Plain &) const;
diff --git a/src/clients/gtkpaludis/libgtkpaludis/packages_list_model.cc b/src/clients/gtkpaludis/libgtkpaludis/packages_list_model.cc
index 52e72df..05392f8 100644
--- a/src/clients/gtkpaludis/libgtkpaludis/packages_list_model.cc
+++ b/src/clients/gtkpaludis/libgtkpaludis/packages_list_model.cc
@@ -253,7 +253,7 @@ PackagesListModel::populate_in_paludis_thread()
}
else if (_imp->packages_page->get_set())
{
- DepSpecFlattener<SetSpecTree, PackageDepSpec> f(_imp->main_window->environment(), tr1::shared_ptr<const PackageID>());
+ DepSpecFlattener<SetSpecTree, PackageDepSpec> f(_imp->main_window->environment());
_imp->main_window->environment()->set(*_imp->packages_page->get_set())->accept(f);
std::set<std::string> a;
std::transform(indirect_iterator(f.begin()), indirect_iterator(f.end()), std::inserter(a, a.begin()),
diff --git a/src/clients/paludis/query.cc b/src/clients/paludis/query.cc
index 159c866..1b47a1b 100644
--- a/src/clients/paludis/query.cc
+++ b/src/clients/paludis/query.cc
@@ -83,6 +83,11 @@ namespace
stream << " " << d << std::endl;
}
+ void visit_leaf(const NamedSetDepSpec & d)
+ {
+ stream << " " << d << std::endl;
+ }
+
void visit_sequence(const AllDepSpec &,
SetSpecTree::ConstSequenceIterator cur,
SetSpecTree::ConstSequenceIterator end)
diff --git a/src/output/colour_formatter.cc b/src/output/colour_formatter.cc
index 0af5c3c..52d3793 100644
--- a/src/output/colour_formatter.cc
+++ b/src/output/colour_formatter.cc
@@ -343,6 +343,12 @@ ColourFormatter::format(const URILabelsDepSpec & f, const format::Plain &) const
}
std::string
+ColourFormatter::format(const NamedSetDepSpec & f, const format::Plain &) const
+{
+ return stringify(f);
+}
+
+std::string
ColourFormatter::format(const DependencyLabelsDepSpec & f, const format::Plain &) const
{
return stringify(f);
diff --git a/src/output/colour_formatter.hh b/src/output/colour_formatter.hh
index 9ff1b8f..b9e3e53 100644
--- a/src/output/colour_formatter.hh
+++ b/src/output/colour_formatter.hh
@@ -38,6 +38,7 @@ class ColourFormatter :
public paludis::CanFormat<paludis::SimpleURIDepSpec>,
public paludis::CanFormat<paludis::FetchableURIDepSpec>,
public paludis::CanFormat<paludis::LicenseDepSpec>,
+ public paludis::CanFormat<paludis::NamedSetDepSpec>,
public paludis::CanFormat<paludis::tr1::shared_ptr<const paludis::PackageID> >,
public paludis::CanFormat<std::string>,
public paludis::CanSpace,
@@ -96,6 +97,8 @@ class ColourFormatter :
std::string format(const paludis::SimpleURIDepSpec &, const paludis::format::Plain &) const;
+ std::string format(const paludis::NamedSetDepSpec &, const paludis::format::Plain &) const;
+
std::string format(const paludis::BlockDepSpec &, const paludis::format::Plain &) const;
std::string format(const paludis::tr1::shared_ptr<const paludis::PackageID> &, const paludis::format::Plain &) const;
diff --git a/src/output/console_query_task.cc b/src/output/console_query_task.cc
index 5939e0a..4fb6953 100644
--- a/src/output/console_query_task.cc
+++ b/src/output/console_query_task.cc
@@ -651,6 +651,11 @@ namespace
empty = false;
}
+ void visit_leaf(const NamedSetDepSpec &)
+ {
+ empty = false;
+ }
+
void visit_leaf(const URILabelsDepSpec &)
{
}