1
// aptitude_resolver_universe.cc -*-c++-*-
3
#include "aptitude_resolver_universe.h"
5
#include "config_signal.h"
7
#include <generic/problemresolver/problemresolver.h>
8
#include <generic/problemresolver/solution.h>
13
#include <apt-pkg/error.h>
15
#include <cwidget/generic/util/ssprintf.h>
21
using aptitude::Loggers;
22
using cwidget::util::ssprintf;
25
bool ver_disappeared(const pkgCache::VerIterator ver)
28
!ver.Downloadable() &&
29
(ver != ver.ParentPkg().CurrentVer() ||
30
ver.ParentPkg()->CurrentState == pkgCache::State::ConfigFiles);
33
/** Detects dependencies that (provides ignored) are conflicts that
34
* can't be triggered ever.
36
* We want to eliminate these dependencies because they are an
37
* inconsistency (albiet spurious) in aptitude's model: they don't
38
* appear as reverse dependencies since there is no package that they
39
* would be followed backwards from.
41
* Ignoring provides is safe since conflicts as seen in the model are
42
* specific to a particular provides link, and
43
* conflicts-through-provides can't be empty (true? maybe not: what
44
* about disappeared providers?).
46
static bool empty_conflict(const pkgCache::DepIterator &dep,
47
const pkgCache::PrvIterator &prv)
49
if(!is_conflict(dep->Type))
55
for(pkgCache::VerIterator ver =
56
const_cast<pkgCache::DepIterator &>(dep).TargetPkg().VersionList();
57
!ver.end() && !found; ++ver)
59
if(!ver_disappeared(ver) &&
60
(dep.TargetVer() == NULL ||
61
_system->VS->CheckDep(ver.VerStr(),
67
// If we found no matching non-disappeared version, then this
68
// conflict is irrelevant.
73
if(ver_disappeared(const_cast<pkgCache::PrvIterator &>(prv).OwnerVer()))
76
// If the provider doesn't match the dependency, then this is an
77
// irrelevant conflict.
78
return !_system->VS->CheckDep(prv.ProvideVersion(),
79
dep->CompareOp, dep.TargetVer());
83
string aptitude_resolver_version::get_name() const
85
pkgCache::VerIterator ver(get_ver());
86
pkgCache::PkgIterator pkg(get_pkg());
89
// If there are two distinct package files with the same
90
// Version, apt will give them the same VerStr. Detect and
91
// compensate for this.
95
for(pkgCache::VerIterator i=pkg.VersionList(); !i.end(); ++i)
102
else if(!strcmp(i.VerStr(), ver.VerStr()))
106
// if not, we have a "version" of this package that's not in
107
// its list of versions!
113
s << ver.VerStr() << "<" << idx+1 << ">";
120
// Note that this is an invalid version string for apt, so we
121
// can't clash with real versions.
125
bool aptitude_resolver_version::revdep_iterator::applicable() const
127
if(!is_interesting_dep(dep_lst, cache))
130
// Screen out self-conflicts from the reverse dependency list. Note
131
// that we can screen out *any* conflict on a version of the same
132
// package: if a version conflicts with itself it's ignored, and if
133
// a version conflicts with a different version of the same package,
134
// that's just a redundant expression of the rule that no two
135
// versions of the same package can be simultaneously installed.
137
// As a bonus, this lets us match what gets generated for forward
139
if(is_conflict(dep_lst->Type) &&
141
const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerPkg() == const_cast<pkgCache::DepIterator &>(dep_lst).ParentPkg())
143
// Self-deps are always irrelevant regardless of whether we're in a
146
const_cast<pkgCache::DepIterator &>(dep_lst).ParentPkg() == const_cast<pkgCache::DepIterator &>(dep_lst).TargetPkg())
149
// Drop irrelevant conflicts; that is, conflicts that are never
150
// satisfied. This improves the connection consistency of the
152
if(empty_conflict(dep_lst, prv_lst))
156
// Unversioned deps always apply unless they are self-deps or
158
if(!dep_lst.TargetVer())
162
return _system->VS->CheckDep(prv_lst.ProvideVersion(),
163
dep_lst->CompareOp, dep_lst.TargetVer());
165
return _system->VS->CheckDep(ver.VerStr(),
166
dep_lst->CompareOp, dep_lst.TargetVer());
169
void aptitude_resolver_version::revdep_iterator::normalize()
171
while(!dep_lst.end() && !applicable())
174
if(dep_lst.end() && !provides_open)
176
eassert(prv_lst.end());
177
prv_lst=ver.ProvidesList();
181
dep_lst=prv_lst.ParentPkg().RevDependsList();
182
while(!dep_lst.end() && !applicable())
187
// When we've run out of provides, give up..
188
while(dep_lst.end() && !prv_lst.end())
190
eassert(provides_open);
195
eassert(!prv_lst.ParentPkg().end());
196
dep_lst=prv_lst.ParentPkg().RevDependsList();
198
while(!dep_lst.end() && !applicable())
204
inline void aptitude_resolver_version::dep_iterator::advance()
206
bool move_to_next_dep = true;
208
eassert(prv_open == !prv.end());
210
// If the Provides list is nonempty, advance it.
219
move_to_next_dep = false;
221
// If we weren't trying to iterate over a Provides list *and* the
222
// current dep is a non-versioned Conflicts, start such an
224
else if(!prv_open && is_conflict(dep->Type) &&
227
prv = dep.TargetPkg().ProvidesList();
228
if(!prv.end()) // otherwise we should advance to the next dep.
231
move_to_next_dep = false;
235
eassert(prv_open == !prv.end());
239
if(!dep.end() && is_conflict(dep->Type))
243
// If it's not a conflict, skip a whole OR group.
244
while(!dep.end() && (dep->CompareOp & pkgCache::Dep::Or))
247
// Now we're on the last element of the OR group, push
256
aptitude_resolver_version::dep_iterator::applicable(const pkgCache::DepIterator &dep,
257
const pkgCache::PrvIterator &prv,
265
eassert(is_conflict(dep->Type));
267
// NB: inlined pkgCache::DepIterator::IsIgnorable
268
// if(dep.IsIgnorable(prv) == true)
270
const pkgCache::PkgIterator pkg = dep.ParentPkg();
271
if(prv.OwnerPkg()->Group == pkg->Group)
273
if(pkg->Group == dep.TargetPkg()->Group && prv.OwnerPkg()->Group != pkg->Group)
277
if(dep.ParentPkg() == dep.TargetPkg())
280
if(!is_interesting_dep(dep, cache))
282
if(empty_conflict(dep, prv))
288
bool aptitude_resolver_version::dep_iterator::applicable()
290
if(is_conflict(dep->Type))
291
// In this case the current dependency is represented completely
292
// by the depends and provides iterators; no need to step.
293
return applicable(dep, prv, prv_open, cache);
296
// We need to check everything in the current OR block.
297
pkgCache::DepIterator tmpdep = dep;
299
if(!tmpdep.end() && applicable(tmpdep, prv, prv_open, cache))
301
while(!tmpdep.end() && (tmpdep->CompareOp & pkgCache::Dep::Or))
304
if(!tmpdep.end() && applicable(tmpdep, prv, prv_open, cache))
312
void aptitude_resolver_version::dep_iterator::normalize()
314
while(!dep.end() && !applicable())
316
// If we ran out of deps, we're done!
319
void aptitude_resolver_dep::solver_iterator::normalize()
321
if(!is_conflict(dep_lst->Type))
325
for(; ver_lst.end() == false; ++ver_lst)
327
if(dep_lst.IsIgnorable(ver_lst.ParentPkg()) == true)
330
if(_system->VS->CheckDep(ver_lst.VerStr(),
332
dep_lst.TargetVer()) == false)
335
if(ver_disappeared(ver_lst) == false)
339
// If we ran out of versions, try provides instead.
340
for(; prv_lst.end() == false; ++prv_lst)
342
if(dep_lst.IsIgnorable(prv_lst) == true)
345
if(_system->VS->CheckDep(prv_lst.ProvideVersion(),
347
dep_lst.TargetVer()) == false)
350
if(ver_disappeared(prv_lst.OwnerVer()) == false)
354
// No more target versions or providers of the target;
355
// increment the dependency list if we aren't yet at the
356
// end of the OR group.
358
if(!(dep_lst->CompareOp & pkgCache::Dep::Or))
363
// Since we aren't finished, dep_lst should still be
365
eassert(!dep_lst.end());
366
ver_lst=dep_lst.TargetPkg().VersionList();
368
// Only set the prv_lst to non-end if there is no target
370
prv_lst=dep_lst.TargetPkg().ProvidesList();
376
// For Conflicts/Breaks, we're iterating over all the versions of
377
// *one* package for *one* dep, either the owner of the
378
// dep or a provided package. (prv_lst is mostly
379
// unnecessary, but it makes it simple to remember whether
380
// we have a provides). Note that the efficiency of this
381
// stanza is based on the *assumption* that most packages
382
// only Provide a few things.
384
// For provided packages, return exactly those packages
385
// that *don't* have a matching Provides.
388
while(!ver_lst.end())
390
if(ver_lst != prv_lst.OwnerVer() &&
391
!ver_disappeared(ver_lst))
396
// Important point: end version iterators always match
397
// a Conflicts/Breaks! (i.e., those can always be resolved
398
// by removing the conflicted package)
403
while(!ver_lst.end())
405
bool ver_matches=(!dep_lst.TargetVer()) ||
407
_system->VS->CheckDep(ver_lst.VerStr(),
409
dep_lst.TargetVer()));
411
if(!ver_matches && !ver_disappeared(ver_lst))
412
// This version resolves the conflict.
418
// Ignore provides; as above, end versions are A-OK.
424
bool aptitude_resolver_dep::solved_by(const aptitude_resolver_version &v) const
426
pkgCache::DepIterator start_iter(cache->GetCache(), const_cast<pkgCache::Dependency *>(start));
428
// First check for moving the source.
429
if(v.get_pkg() == start_iter.ParentPkg() && v.get_ver() != start_iter.ParentVer())
432
// Now check each of the members of the OR group.
433
pkgCache::DepIterator d = start_iter;
435
if(!is_conflict(start->Type))
437
// Of course, installing an end version never fixes a
438
// non-conflict unless it removes the source (tested for above).
439
if(v.get_ver().end())
444
if(d.IsIgnorable(v.get_pkg()) == false
445
&& _system->VS->CheckDep(v.get_ver().VerStr(),
447
d.TargetVer()) == true)
450
// Check for a resolution via Provides.
451
for(pkgCache::PrvIterator p2 = v.get_ver().ProvidesList();
452
p2.end() == false; ++p2)
454
if(d.IsIgnorable(p2) == true)
457
if(p2.ParentPkg() != d.TargetPkg())
460
if(_system->VS->CheckDep(p2.ProvideVersion(),
462
d.TargetVer()) == true)
466
if((d->CompareOp & pkgCache::Dep::Or) != 0)
474
if(d.TargetPkg() != v.get_pkg())
477
if(v.get_ver().end())
480
// Check the non-virtual part of the conflict: the package is
481
// the same and the version **doesn't** match.
482
return !(!d.TargetVer() || _system->VS->CheckDep(v.get_ver().VerStr(),
488
pkgCache::PrvIterator prv_iter(cache->GetCache(), const_cast<pkgCache::Provides *>(prv),
489
(pkgCache::Package *)0);
491
// Only other versions of the provider can solve this.
492
if(v.get_pkg() != prv_iter.OwnerPkg())
495
return v.get_ver() != prv_iter.OwnerVer();
499
aptitude_resolver_dep::solver_iterator &aptitude_resolver_dep::solver_iterator::operator++()
503
// Advance whatever needs to be advanced next in the
508
else if(!is_conflict(dep_lst->Type))
521
aptitude_resolver_version::dep_iterator &aptitude_resolver_version::dep_iterator::operator++()
531
aptitude_resolver_version aptitude_resolver_dep::solver_iterator::operator*() const
536
return aptitude_resolver_version::make_install(ver_lst, cache);
537
else // In this case we're trying to remove some package or other.
539
if(!is_conflict(dep_lst->Type))
541
// Assume this because otherwise end() should be true.
542
eassert(!prv_lst.end());
544
return aptitude_resolver_version::make_install(const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerVer(), cache);
546
else if(!prv_lst.end())
547
return aptitude_resolver_version::make_removal(const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerPkg(), cache);
549
return aptitude_resolver_version::make_removal(const_cast<pkgCache::DepIterator &>(dep_lst).TargetPkg(), cache);
553
void aptitude_universe::dep_iterator::normalize()
555
while(dep.end() && !pkg.end())
557
while(dep.end() && !ver.end())
561
dep=aptitude_resolver_version::dep_iterator(ver, cache);
569
ver=pkg.VersionList();
571
dep=aptitude_resolver_version::dep_iterator(ver, cache);
577
bool aptitude_universe::broken_dep_iterator::dep_is_inst_broken(const pkgCache::DepIterator &d) const
579
pkgCache::DepIterator d2=d;
581
while(d2->CompareOp & pkgCache::Dep::Or)
584
return ((*cache)[d2] & pkgDepCache::DepGInstall)==0;
587
struct DummyEmptySolution
589
aptitude_resolver_version version_of(const aptitude_resolver_package &p) const
591
return p.current_version();
595
void dumpDep(std::ostream &out, pkgCache::DepIterator &dep,
598
out << dep.ParentPkg().FullName(false) << " ("
599
<< dep.ParentVer().VerStr() << ") "
602
<< dep.TargetPkg().FullName(false);
603
if(dep.TargetVer() != NULL)
605
out << " (" << dep.CompType() << " " << dep.TargetVer() << ")";
607
std::vector<std::string> flags;
608
if(dep->Type & pkgCache::Dep::Or)
609
flags.push_back("OR");
611
unsigned char dep_state = (*cache)[dep];
612
if(dep_state & pkgDepCache::DepNow)
613
flags.push_back("DEPNOW");
614
if(dep_state & pkgDepCache::DepInstall)
615
flags.push_back("DEPINSTALL");
616
if(dep_state & pkgDepCache::DepCVer)
617
flags.push_back("DEPCVER");
618
if(dep_state & pkgDepCache::DepGNow)
619
flags.push_back("DEPGNOW");
620
if(dep_state & pkgDepCache::DepGInstall)
621
flags.push_back("DEPGINSTALL");
622
if(dep_state & pkgDepCache::DepGCVer)
623
flags.push_back("DEPGCVER");
627
for(std::vector<std::string>::const_iterator it =
628
flags.begin(); it != flags.end(); ++it)
640
void aptitude_universe::broken_dep_iterator::normalize()
642
while(!the_dep.end() &&
643
!(is_interesting_dep(the_dep, cache) &&
644
dep_is_inst_broken(the_dep)))
647
while(the_dep.end() && !pkg.end())
649
// Make sure we move at least one package forward!
650
// Otherwise we just spin on the same package over and over,
651
// since it's still broken..
656
// Examine just the InstVer of the package.
657
pkgCache::VerIterator ver=(*cache)[pkg].InstVerIter(*cache);
660
the_dep=ver.DependsList();
662
while(!the_dep.end() &&
663
!(is_interesting_dep(the_dep, cache) &&
664
dep_is_inst_broken(the_dep)))
672
eassert(the_dep.end() || is_interesting_dep(the_dep, cache));
674
// Now dep is a broken critical dep or an end dep. If it is a
675
// conflicts, we might need to push down into Provides...
676
if(!the_dep.end() && is_conflict(the_dep->Type))
678
// If we aren't in provides, check whether the dep is
679
// trivially broken (i.e., without following provides).
682
// If it's a direct self-conflict, jump into provides
684
if(the_dep.TargetPkg() != the_dep.ParentPkg())
686
pkgCache::VerIterator ver=(*cache)[the_dep.TargetPkg()].InstVerIter(*cache);
689
!ver_disappeared(ver) &&
690
(!the_dep.TargetVer() ||
692
_system->VS->CheckDep(ver.VerStr(),
694
the_dep.TargetVer()))))
695
// OK, the dep is broken without provides, no need
701
prv=the_dep.TargetPkg().ProvidesList();
704
// Ok, we have found something that causes breakage. The
705
// provides-list is a list of all the package versions that
706
// provide this package name; move forward until we find one
710
// Ignore indirect self-conflicts.
711
if(prv.OwnerPkg() != the_dep.ParentPkg())
713
// First, is the providing version going to be
715
if((*cache)[prv.OwnerPkg()].InstVerIter(*cache) == prv.OwnerVer())
717
// Ok, does it match the version string?
719
!the_dep.TargetVer() ||
720
(prv.ProvideVersion() &&
721
_system->VS->CheckDep(prv.ProvideVersion(),
723
the_dep.TargetVer()));
725
if(ver_disappeared(prv.OwnerVer()))
736
// if all provides are exhausted, increment the dep and try
737
// again. (probably this was only a self-conflict and
742
// hopefully g++ is smart enough to optimize this into a
747
if(!end() && !(**this).broken_under(DummyEmptySolution()))
749
std::ostringstream s;
751
// Not translated because this is an internal error that users
752
// should report to me verbatim.
753
_error->Warning("apt thinks that %s is broken, but I don't.",
760
aptitude_universe::broken_dep_iterator &aptitude_universe::broken_dep_iterator::operator++()
763
// If the_dep.end() we have pkg.end().
764
eassert(!the_dep.end());
766
if(!prv_open && is_conflict(the_dep->Type))
769
prv = the_dep.TargetPkg().ProvidesList();
771
else if(prv_open && !prv.end())
780
std::ostream &operator<<(ostream &out, const aptitude_resolver_package &p)
782
return out << p.get_name();
785
std::ostream &operator<<(ostream &out, const aptitude_resolver_version &v)
787
return out << v.get_package().get_name() << " " << v.get_name();
790
std::ostream &operator<<(ostream &out, const aptitude_resolver_dep &d)
792
std::vector<aptitude_resolver_version> solvers;
793
for(aptitude_resolver_dep::solver_iterator i=d.solvers_begin(); !i.end(); ++i)
794
solvers.push_back(*i);
796
generic_solution<aptitude_universe>::ver_name_lt lt;
797
sort(solvers.begin(), solvers.end(), lt);
799
out << d.get_source() << (d.is_soft() ? " -S> {" : " -> {");
801
for(std::vector<aptitude_resolver_version>::const_iterator i = solvers.begin();
802
i != solvers.end(); ++i)
804
if(i != solvers.begin())
813
std::ostream &operator<<(std::ostream &out, const cfg_level &level)
815
if(level.get_is_discard())
818
out << level.get_level();
823
cfg_level aptitude_universe::parse_level(const std::string &s)
825
typedef generic_problem_resolver<aptitude_universe> aptitude_resolver;
827
return cfg_level::make_level(cost_limits::maximum_level);
828
else if(s == "minimum" || s == "")
829
return cfg_level::make_level(cost_limits::minimum_level);
830
else if(s == "conflict" || s == "discard")
831
return cfg_level::make_conflict();
835
int n = static_cast<int>(strtol(s.c_str(), &endptr, 0));
838
std::string msg(ssprintf(N_("Invalid safety level \"%s\" (not \"discard\", \"maximum\", \"minimum\", or an integer)."), s.c_str()));
839
LOG_ERROR(Loggers::getAptitudeResolverCosts(), msg);
840
_error->Error("%s", _(msg.c_str()));
841
return cfg_level::make_level(cost_limits::minimum_level);
844
return cfg_level::make_level(n);
848
cfg_level aptitude_universe::parse_levels(const std::string &level1,
849
const std::string &level2,
850
cfg_level default_level)
852
if(level1.empty() && level2.empty())
853
return default_level;
854
else if(level1.empty())
855
return parse_level(level2);
856
else if(level2.empty())
857
return parse_level(level1);
859
return std::max<cfg_level>(parse_level(level1), parse_level(level2));
862
cfg_level aptitude_universe::get_safe_level()
865
parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Safe-Level", ""),
866
aptcfg->Find(PACKAGE "::ProblemResolver::Safe-Tier", ""),
867
cfg_level::make_level(10000));
870
cfg_level aptitude_universe::get_keep_all_level()
872
return parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Keep-All-Level", ""),
873
aptcfg->Find(PACKAGE "::ProblemResolver::Keep-All-Tier", ""),
874
cfg_level::make_level(20000));
877
cfg_level aptitude_universe::get_remove_level()
879
return parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Remove-Level", ""),
880
aptcfg->Find(PACKAGE "::ProblemResolver::Remove-Tier", ""),
881
cfg_level::make_level(10000));
884
cfg_level aptitude_universe::get_break_hold_level()
886
return parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Break-Hold-Level", ""),
887
aptcfg->Find(PACKAGE "::ProblemResolver::Break-Hold-Tier", ""),
888
cfg_level::make_level(40000));
891
cfg_level aptitude_universe::get_non_default_level()
893
return parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Non-Default-Level", ""),
894
aptcfg->Find(PACKAGE "::ProblemResolver::Non-Default-Tier", ""),
895
cfg_level::make_level(50000));
898
cfg_level aptitude_universe::get_remove_essential_level()
900
return parse_levels(aptcfg->Find(PACKAGE "::ProblemResolver::Remove-Essential-Level", ""),
901
aptcfg->Find(PACKAGE "::ProblemResolver::Remove-Essential-Tier", ""),
902
cfg_level::make_level(60000));
905
bool aptitude_universe::is_candidate_for_initial_set(const aptitude_resolver_dep &d) const
913
pkgCache::DepIterator d2(d.get_dep());
914
while(!d2.end() && (d2->CompareOp & pkgCache::Dep::Or))
920
// Return true only if the dependency is *currently* not broken.
921
return (*cache)[d2] & pkgDepCache::DepGNow;