#include #include #include #include #include #include #include #include using namespace std; enum class Option {None=0,UseInput=1,UseOutput=2,UseBanned=4,Verbose=8,DumpProvide=16,AddBootstrap=32}; class Application { public: map bootstrap; map depmap; map > prvmap; map virtuals; vector multiples; map banmap; string filename; bool dump_provide; bool add_bootstrap; pkgCache* cache; /*! Constructor application start point */ Application(int argc,char * argv[]) { vector targets; vector bad_targets; filename=""; dump_provide=false; add_bootstrap=false; if(argc<2) { PrintUsage(); return; } Option option=Option::None; for(int n=0;nPkgBegin();!pkg.end();pkg++) { if(IsVirtual(pkg))continue; //we just take first available version pkgCache::VerIterator ver = pkg.VersionList(); if(ver->Priority == pkgCache::State::Required || ver->Priority == pkgCache::State::Important) { bootstrap[pkg.Name()]=ver.VerStr(); } for(pkgCache::PrvIterator prv=ver.ProvidesList();!prv.end();prv++) { pkgCache::PkgIterator owner= prv.OwnerPkg(); string pname = prv.Name(); string oname = pkg.Name(); if(pname!=oname) { prvmap[pname].push_back(oname); } } } //main targets for(string target : targets) { pkgCache::PkgIterator pkg; string vname; try { pkg = Find(target); } catch(runtime_error e) { //package does not exists bad_targets.push_back(target); continue; } if(IsVirtual(pkg)) { try { vname = ResolveProvide(target); } catch(runtime_error e) { //no one provide this virtual package bad_targets.push_back(target); continue; } //using provided name pkg = Find(vname); } depmap[pkg.Name()]=""; cout<<"[ 0]->"< newdep; /* solving multiple choices */ recompute_multiples: cout<<"multiple choices:"<CompareOp & pkgCache::Dep::Or)!=pkgCache::Dep::Or)break; dep++; cout<<" | "; } cout<<")"<CompareOp & pkgCache::Dep::Or)!=pkgCache::Dep::Or)break; dep++; } if(!found) { /* no choice has be done, let's look for a not banned option */ pkgCache::DepIterator t = q; while(true) { string pkgname = t.TargetPkg().Name(); if(banmap.find(pkgname)==banmap.end()) { if(newdep.find(pkgname)==newdep.end()) { cout<<"Adding "<CompareOp & pkgCache::Dep::Or)!=pkgCache::Dep::Or)break; t++; } } } multiples.clear(); for(pair q: newdep) { cout<<"* RECOMPUTING: "<0) { newdep.clear(); goto recompute_multiples; } //does it ever happen? cout<<"Missing multiples:"<0) { cout<<"Bad inputs:"<0) { cout<<"Provide : Provided from"< > p : prvmap) { cout<<"* "<FindPkg(pkgname); if(pkg.end())throw runtime_error("package does not exists"); return pkg; } /*! Recursive dependency build \param ver Version start point \param depth used for debugging, use 0 */ void Build(pkgCache::VerIterator ver,int depth) { bool last_or=false; for(pkgCache::DepIterator dep=ver.DependsList();!dep.end();dep++) { if(dep->Type==pkgCache::Dep::Depends || dep->Type==pkgCache::Dep::Recommends || dep->Type==pkgCache::Dep::PreDepends ) { //deferred resolution of multiple choices if((dep->CompareOp & pkgCache::Dep::Or)==pkgCache::Dep::Or) { if(!last_or) { last_or=true; multiples.push_back(dep); } continue; } else { if(last_or) { last_or=false; continue; } } pkgCache::PkgIterator pkg = dep.TargetPkg(); string pkgname = pkg.Name(); if(IsVirtual(pkg)) { try { string vname = ResolveProvide(pkgname); cout<"<"< q : depmap) { f< q : bootstrap) { f<\tInput packages"<\tOutput file"<\tPackages to avoid"<