/* vim: set sw=4 sts=4 et foldmethod=syntax : *//* * Copyright (c) 2007, 2008, 2009, 2010 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"key_extractor.hh"#include"matcher.hh"#include<paludis/util/pimp-impl.hh>#include<paludis/util/stringify.hh>#include<paludis/util/set.hh>#include<paludis/util/join.hh>#include<paludis/util/sequence.hh>#include<paludis/util/indirect_iterator-impl.hh>#include<paludis/util/timestamp.hh>#include<paludis/util/accept_visitor.hh>#include<paludis/package_id.hh>#include<paludis/metadata_key.hh>#include<paludis/stringify_formatter.hh>#include<paludis/dep_spec.hh>#include<paludis/environment.hh>#include<paludis/choice.hh>#include<functional>#include<algorithm>usingnamespacepaludis;usingnamespaceinquisitio;namespacepaludis{template<>structImp<KeyExtractor>{conststd::stringkey;constboolflatten;constboolvisible_only;constEnvironment&env;Imp(conststd::string&k,constboolf,constboolv,constEnvironment&e):key(k),flatten(f),visible_only(v),env(e){}};}KeyExtractor::KeyExtractor(conststd::string&k,constboolf,constboolv,constEnvironment&e):Pimp<KeyExtractor>(k,f,v,e){}KeyExtractor::~KeyExtractor(){}namespace{classTreeVisitor{private:conststd::string_key;constbool_visible_only;constEnvironment&_env;conststd::shared_ptr<constPackageID>_id;constMatcher&_m;public:boolresult;TreeVisitor(conststd::string&k,constboolv,constEnvironment&e,conststd::shared_ptr<constPackageID>&i,constMatcher&m):_key(k),_visible_only(v),_env(e),_id(i),_m(m),result(false){}voidvisit(constGenericSpecTree::NodeType<AllDepSpec>::Type&node){std::for_each(indirect_iterator(node.begin()),indirect_iterator(node.end()),accept_visitor(*this));}voidvisit(constGenericSpecTree::NodeType<AnyDepSpec>::Type&node){std::for_each(indirect_iterator(node.begin()),indirect_iterator(node.end()),accept_visitor(*this));}voidvisit(constGenericSpecTree::NodeType<ExactlyOneDepSpec>::Type&node){std::for_each(indirect_iterator(node.begin()),indirect_iterator(node.end()),accept_visitor(*this));}voidvisit(constGenericSpecTree::NodeType<ConditionalDepSpec>::Type&node){if(!result){result|=_m(stringify(*node.spec()));if(!result){if(!_visible_only)std::for_each(indirect_iterator(node.begin()),indirect_iterator(node.end()),accept_visitor(*this));elseif(node.spec()->condition_met(&_env,_id))std::for_each(indirect_iterator(node.begin()),indirect_iterator(node.end()),accept_visitor(*this));}}}voidvisit(constGenericSpecTree::NodeType<SimpleURIDepSpec>::Type&node){if(!result)result|=_m(stringify(*node.spec()));}voidvisit(constGenericSpecTree::NodeType<URILabelsDepSpec>::Type&node){if(!result)result|=_m(stringify(*node.spec()));}voidvisit(constGenericSpecTree::NodeType<PlainTextDepSpec>::Type&node){if(!result)result|=_m(stringify(*node.spec()));}voidvisit(constGenericSpecTree::NodeType<FetchableURIDepSpec>::Type&node){if(!result)result|=_m(stringify(*node.spec()));}voidvisit(constGenericSpecTree::NodeType<PackageDepSpec>::Type&node){if(!result)result|=_m(stringify(*node.spec()));}voidvisit(constGenericSpecTree::NodeType<BlockDepSpec>::Type&node){if(!result)result|=_m(stringify(*node.spec()));}voidvisit(constGenericSpecTree::NodeType<LicenseDepSpec>::Type&node){if(!result)result|=_m(stringify(*node.spec()));}voidvisit(constGenericSpecTree::NodeType<PlainTextLabelDepSpec>::Type&node){if(!result)result|=_m(stringify(*node.spec()));}voidvisit(constGenericSpecTree::NodeType<DependenciesLabelsDepSpec>::Type&node){if(!result)result|=_m(stringify(*node.spec()));}voidvisit(constGenericSpecTree::NodeType<NamedSetDepSpec>::Type&node){if(!result)result|=_m(stringify(*node.spec()));}};std::stringstringify_string_pair(conststd::pair<conststd::string,std::string>&s){if(s.first.empty())returns.second;elsereturns.first+"="+s.second;}classKeyVisitor{private:conststd::string_key;constbool_flatten;constbool_visible_only;constEnvironment&_env;conststd::shared_ptr<constPackageID>_id;constMatcher&_m;public:boolresult;KeyVisitor(conststd::string&k,constboolf,constboolv,constEnvironment&e,conststd::shared_ptr<constPackageID>&i,constMatcher&m):_key(k),_flatten(f),_visible_only(v),_env(e),_id(i),_m(m),result(false){}voidvisit(constMetadataValueKey<std::string>&s){result=_m(s.value());}voidvisit(constMetadataValueKey<SlotName>&s){result=_m(stringify(s.value()));}voidvisit(constMetadataValueKey<long>&s){result=_m(stringify(s.value()));}voidvisit(constMetadataValueKey<bool>&s){result=_m(stringify(s.value()));}voidvisit(constMetadataTimeKey&s){result=_m(stringify(s.value().seconds()));}voidvisit(constMetadataValueKey<std::shared_ptr<constContents>>&){}voidvisit(constMetadataValueKey<std::shared_ptr<constRepositoryMaskInfo>>&){}voidvisit(constMetadataValueKey<FSPath>&s){result=_m(stringify(s.value()));}voidvisit(constMetadataValueKey<std::shared_ptr<constPackageID>>&s){result=_m(stringify(*s.value()));}voidvisit(constMetadataCollectionKey<KeywordNameSet>&s){usingnamespacestd::placeholders;if(_flatten)result=_m(join(s.value()->begin(),s.value()->end()," "));elseresult=s.value()->end()!=std::find_if(s.value()->begin(),s.value()->end(),std::bind(&Matcher::operator(),std::cref(_m),std::bind(&stringify<KeywordName>,_1)));}voidvisit(constMetadataValueKey<std::shared_ptr<constChoices>>&s){if(_flatten){std::stringr;for(Choices::ConstIteratorc(s.value()->begin()),c_end(s.value()->end());c!=c_end;++c)for(Choice::ConstIteratori((*c)->begin()),i_end((*c)->end());i!=i_end;++i){if(!r.empty())r.append(" ");r.append(stringify((*i)->name_with_prefix()));}result=_m(r);}else{for(Choices::ConstIteratorc(s.value()->begin()),c_end(s.value()->end());c!=c_end&&!result;++c)for(Choice::ConstIteratori((*c)->begin()),i_end((*c)->end());i!=i_end&&!result;++i)result=_m(stringify((*i)->name_with_prefix()));}}voidvisit(constMetadataCollectionKey<Set<std::string>>&s){usingnamespacestd::placeholders;if(_flatten)result=_m(join(s.value()->begin(),s.value()->end()," "));elseresult=s.value()->end()!=std::find_if(s.value()->begin(),s.value()->end(),std::bind(&Matcher::operator(),std::cref(_m),_1));}voidvisit(constMetadataCollectionKey<Map<std::string,std::string>>&s){usingnamespacestd::placeholders;if(_flatten)result=_m(join(s.value()->begin(),s.value()->end()," ",stringify_string_pair));elseresult=s.value()->end()!=std::find_if(s.value()->begin(),s.value()->end(),std::bind(&Matcher::operator(),std::cref(_m),std::bind(&stringify_string_pair,_1)));}voidvisit(constMetadataCollectionKey<Sequence<std::string>>&s){usingnamespacestd::placeholders;if(_flatten)result=_m(join(s.value()->begin(),s.value()->end()," "));elseresult=s.value()->end()!=std::find_if(s.value()->begin(),s.value()->end(),std::bind(&Matcher::operator(),std::cref(_m),_1));}voidvisit(constMetadataCollectionKey<FSPathSequence>&s){usingnamespacestd::placeholders;if(_flatten)result=_m(join(s.value()->begin(),s.value()->end()," "));elseresult=s.value()->end()!=std::find_if(s.value()->begin(),s.value()->end(),std::bind(&Matcher::operator(),std::cref(_m),std::bind(&stringify<FSPath>,_1)));}voidvisit(constMetadataCollectionKey<PackageIDSequence>&s){usingnamespacestd::placeholders;if(_flatten)result=_m(join(indirect_iterator(s.value()->begin()),indirect_iterator(s.value()->end())," "));elseresult=indirect_iterator(s.value()->end())!=std::find_if(indirect_iterator(s.value()->begin()),indirect_iterator(s.value()->end()),std::bind(&Matcher::operator(),std::cref(_m),std::bind(&stringify<PackageID>,_1)));}voidvisit(constMetadataSpecTreeKey<PlainTextSpecTree>&s){if(_flatten){StringifyFormatterf;result=_m(s.pretty_print_flat(f));}else{TreeVisitorv(_key,_visible_only,_env,_id,_m);s.value()->top()->accept(v);result=v.result;}}voidvisit(constMetadataSpecTreeKey<RequiredUseSpecTree>&s){if(_flatten){StringifyFormatterf;result=_m(s.pretty_print_flat(f));}else{TreeVisitorv(_key,_visible_only,_env,_id,_m);s.value()->top()->accept(v);result=v.result;}}voidvisit(constMetadataSpecTreeKey<DependencySpecTree>&s){if(_flatten){StringifyFormatterf;result=_m(s.pretty_print_flat(f));}else{TreeVisitorv(_key,_visible_only,_env,_id,_m);s.value()->top()->accept(v);result=v.result;}}voidvisit(constMetadataSpecTreeKey<SetSpecTree>&s){if(_flatten){StringifyFormatterf;result=_m(s.pretty_print_flat(f));}else{TreeVisitorv(_key,_visible_only,_env,_id,_m);s.value()->top()->accept(v);result=v.result;}}voidvisit(constMetadataSpecTreeKey<LicenseSpecTree>&s){if(_flatten){StringifyFormatterf;result=_m(s.pretty_print_flat(f));}else{TreeVisitorv(_key,_visible_only,_env,_id,_m);s.value()->top()->accept(v);result=v.result;}}voidvisit(constMetadataSpecTreeKey<FetchableURISpecTree>&s){if(_flatten){StringifyFormatterf;result=_m(s.pretty_print_flat(f));}else{TreeVisitorv(_key,_visible_only,_env,_id,_m);s.value()->top()->accept(v);result=v.result;}}voidvisit(constMetadataSpecTreeKey<SimpleURISpecTree>&s){if(_flatten){StringifyFormatterf;result=_m(s.pretty_print_flat(f));}else{TreeVisitorv(_key,_visible_only,_env,_id,_m);s.value()->top()->accept(v);result=v.result;}}voidvisit(constMetadataSpecTreeKey<ProvideSpecTree>&s){if(_flatten){StringifyFormatterf;result=_m(s.pretty_print_flat(f));}else{TreeVisitorv(_key,_visible_only,_env,_id,_m);s.value()->top()->accept(v);result=v.result;}}voidvisit(constMetadataSectionKey&k){std::for_each(indirect_iterator(k.begin_metadata()),indirect_iterator(k.end_metadata()),accept_visitor(*this));}};}boolKeyExtractor::operator()(constMatcher&m,conststd::shared_ptr<constPackageID>&id)const{PackageID::MetadataConstIteratormi(id->find_metadata(_imp->key));if(id->end_metadata()==mi)returnfalse;KeyVisitorv(_imp->key,_imp->flatten,_imp->visible_only,_imp->env,id,m);(*mi)->accept(v);returnv.result;}