]>
git.saurik.com Git - apt.git/blob - apt-pkg/depcache.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: depcache.cc,v 1.25 2001/05/27 05:36:04 jgg Exp $
4 /* ######################################################################
6 Dependency Cache - Caches Dependency information.
8 ##################################################################### */
10 // Include Files /*{{{*/
12 #pragma implementation "apt-pkg/depcache.h"
14 #include <apt-pkg/depcache.h>
15 #include <apt-pkg/version.h>
16 #include <apt-pkg/error.h>
17 #include <apt-pkg/sptr.h>
18 #include <apt-pkg/algorithms.h>
20 #include <apt-pkg/fileutl.h>
21 #include <apt-pkg/configuration.h>
22 #include <apt-pkg/tagfile.h>
29 // DepCache::pkgDepCache - Constructors /*{{{*/
30 // ---------------------------------------------------------------------
32 pkgDepCache::pkgDepCache(pkgCache
*pCache
,Policy
*Plcy
) :
33 Cache(pCache
), PkgState(0), DepState(0)
38 delLocalPolicy
= LocalPolicy
= new Policy
;
41 // DepCache::~pkgDepCache - Destructor /*{{{*/
42 // ---------------------------------------------------------------------
44 pkgDepCache::~pkgDepCache()
48 delete delLocalPolicy
;
51 // DepCache::Init - Generate the initial extra structures. /*{{{*/
52 // ---------------------------------------------------------------------
53 /* This allocats the extension buffers and initializes them. */
54 bool pkgDepCache::Init(OpProgress
*Prog
)
58 PkgState
= new StateCache
[Head().PackageCount
];
59 DepState
= new unsigned char[Head().DependsCount
];
60 memset(PkgState
,0,sizeof(*PkgState
)*Head().PackageCount
);
61 memset(DepState
,0,sizeof(*DepState
)*Head().DependsCount
);
65 Prog
->OverallProgress(0,2*Head().PackageCount
,Head().PackageCount
,
66 _("Building dependency tree"));
67 Prog
->SubProgress(Head().PackageCount
,_("Candidate versions"));
70 /* Set the current state of everything. In this state all of the
71 packages are kept exactly as is. See AllUpgrade */
73 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
78 // Find the proper cache slot
79 StateCache
&State
= PkgState
[I
->ID
];
81 State
.DirtyState
= pkgCache::State::RemoveUnknown
;
82 //State.AutomaticRemove = I->AutomaticRemove;
83 State
.AutomaticRemove
= pkgCache::State::RemoveUnknown
;
85 // Figure out the install version
86 State
.CandidateVer
= GetCandidateVer(I
);
87 State
.InstallVer
= I
.CurrentVer();
88 State
.Mode
= ModeKeep
;
90 State
.Update(I
,*this);
96 Prog
->OverallProgress(Head().PackageCount
,2*Head().PackageCount
,
98 _("Building dependency tree"));
99 Prog
->SubProgress(Head().PackageCount
,_("Dependency generation"));
111 bool pkgDepCache::readStateFile(OpProgress
*Prog
)
114 string state
= _config
->FindDir("Dir::State") + "pkgstates";
115 if(FileExists(state
)) {
116 state_file
.Open(state
, FileFd::ReadOnly
);
117 int file_size
= state_file
.Size();
118 Prog
->OverallProgress(0, file_size
, 1,
119 _("Reading extended state information"));
121 pkgTagFile
tagfile(&state_file
);
122 pkgTagSection section
;
124 while(tagfile
.Step(section
)) {
125 string pkgname
= section
.FindS("Package");
126 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
127 // Silently ignore unknown packages and packages with no actual
129 if(!pkg
.end() && !pkg
.VersionList().end()) {
130 short reason
= section
.FindI("Remove-Reason",
131 pkgCache::State::RemoveManual
);
132 PkgState
[pkg
->ID
].AutomaticRemove
= reason
;
133 //std::cout << "Set: " << pkgname << " to " << reason << std::endl;
135 Prog
->OverallProgress(amt
, file_size
, 1,
136 _("Reading extended state information"));
138 Prog
->OverallProgress(file_size
, file_size
, 1,
139 _("Reading extended state information"));
146 bool pkgDepCache::writeStateFile(OpProgress
*prog
)
148 // FIXME: this function needs to be called inside the commit()
149 // of the package manager. so after
152 string state
= _config
->FindDir("Dir::State") + "pkgstates";
154 if(!StateFile
.Open(state
, FileFd::WriteEmpty
))
155 return _error
->Error(_("Failed to write StateFile %s"),
158 std::ostringstream ostr
;
159 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end();pkg
++) {
161 // clear out no longer installed pkg
162 if(PkgState
[pkg
->ID
].Delete() || pkg
.CurrentVer() == NULL
)
163 PkgState
[pkg
->ID
].AutomaticRemove
= pkgCache::State::RemoveUnknown
;
165 // check if we have new information
166 if(PkgState
[pkg
->ID
].Flags
& pkgCache::Flag::Auto
) {
167 if(_config
->FindI("Debug::pkgAutoRemove",false))
168 std::clog
<< "pkg: " << pkg
.Name() << " is auto-dep" << std::endl
;
169 PkgState
[pkg
->ID
].AutomaticRemove
= pkgCache::State::RemoveRequired
;
172 if(PkgState
[pkg
->ID
].AutomaticRemove
!= pkgCache::State::RemoveUnknown
) {
173 ostr
.str(string(""));
174 ostr
<< "Package: " << pkg
.Name()
175 << "\nRemove-Reason: "
176 << (int)(PkgState
[pkg
->ID
].AutomaticRemove
) << "\n\n";
177 StateFile
.Write(ostr
.str().c_str(), ostr
.str().size());
183 // DepCache::CheckDep - Checks a single dependency /*{{{*/
184 // ---------------------------------------------------------------------
185 /* This first checks the dependency against the main target package and
186 then walks along the package provides list and checks if each provides
187 will be installed then checks the provides against the dep. Res will be
188 set to the package which was used to satisfy the dep. */
189 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
191 Res
= Dep
.TargetPkg();
193 /* Check simple depends. A depends -should- never self match but
194 we allow it anyhow because dpkg does. Technically it is a packaging
195 bug. Conflicts may never self match */
196 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
197 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::Obsoletes
))
199 PkgIterator Pkg
= Dep
.TargetPkg();
200 // Check the base package
201 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
202 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
203 Dep
.TargetVer()) == true)
206 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
207 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
208 Dep
->CompareOp
,Dep
.TargetVer()) == true)
211 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
212 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
213 Dep
->CompareOp
,Dep
.TargetVer()) == true)
217 if (Dep
->Type
== Dep::Obsoletes
)
220 // Check the providing packages
221 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
222 PkgIterator Pkg
= Dep
.ParentPkg();
223 for (; P
.end() != true; P
++)
225 /* Provides may never be applied against the same package if it is
226 a conflicts. See the comment above. */
227 if (P
.OwnerPkg() == Pkg
&& Dep
->Type
== Dep::Conflicts
)
230 // Check if the provides is a hit
231 if (Type
== NowVersion
)
233 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
237 if (Type
== InstallVersion
)
239 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
240 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
244 if (Type
== CandidateVersion
)
246 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
247 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
251 // Compare the versions.
252 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
262 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
263 // ---------------------------------------------------------------------
264 /* Call with Mult = -1 to preform the inverse opration */
265 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
267 StateCache
&P
= PkgState
[Pkg
->ID
];
269 if (Pkg
->VersionList
== 0)
272 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
276 // Compute the size data
277 if (P
.NewInstall() == true)
279 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
280 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
285 if (Pkg
->CurrentVer
!= 0 &&
286 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
287 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
289 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
290 (signed)Pkg
.CurrentVer()->InstalledSize
));
291 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
296 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
299 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
304 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
306 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
311 // DepCache::AddStates - Add the package to the state counter /*{{{*/
312 // ---------------------------------------------------------------------
313 /* This routine is tricky to use, you must make sure that it is never
314 called twice for the same package. This means the Remove/Add section
315 should be as short as possible and not encompass any code that will
316 calld Remove/Add itself. Remember, dependencies can be circular so
317 while processing a dep for Pkg it is possible that Add/Remove
318 will be called on Pkg */
319 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
321 StateCache
&State
= PkgState
[Pkg
->ID
];
323 // The Package is broken
324 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
328 if (Pkg
.State() != PkgIterator::NeedsNothing
)
332 if (Pkg
->CurrentVer
== 0)
334 if (State
.Mode
== ModeDelete
&&
335 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
338 if (State
.Mode
== ModeInstall
)
343 // Installed, no upgrade
344 if (State
.Status
== 0)
346 if (State
.Mode
== ModeDelete
)
349 if ((State
.iFlags
& ReInstall
) == ReInstall
)
355 // Alll 3 are possible
356 if (State
.Mode
== ModeDelete
)
358 if (State
.Mode
== ModeKeep
)
360 if (State
.Mode
== ModeInstall
)
364 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
365 // ---------------------------------------------------------------------
366 /* The or group results are stored in the last item of the or group. This
367 allows easy detection of the state of a whole or'd group. */
368 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
370 unsigned char Group
= 0;
372 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
374 // Build the dependency state.
375 unsigned char &State
= DepState
[D
->ID
];
377 /* Invert for Conflicts. We have to do this twice to get the
378 right sense for a conflicts group */
379 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
382 // Add to the group if we are within an or..
386 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
389 // Invert for Conflicts
390 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
395 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
396 // ---------------------------------------------------------------------
397 /* This is used to run over a dependency list and determine the dep
398 state of the list, filtering it through both a Min check and a Policy
399 check. The return result will have SetMin/SetPolicy low if a check
400 fails. It uses the DepState cache for it's computations. */
401 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
402 unsigned char SetMin
,
403 unsigned char SetPolicy
)
405 unsigned char Dep
= 0xFF;
407 while (D
.end() != true)
409 // Compute a single dependency element (glob or)
410 DepIterator Start
= D
;
411 unsigned char State
= 0;
412 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
414 State
|= DepState
[D
->ID
];
415 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
418 // Minimum deps that must be satisfied to have a working package
419 if (Start
.IsCritical() == true)
420 if ((State
& Check
) != Check
)
423 // Policy deps that must be satisfied to install the package
424 if (IsImportantDep(Start
) == true &&
425 (State
& Check
) != Check
)
432 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
433 // ---------------------------------------------------------------------
434 /* This is the main dependency computation bit. It computes the 3 main
435 results for a dependencys, Now, Install and Candidate. Callers must
436 invert the result if dealing with conflicts. */
437 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
439 unsigned char State
= 0;
441 if (CheckDep(D
,NowVersion
) == true)
443 if (CheckDep(D
,InstallVersion
) == true)
445 if (CheckDep(D
,CandidateVersion
) == true)
451 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
452 // ---------------------------------------------------------------------
453 /* This determines the combined dependency representation of a package
454 for its two states now and install. This is done by using the pre-generated
455 dependency information. */
456 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
458 // Empty deps are always true
459 StateCache
&State
= PkgState
[Pkg
->ID
];
460 State
.DepState
= 0xFF;
462 // Check the Current state
463 if (Pkg
->CurrentVer
!= 0)
465 DepIterator D
= Pkg
.CurrentVer().DependsList();
466 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
469 /* Check the candidate state. We do not compare against the whole as
470 a candidate state but check the candidate version against the
472 if (State
.CandidateVer
!= 0)
474 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
475 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
478 // Check target state which can only be current or installed
479 if (State
.InstallVer
!= 0)
481 DepIterator D
= State
.InstVerIter(*this).DependsList();
482 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
486 // DepCache::Update - Figure out all the state information /*{{{*/
487 // ---------------------------------------------------------------------
488 /* This will figure out the state of all the packages and all the
489 dependencies based on the current policy. */
490 void pkgDepCache::Update(OpProgress
*Prog
)
500 // Perform the depends pass
502 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
504 if (Prog
!= 0 && Done%20
== 0)
505 Prog
->Progress(Done
);
506 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
508 unsigned char Group
= 0;
510 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
512 // Build the dependency state.
513 unsigned char &State
= DepState
[D
->ID
];
514 State
= DependencyState(D
);
516 // Add to the group if we are within an or..
519 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
522 // Invert for Conflicts
523 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
528 // Compute the pacakge dependency state and size additions
537 Prog
->Progress(Done
);
540 // DepCache::Update - Update the deps list of a package /*{{{*/
541 // ---------------------------------------------------------------------
542 /* This is a helper for update that only does the dep portion of the scan.
543 It is mainly ment to scan reverse dependencies. */
544 void pkgDepCache::Update(DepIterator D
)
546 // Update the reverse deps
547 for (;D
.end() != true; D
++)
549 unsigned char &State
= DepState
[D
->ID
];
550 State
= DependencyState(D
);
552 // Invert for Conflicts
553 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
556 RemoveStates(D
.ParentPkg());
557 BuildGroupOrs(D
.ParentVer());
558 UpdateVerState(D
.ParentPkg());
559 AddStates(D
.ParentPkg());
563 // DepCache::Update - Update the related deps of a package /*{{{*/
564 // ---------------------------------------------------------------------
565 /* This is called whenever the state of a package changes. It updates
566 all cached dependencies related to this package. */
567 void pkgDepCache::Update(PkgIterator
const &Pkg
)
569 // Recompute the dep of the package
574 // Update the reverse deps
575 Update(Pkg
.RevDependsList());
577 // Update the provides map for the current ver
578 if (Pkg
->CurrentVer
!= 0)
579 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
580 P
.end() != true; P
++)
581 Update(P
.ParentPkg().RevDependsList());
583 // Update the provides map for the candidate ver
584 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
585 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
586 P
.end() != true; P
++)
587 Update(P
.ParentPkg().RevDependsList());
592 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
593 // ---------------------------------------------------------------------
595 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
,bool Soft
)
597 // Simplifies other routines.
598 if (Pkg
.end() == true)
601 /* Reject an attempt to keep a non-source broken installed package, those
603 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
604 Pkg
.CurrentVer().Downloadable() == false)
607 /* We changed the soft state all the time so the UI is a bit nicer
609 StateCache
&P
= PkgState
[Pkg
->ID
];
611 P
.iFlags
|= AutoKept
;
613 P
.iFlags
&= ~AutoKept
;
615 // Check that it is not already kept
616 if (P
.Mode
== ModeKeep
)
619 // We dont even try to keep virtual packages..
620 if (Pkg
->VersionList
== 0)
623 P
.Flags
&= ~Flag::Auto
;
628 if (Pkg
->CurrentVer
== 0)
631 P
.InstallVer
= Pkg
.CurrentVer();
640 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
641 // ---------------------------------------------------------------------
643 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
)
645 // Simplifies other routines.
646 if (Pkg
.end() == true)
649 // Check that it is not already marked for delete
650 StateCache
&P
= PkgState
[Pkg
->ID
];
651 P
.iFlags
&= ~(AutoKept
| Purge
);
655 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
656 (Pkg
.Purge() == true || rPurge
== false))
659 // We dont even try to delete virtual packages..
660 if (Pkg
->VersionList
== 0)
666 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
671 // This was not inverted before, but I think it should be
672 P
.Flags
&= ~Flag::Auto
;
679 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
680 // ---------------------------------------------------------------------
682 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
688 // Simplifies other routines.
689 if (Pkg
.end() == true)
692 /* Check that it is not already marked for install and that it can be
694 StateCache
&P
= PkgState
[Pkg
->ID
];
695 P
.iFlags
&= ~AutoKept
;
696 if (P
.InstBroken() == false && (P
.Mode
== ModeInstall
||
697 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
699 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
704 // See if there is even any possible instalation candidate
705 if (P
.CandidateVer
== 0)
708 // We dont even try to install virtual packages..
709 if (Pkg
->VersionList
== 0)
712 /* Target the candidate version and remove the autoflag. We reset the
713 autoflag below if this was called recursively. Otherwise the user
714 should have the ability to de-auto a package by changing its state */
718 P
.Mode
= ModeInstall
;
719 P
.InstallVer
= P
.CandidateVer
;
720 P
.Flags
&= ~Flag::Auto
;
721 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
728 if (AutoInst
== false)
731 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
732 for (; Dep
.end() != true;)
735 DepIterator Start
= Dep
;
738 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
740 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
742 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
746 // Dep is satisfied okay.
750 /* Check if this dep should be consider for install. If it is a user
751 defined important dep and we are installed a new package then
752 it will be installed. Otherwise we only worry about critical deps */
753 if (IsImportantDep(Start
) == false)
755 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false)
758 /* If we are in an or group locate the first or that can
759 succeed. We have already cached this.. */
760 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
763 /* This bit is for processing the possibilty of an install/upgrade
764 fixing the problem */
765 SPtrArray
<Version
*> List
= Start
.AllTargets();
766 if ((DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
768 // Right, find the best version to install..
769 Version
**Cur
= List
;
770 PkgIterator P
= Start
.TargetPkg();
771 PkgIterator
InstPkg(*Cache
,0);
773 // See if there are direct matches (at the start of the list)
774 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
776 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
777 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
783 // Select the highest priority providing package
784 if (InstPkg
.end() == true)
786 pkgPrioSortList(*Cache
,Cur
);
787 for (; *Cur
!= 0; Cur
++)
789 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
790 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
797 if (InstPkg
.end() == false)
799 MarkInstall(InstPkg
,true,Depth
+ 1);
801 // Set the autoflag, after MarkInstall because MarkInstall unsets it
802 if (P
->CurrentVer
== 0)
803 PkgState
[InstPkg
->ID
].Flags
|= Flag::Auto
;
809 /* For conflicts we just de-install the package and mark as auto,
810 Conflicts may not have or groups */
811 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
)
813 for (Version
**I
= List
; *I
!= 0; I
++)
815 VerIterator
Ver(*this,*I
);
816 PkgIterator Pkg
= Ver
.ParentPkg();
819 PkgState
[Pkg
->ID
].Flags
|= Flag::Auto
;
826 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
827 // ---------------------------------------------------------------------
829 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
834 StateCache
&P
= PkgState
[Pkg
->ID
];
836 P
.iFlags
|= ReInstall
;
838 P
.iFlags
&= ~ReInstall
;
844 // DepCache::SetDirty - Switch the package between dirty states /*{{{*/
845 // ---------------------------------------------------------------------
847 void pkgDepCache::SetDirty(PkgIterator
const &Pkg
, pkgCache::State::PkgRemoveState To
)
849 StateCache
&P
= PkgState
[Pkg
->ID
];
853 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
854 // ---------------------------------------------------------------------
856 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
858 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
859 StateCache
&P
= PkgState
[Pkg
->ID
];
864 if (P
.CandidateVer
== P
.InstallVer
)
865 P
.InstallVer
= (Version
*)TargetVer
;
866 P
.CandidateVer
= (Version
*)TargetVer
;
874 // StateCache::Update - Compute the various static display things /*{{{*/
875 // ---------------------------------------------------------------------
876 /* This is called whenever the Candidate version changes. */
877 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
880 VerIterator Ver
= CandidateVerIter(Cache
);
882 // Use a null string or the version string
883 if (Ver
.end() == true)
886 CandVersion
= Ver
.VerStr();
888 // Find the current version
890 if (Pkg
->CurrentVer
!= 0)
891 CurVersion
= Pkg
.CurrentVer().VerStr();
893 // Strip off the epochs for display
894 CurVersion
= StripEpoch(CurVersion
);
895 CandVersion
= StripEpoch(CandVersion
);
897 // Figure out if its up or down or equal
898 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
899 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
903 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
904 // ---------------------------------------------------------------------
906 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
912 for (const char *I
= Ver
; *I
!= 0; I
++)
919 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
920 // ---------------------------------------------------------------------
921 /* The default just returns the highest available version that is not
922 a source and automatic. */
923 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
925 /* Not source/not automatic versions cannot be a candidate version
926 unless they are already installed */
927 VerIterator
Last(*(pkgCache
*)this,0);
929 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
931 if (Pkg
.CurrentVer() == I
)
934 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
936 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
939 /* Stash the highest version of a not-automatic source, we use it
940 if there is nothing better */
941 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
943 if (Last
.end() == true)
955 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
956 // ---------------------------------------------------------------------
958 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
960 return Dep
.IsCritical();