]>
git.saurik.com Git - apt.git/blob - apt-pkg/depcache.cc
54cfcb8bb64f79dcea823e4e8cfc4aeb6121b83a
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>
27 // DepCache::pkgDepCache - Constructors /*{{{*/
28 // ---------------------------------------------------------------------
30 pkgDepCache::pkgDepCache(pkgCache
*pCache
,Policy
*Plcy
) :
31 Cache(pCache
), PkgState(0), DepState(0)
36 delLocalPolicy
= LocalPolicy
= new Policy
;
39 // DepCache::~pkgDepCache - Destructor /*{{{*/
40 // ---------------------------------------------------------------------
42 pkgDepCache::~pkgDepCache()
46 delete delLocalPolicy
;
49 // DepCache::Init - Generate the initial extra structures. /*{{{*/
50 // ---------------------------------------------------------------------
51 /* This allocats the extension buffers and initializes them. */
52 bool pkgDepCache::Init(OpProgress
*Prog
)
56 PkgState
= new StateCache
[Head().PackageCount
];
57 DepState
= new unsigned char[Head().DependsCount
];
58 memset(PkgState
,0,sizeof(*PkgState
)*Head().PackageCount
);
59 memset(DepState
,0,sizeof(*DepState
)*Head().DependsCount
);
63 Prog
->OverallProgress(0,2*Head().PackageCount
,Head().PackageCount
,
64 _("Building dependency tree"));
65 Prog
->SubProgress(Head().PackageCount
,_("Candidate versions"));
68 /* Set the current state of everything. In this state all of the
69 packages are kept exactly as is. See AllUpgrade */
71 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
76 // Find the proper cache slot
77 StateCache
&State
= PkgState
[I
->ID
];
79 State
.DirtyState
= pkgCache::State::RemoveUnknown
;
80 //State.AutomaticRemove = I->AutomaticRemove;
81 State
.AutomaticRemove
= pkgCache::State::RemoveUnknown
;
83 // Figure out the install version
84 State
.CandidateVer
= GetCandidateVer(I
);
85 State
.InstallVer
= I
.CurrentVer();
86 State
.Mode
= ModeKeep
;
88 State
.Update(I
,*this);
94 Prog
->OverallProgress(Head().PackageCount
,2*Head().PackageCount
,
96 _("Building dependency tree"));
97 Prog
->SubProgress(Head().PackageCount
,_("Dependency generation"));
109 bool pkgDepCache::readStateFile(OpProgress
*Prog
)
112 string state
= _config
->FindDir("Dir::State") + "pkgstates";
113 if(FileExists(state
)) {
114 state_file
.Open(state
, FileFd::ReadOnly
);
115 int file_size
= state_file
.Size();
116 Prog
->OverallProgress(0, file_size
, 1,
117 _("Reading extended state information"));
119 pkgTagFile
tagfile(&state_file
);
120 pkgTagSection section
;
122 while(tagfile
.Step(section
)) {
123 string pkgname
= section
.FindS("Package");
124 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
125 // Silently ignore unknown packages and packages with no actual
127 if(!pkg
.end() && !pkg
.VersionList().end()) {
128 short reason
= section
.FindI("Remove-Reason",
129 pkgCache::State::RemoveManual
);
130 PkgState
[pkg
->ID
].AutomaticRemove
= reason
;
131 //std::cout << "Set: " << pkgname << " to " << reason << std::endl;
133 Prog
->OverallProgress(amt
, file_size
, 1,
134 _("Reading extended state information"));
136 Prog
->OverallProgress(file_size
, file_size
, 1,
137 _("Reading extended state information"));
144 bool pkgDepCache::writeStateFile(OpProgress
*prog
)
146 // FIXME: this function needs to be called inside the commit()
147 // of the package manager. so after
150 string state
= _config
->FindDir("Dir::State") + "pkgstates";
152 if(!StateFile
.Open(state
, FileFd::WriteEmpty
))
153 return _error
->Error(_("Failed to write StateFile %s"),
156 std::ostringstream ostr
;
157 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end();pkg
++) {
159 // clear out no longer installed pkg
160 if(PkgState
[pkg
->ID
].Delete() || pkg
.CurrentVer() == NULL
)
161 PkgState
[pkg
->ID
].AutomaticRemove
= pkgCache::State::RemoveUnknown
;
163 // check if we have new information
164 if(PkgState
[pkg
->ID
].Flags
& pkgCache::Flag::Auto
) {
165 std::cout
<< "pkg: " << pkg
.Name() << " is auto-dep" << std::endl
;
166 PkgState
[pkg
->ID
].AutomaticRemove
= pkgCache::State::RemoveRequired
;
169 if(PkgState
[pkg
->ID
].AutomaticRemove
!= pkgCache::State::RemoveUnknown
) {
170 ostr
.str(string(""));
171 ostr
<< "Package: " << pkg
.Name()
172 << "\nRemove-Reason: "
173 << (int)(PkgState
[pkg
->ID
].AutomaticRemove
) << "\n\n";
174 StateFile
.Write(ostr
.str().c_str(), ostr
.str().size());
175 //std::cout << "Writing auto-mark: " << ostr.str() << endl;
181 // DepCache::CheckDep - Checks a single dependency /*{{{*/
182 // ---------------------------------------------------------------------
183 /* This first checks the dependency against the main target package and
184 then walks along the package provides list and checks if each provides
185 will be installed then checks the provides against the dep. Res will be
186 set to the package which was used to satisfy the dep. */
187 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
189 Res
= Dep
.TargetPkg();
191 /* Check simple depends. A depends -should- never self match but
192 we allow it anyhow because dpkg does. Technically it is a packaging
193 bug. Conflicts may never self match */
194 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
195 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::Obsoletes
))
197 PkgIterator Pkg
= Dep
.TargetPkg();
198 // Check the base package
199 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
200 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
201 Dep
.TargetVer()) == true)
204 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
205 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
206 Dep
->CompareOp
,Dep
.TargetVer()) == true)
209 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
210 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
211 Dep
->CompareOp
,Dep
.TargetVer()) == true)
215 if (Dep
->Type
== Dep::Obsoletes
)
218 // Check the providing packages
219 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
220 PkgIterator Pkg
= Dep
.ParentPkg();
221 for (; P
.end() != true; P
++)
223 /* Provides may never be applied against the same package if it is
224 a conflicts. See the comment above. */
225 if (P
.OwnerPkg() == Pkg
&& Dep
->Type
== Dep::Conflicts
)
228 // Check if the provides is a hit
229 if (Type
== NowVersion
)
231 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
235 if (Type
== InstallVersion
)
237 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
238 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
242 if (Type
== CandidateVersion
)
244 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
245 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
249 // Compare the versions.
250 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
260 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
261 // ---------------------------------------------------------------------
262 /* Call with Mult = -1 to preform the inverse opration */
263 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
265 StateCache
&P
= PkgState
[Pkg
->ID
];
267 if (Pkg
->VersionList
== 0)
270 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
274 // Compute the size data
275 if (P
.NewInstall() == true)
277 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
278 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
283 if (Pkg
->CurrentVer
!= 0 &&
284 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
285 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
287 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
288 (signed)Pkg
.CurrentVer()->InstalledSize
));
289 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
294 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
297 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
302 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
304 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
309 // DepCache::AddStates - Add the package to the state counter /*{{{*/
310 // ---------------------------------------------------------------------
311 /* This routine is tricky to use, you must make sure that it is never
312 called twice for the same package. This means the Remove/Add section
313 should be as short as possible and not encompass any code that will
314 calld Remove/Add itself. Remember, dependencies can be circular so
315 while processing a dep for Pkg it is possible that Add/Remove
316 will be called on Pkg */
317 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
319 StateCache
&State
= PkgState
[Pkg
->ID
];
321 // The Package is broken
322 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
326 if (Pkg
.State() != PkgIterator::NeedsNothing
)
330 if (Pkg
->CurrentVer
== 0)
332 if (State
.Mode
== ModeDelete
&&
333 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
336 if (State
.Mode
== ModeInstall
)
341 // Installed, no upgrade
342 if (State
.Status
== 0)
344 if (State
.Mode
== ModeDelete
)
347 if ((State
.iFlags
& ReInstall
) == ReInstall
)
353 // Alll 3 are possible
354 if (State
.Mode
== ModeDelete
)
356 if (State
.Mode
== ModeKeep
)
358 if (State
.Mode
== ModeInstall
)
362 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
363 // ---------------------------------------------------------------------
364 /* The or group results are stored in the last item of the or group. This
365 allows easy detection of the state of a whole or'd group. */
366 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
368 unsigned char Group
= 0;
370 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
372 // Build the dependency state.
373 unsigned char &State
= DepState
[D
->ID
];
375 /* Invert for Conflicts. We have to do this twice to get the
376 right sense for a conflicts group */
377 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
380 // Add to the group if we are within an or..
384 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
387 // Invert for Conflicts
388 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
393 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
394 // ---------------------------------------------------------------------
395 /* This is used to run over a dependency list and determine the dep
396 state of the list, filtering it through both a Min check and a Policy
397 check. The return result will have SetMin/SetPolicy low if a check
398 fails. It uses the DepState cache for it's computations. */
399 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
400 unsigned char SetMin
,
401 unsigned char SetPolicy
)
403 unsigned char Dep
= 0xFF;
405 while (D
.end() != true)
407 // Compute a single dependency element (glob or)
408 DepIterator Start
= D
;
409 unsigned char State
= 0;
410 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
412 State
|= DepState
[D
->ID
];
413 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
416 // Minimum deps that must be satisfied to have a working package
417 if (Start
.IsCritical() == true)
418 if ((State
& Check
) != Check
)
421 // Policy deps that must be satisfied to install the package
422 if (IsImportantDep(Start
) == true &&
423 (State
& Check
) != Check
)
430 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
431 // ---------------------------------------------------------------------
432 /* This is the main dependency computation bit. It computes the 3 main
433 results for a dependencys, Now, Install and Candidate. Callers must
434 invert the result if dealing with conflicts. */
435 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
437 unsigned char State
= 0;
439 if (CheckDep(D
,NowVersion
) == true)
441 if (CheckDep(D
,InstallVersion
) == true)
443 if (CheckDep(D
,CandidateVersion
) == true)
449 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
450 // ---------------------------------------------------------------------
451 /* This determines the combined dependency representation of a package
452 for its two states now and install. This is done by using the pre-generated
453 dependency information. */
454 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
456 // Empty deps are always true
457 StateCache
&State
= PkgState
[Pkg
->ID
];
458 State
.DepState
= 0xFF;
460 // Check the Current state
461 if (Pkg
->CurrentVer
!= 0)
463 DepIterator D
= Pkg
.CurrentVer().DependsList();
464 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
467 /* Check the candidate state. We do not compare against the whole as
468 a candidate state but check the candidate version against the
470 if (State
.CandidateVer
!= 0)
472 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
473 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
476 // Check target state which can only be current or installed
477 if (State
.InstallVer
!= 0)
479 DepIterator D
= State
.InstVerIter(*this).DependsList();
480 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
484 // DepCache::Update - Figure out all the state information /*{{{*/
485 // ---------------------------------------------------------------------
486 /* This will figure out the state of all the packages and all the
487 dependencies based on the current policy. */
488 void pkgDepCache::Update(OpProgress
*Prog
)
498 // Perform the depends pass
500 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
502 if (Prog
!= 0 && Done%20
== 0)
503 Prog
->Progress(Done
);
504 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
506 unsigned char Group
= 0;
508 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
510 // Build the dependency state.
511 unsigned char &State
= DepState
[D
->ID
];
512 State
= DependencyState(D
);
514 // Add to the group if we are within an or..
517 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
520 // Invert for Conflicts
521 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
526 // Compute the pacakge dependency state and size additions
535 Prog
->Progress(Done
);
538 // DepCache::Update - Update the deps list of a package /*{{{*/
539 // ---------------------------------------------------------------------
540 /* This is a helper for update that only does the dep portion of the scan.
541 It is mainly ment to scan reverse dependencies. */
542 void pkgDepCache::Update(DepIterator D
)
544 // Update the reverse deps
545 for (;D
.end() != true; D
++)
547 unsigned char &State
= DepState
[D
->ID
];
548 State
= DependencyState(D
);
550 // Invert for Conflicts
551 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
554 RemoveStates(D
.ParentPkg());
555 BuildGroupOrs(D
.ParentVer());
556 UpdateVerState(D
.ParentPkg());
557 AddStates(D
.ParentPkg());
561 // DepCache::Update - Update the related deps of a package /*{{{*/
562 // ---------------------------------------------------------------------
563 /* This is called whenever the state of a package changes. It updates
564 all cached dependencies related to this package. */
565 void pkgDepCache::Update(PkgIterator
const &Pkg
)
567 // Recompute the dep of the package
572 // Update the reverse deps
573 Update(Pkg
.RevDependsList());
575 // Update the provides map for the current ver
576 if (Pkg
->CurrentVer
!= 0)
577 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
578 P
.end() != true; P
++)
579 Update(P
.ParentPkg().RevDependsList());
581 // Update the provides map for the candidate ver
582 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
583 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
584 P
.end() != true; P
++)
585 Update(P
.ParentPkg().RevDependsList());
590 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
591 // ---------------------------------------------------------------------
593 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
,bool Soft
)
595 // Simplifies other routines.
596 if (Pkg
.end() == true)
599 /* Reject an attempt to keep a non-source broken installed package, those
601 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
602 Pkg
.CurrentVer().Downloadable() == false)
605 /* We changed the soft state all the time so the UI is a bit nicer
607 StateCache
&P
= PkgState
[Pkg
->ID
];
609 P
.iFlags
|= AutoKept
;
611 P
.iFlags
&= ~AutoKept
;
613 // Check that it is not already kept
614 if (P
.Mode
== ModeKeep
)
617 // We dont even try to keep virtual packages..
618 if (Pkg
->VersionList
== 0)
621 P
.Flags
&= ~Flag::Auto
;
626 if (Pkg
->CurrentVer
== 0)
629 P
.InstallVer
= Pkg
.CurrentVer();
638 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
639 // ---------------------------------------------------------------------
641 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
)
643 // Simplifies other routines.
644 if (Pkg
.end() == true)
647 // Check that it is not already marked for delete
648 StateCache
&P
= PkgState
[Pkg
->ID
];
649 P
.iFlags
&= ~(AutoKept
| Purge
);
653 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
654 (Pkg
.Purge() == true || rPurge
== false))
657 // We dont even try to delete virtual packages..
658 if (Pkg
->VersionList
== 0)
664 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
669 // This was not inverted before, but I think it should be
670 P
.Flags
&= ~Flag::Auto
;
677 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
678 // ---------------------------------------------------------------------
680 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
686 // Simplifies other routines.
687 if (Pkg
.end() == true)
690 /* Check that it is not already marked for install and that it can be
692 StateCache
&P
= PkgState
[Pkg
->ID
];
693 P
.iFlags
&= ~AutoKept
;
694 if (P
.InstBroken() == false && (P
.Mode
== ModeInstall
||
695 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
697 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
702 // See if there is even any possible instalation candidate
703 if (P
.CandidateVer
== 0)
706 // We dont even try to install virtual packages..
707 if (Pkg
->VersionList
== 0)
710 /* Target the candidate version and remove the autoflag. We reset the
711 autoflag below if this was called recursively. Otherwise the user
712 should have the ability to de-auto a package by changing its state */
716 P
.Mode
= ModeInstall
;
717 P
.InstallVer
= P
.CandidateVer
;
718 P
.Flags
&= ~Flag::Auto
;
719 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
726 if (AutoInst
== false)
729 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
730 for (; Dep
.end() != true;)
733 DepIterator Start
= Dep
;
736 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
738 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
740 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
744 // Dep is satisfied okay.
748 /* Check if this dep should be consider for install. If it is a user
749 defined important dep and we are installed a new package then
750 it will be installed. Otherwise we only worry about critical deps */
751 if (IsImportantDep(Start
) == false)
753 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false)
756 /* If we are in an or group locate the first or that can
757 succeed. We have already cached this.. */
758 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
761 /* This bit is for processing the possibilty of an install/upgrade
762 fixing the problem */
763 SPtrArray
<Version
*> List
= Start
.AllTargets();
764 if ((DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
766 // Right, find the best version to install..
767 Version
**Cur
= List
;
768 PkgIterator P
= Start
.TargetPkg();
769 PkgIterator
InstPkg(*Cache
,0);
771 // See if there are direct matches (at the start of the list)
772 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
774 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
775 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
781 // Select the highest priority providing package
782 if (InstPkg
.end() == true)
784 pkgPrioSortList(*Cache
,Cur
);
785 for (; *Cur
!= 0; Cur
++)
787 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
788 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
795 if (InstPkg
.end() == false)
797 MarkInstall(InstPkg
,true,Depth
+ 1);
799 // Set the autoflag, after MarkInstall because MarkInstall unsets it
800 if (P
->CurrentVer
== 0)
801 PkgState
[InstPkg
->ID
].Flags
|= Flag::Auto
;
807 /* For conflicts we just de-install the package and mark as auto,
808 Conflicts may not have or groups */
809 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
)
811 for (Version
**I
= List
; *I
!= 0; I
++)
813 VerIterator
Ver(*this,*I
);
814 PkgIterator Pkg
= Ver
.ParentPkg();
817 PkgState
[Pkg
->ID
].Flags
|= Flag::Auto
;
824 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
825 // ---------------------------------------------------------------------
827 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
832 StateCache
&P
= PkgState
[Pkg
->ID
];
834 P
.iFlags
|= ReInstall
;
836 P
.iFlags
&= ~ReInstall
;
842 // DepCache::SetDirty - Switch the package between dirty states /*{{{*/
843 // ---------------------------------------------------------------------
845 void pkgDepCache::SetDirty(PkgIterator
const &Pkg
, pkgCache::State::PkgRemoveState To
)
847 StateCache
&P
= PkgState
[Pkg
->ID
];
851 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
852 // ---------------------------------------------------------------------
854 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
856 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
857 StateCache
&P
= PkgState
[Pkg
->ID
];
862 if (P
.CandidateVer
== P
.InstallVer
)
863 P
.InstallVer
= (Version
*)TargetVer
;
864 P
.CandidateVer
= (Version
*)TargetVer
;
872 // StateCache::Update - Compute the various static display things /*{{{*/
873 // ---------------------------------------------------------------------
874 /* This is called whenever the Candidate version changes. */
875 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
878 VerIterator Ver
= CandidateVerIter(Cache
);
880 // Use a null string or the version string
881 if (Ver
.end() == true)
884 CandVersion
= Ver
.VerStr();
886 // Find the current version
888 if (Pkg
->CurrentVer
!= 0)
889 CurVersion
= Pkg
.CurrentVer().VerStr();
891 // Strip off the epochs for display
892 CurVersion
= StripEpoch(CurVersion
);
893 CandVersion
= StripEpoch(CandVersion
);
895 // Figure out if its up or down or equal
896 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
897 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
901 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
902 // ---------------------------------------------------------------------
904 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
910 for (const char *I
= Ver
; *I
!= 0; I
++)
917 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
918 // ---------------------------------------------------------------------
919 /* The default just returns the highest available version that is not
920 a source and automatic. */
921 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
923 /* Not source/not automatic versions cannot be a candidate version
924 unless they are already installed */
925 VerIterator
Last(*(pkgCache
*)this,0);
927 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
929 if (Pkg
.CurrentVer() == I
)
932 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
934 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
937 /* Stash the highest version of a not-automatic source, we use it
938 if there is nothing better */
939 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
941 if (Last
.end() == true)
953 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
954 // ---------------------------------------------------------------------
956 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
958 return Dep
.IsCritical();