/* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* * Copyright (c) 2008, 2009, 2010, 2011 Ciaran McCreesh * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace paludis; namespace paludis { template <> struct Imp { std::shared_ptr handler; Imp(const std::shared_ptr & h) : handler(h) { } }; } Filter::Filter(const std::shared_ptr & h) : _imp(h) { } Filter::Filter(const Filter & other) : _imp(other._imp->handler) { } Filter & Filter::operator= (const Filter & other) { if (this != &other) _imp->handler = other._imp->handler; return *this; } Filter::~Filter() { } std::shared_ptr Filter::repositories( const Environment * const env, const std::shared_ptr & r) const { return _imp->handler->repositories(env, r); } std::shared_ptr Filter::categories( const Environment * const env, const std::shared_ptr & r, const std::shared_ptr & c) const { return _imp->handler->categories(env, r, c); } std::shared_ptr Filter::packages( const Environment * const env, const std::shared_ptr & r, const std::shared_ptr & c) const { return _imp->handler->packages(env, r, c); } std::shared_ptr Filter::ids( const Environment * const env, const std::shared_ptr & i) const { return _imp->handler->ids(env, i); } const RepositoryContentMayExcludes Filter::may_excludes() const { return _imp->handler->may_excludes(); } std::string Filter::as_string() const { return _imp->handler->as_string(); } namespace { struct AllFilterHandler : AllFilterHandlerBase { virtual std::string as_string() const { return "all matches"; } }; template struct SupportsActionFilterHandler : AllFilterHandlerBase { virtual std::shared_ptr repositories( const Environment * const env, const std::shared_ptr & repos) const { std::shared_ptr result(std::make_shared()); for (RepositoryNameSet::ConstIterator r(repos->begin()), r_end(repos->end()) ; r != r_end ; ++r) { if (env->fetch_repository(*r)->some_ids_might_support_action(SupportsActionTest())) result->insert(*r); } return result; } virtual std::shared_ptr ids( const Environment * const, const std::shared_ptr & id) const { std::shared_ptr result(std::make_shared()); for (PackageIDSet::ConstIterator i(id->begin()), i_end(id->end()) ; i != i_end ; ++i) { if ((*i)->supports_action(SupportsActionTest())) result->insert(*i); } return result; } virtual std::string as_string() const { return "supports action " + stringify(ActionNames::value); } }; struct NotMaskedFilterHandler : AllFilterHandlerBase { virtual const RepositoryContentMayExcludes may_excludes() const { return { rcme_masked }; } virtual std::shared_ptr repositories( const Environment * const env, const std::shared_ptr & repos) const { std::shared_ptr result(std::make_shared()); for (RepositoryNameSet::ConstIterator r(repos->begin()), r_end(repos->end()) ; r != r_end ; ++r) { if (env->fetch_repository(*r)->some_ids_might_not_be_masked()) result->insert(*r); } return result; } virtual std::shared_ptr ids( const Environment * const, const std::shared_ptr & id) const { std::shared_ptr result(std::make_shared()); for (PackageIDSet::ConstIterator i(id->begin()), i_end(id->end()) ; i != i_end ; ++i) if (! (*i)->masked()) result->insert(*i); return result; } virtual std::string as_string() const { return "not masked"; } }; struct InstalledAtFilterHandler : AllFilterHandlerBase { const FSPath root; const bool equal; InstalledAtFilterHandler(const FSPath & r, const bool e) : root(r), equal(e) { } virtual const RepositoryContentMayExcludes may_excludes() const { return { rcme_not_installed }; } virtual std::shared_ptr repositories( const Environment * const env, const std::shared_ptr & repos) const { std::shared_ptr result(std::make_shared()); for (RepositoryNameSet::ConstIterator r(repos->begin()), r_end(repos->end()) ; r != r_end ; ++r) { const std::shared_ptr repo(env->fetch_repository(*r)); if (repo->installed_root_key() && (equal == (root == repo->installed_root_key()->parse_value()))) result->insert(*r); } return result; } virtual std::shared_ptr ids( const Environment * const, const std::shared_ptr & id) const { std::shared_ptr result(std::make_shared()); for (PackageIDSet::ConstIterator i(id->begin()), i_end(id->end()) ; i != i_end ; ++i) result->insert(*i); return result; } virtual std::string as_string() const { return "installed " + std::string(equal ? "" : "not ") + "at root " + stringify(root); } }; struct AndFilterHandler : FilterHandler { const Filter f1; const Filter f2; AndFilterHandler(const Filter & a1, const Filter & a2) : f1(a1), f2(a2) { } virtual const RepositoryContentMayExcludes may_excludes() const { /* we can exclude anything either filter would reject */ return f1.may_excludes() | f2.may_excludes(); } virtual std::shared_ptr repositories( const Environment * const env, const std::shared_ptr & s) const { return f2.repositories(env, f1.repositories(env, s)); } virtual std::shared_ptr categories( const Environment * const env, const std::shared_ptr & r, const std::shared_ptr & c) const { return f2.categories(env, r, f1.categories(env, r, c)); } virtual std::shared_ptr packages( const Environment * const env, const std::shared_ptr & r, const std::shared_ptr & q) const { return f2.packages(env, r, f1.packages(env, r, q)); } virtual std::shared_ptr ids( const Environment * const env, const std::shared_ptr & s) const { return f2.ids(env, f1.ids(env, s)); } virtual std::string as_string() const { return stringify(f1) + " filtered through " + stringify(f2); } }; struct SameSlotHandler : AllFilterHandlerBase { const std::shared_ptr as_id; SameSlotHandler(const std::shared_ptr & i) : as_id(i) { } virtual const RepositoryContentMayExcludes may_excludes() const { return { }; } virtual std::shared_ptr ids( const Environment * const, const std::shared_ptr & id) const { std::shared_ptr result(std::make_shared()); for (PackageIDSet::ConstIterator i(id->begin()), i_end(id->end()) ; i != i_end ; ++i) if (as_id->slot_key()) { if ((*i)->slot_key() && (*i)->slot_key()->parse_value() == as_id->slot_key()->parse_value()) result->insert(*i); } else { if (! (*i)->slot_key()) result->insert(*i); } return result; } virtual std::string as_string() const { return "same slot as " + stringify(*as_id); } }; struct SlotHandler : AllFilterHandlerBase { const SlotName slot; SlotHandler(const SlotName & s) : slot(s) { } virtual const RepositoryContentMayExcludes may_excludes() const { return { }; } virtual std::shared_ptr ids( const Environment * const, const std::shared_ptr & id) const { std::shared_ptr result(std::make_shared()); for (PackageIDSet::ConstIterator i(id->begin()), i_end(id->end()) ; i != i_end ; ++i) if ((*i)->slot_key() && (*i)->slot_key()->parse_value() == slot) result->insert(*i); return result; } virtual std::string as_string() const { return "slot is " + stringify(slot); } }; struct NoSlotHandler : AllFilterHandlerBase { virtual std::shared_ptr ids( const Environment * const, const std::shared_ptr & id) const { std::shared_ptr result(std::make_shared()); for (PackageIDSet::ConstIterator i(id->begin()), i_end(id->end()) ; i != i_end ; ++i) if (! (*i)->slot_key()) result->insert(*i); return result; } virtual const RepositoryContentMayExcludes may_excludes() const { return { }; } virtual std::string as_string() const { return "has no slot"; } }; struct MatchesHandler : AllFilterHandlerBase { const PackageDepSpec spec; const std::shared_ptr from_id; const MatchPackageOptions options; MatchesHandler(const PackageDepSpec & s, const std::shared_ptr & f, const MatchPackageOptions & o) : spec(s), from_id(f), options(o) { } virtual const RepositoryContentMayExcludes may_excludes() const { return { }; } virtual std::shared_ptr ids( const Environment * const env, const std::shared_ptr & id) const { std::shared_ptr result(std::make_shared()); for (PackageIDSet::ConstIterator i(id->begin()), i_end(id->end()) ; i != i_end ; ++i) { if (match_package(*env, spec, *i, from_id, options)) result->insert(*i); } return result; } virtual std::string as_string() const { std::string suffix; if (options[mpo_ignore_additional_requirements]) suffix = " (ignoring additional requirements)"; return "packages matching " + stringify(spec) + suffix; } }; } filter::All::All() : Filter(std::make_shared()) { } template filter::SupportsAction::SupportsAction() : Filter(std::make_shared>()) { } filter::NotMasked::NotMasked() : Filter(std::make_shared()) { } filter::InstalledAtRoot::InstalledAtRoot(const FSPath & r) : Filter(std::make_shared(r, true)) { } filter::InstalledNotAtRoot::InstalledNotAtRoot(const FSPath & r) : Filter(std::make_shared(r, false)) { } filter::InstalledAtSlash::InstalledAtSlash() : Filter(std::make_shared(FSPath("/"), true)) { } filter::InstalledAtNotSlash::InstalledAtNotSlash() : Filter(std::make_shared(FSPath("/"), false)) { } filter::And::And(const Filter & f1, const Filter & f2) : Filter(std::make_shared(f1, f2)) { } filter::SameSlot::SameSlot(const std::shared_ptr & i) : Filter(std::make_shared(i)) { } filter::Slot::Slot(const SlotName & s) : Filter(std::make_shared(s)) { } filter::NoSlot::NoSlot() : Filter(std::make_shared()) { } filter::Matches::Matches(const PackageDepSpec & spec, const std::shared_ptr & f, const MatchPackageOptions & o) : Filter(std::make_shared(spec, f, o)) { } std::ostream & paludis::operator<< (std::ostream & s, const Filter & f) { s << f.as_string(); return s; } namespace paludis { template class Pimp; template class filter::SupportsAction; template class filter::SupportsAction; template class filter::SupportsAction; template class filter::SupportsAction; template class filter::SupportsAction; template class filter::SupportsAction; template class filter::SupportsAction; }