]>
git.saurik.com Git - apt.git/blob - apt-pkg/depcache.cc
269fe8543f7e069bc74c4aca61a6f3e5e4e3fd94
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"));
106 bool pkgDepCache::readStateFile(OpProgress
*Prog
)
109 string state
= _config
->FindDir("Dir::State") + "pkgstates";
110 if(FileExists(state
)) {
111 state_file
.Open(state
, FileFd::ReadOnly
);
112 int file_size
= state_file
.Size();
113 Prog
->OverallProgress(0, file_size
, 1,
114 _("Reading extended state information"));
116 pkgTagFile
tagfile(&state_file
);
117 pkgTagSection section
;
119 while(tagfile
.Step(section
)) {
120 string pkgname
= section
.FindS("Package");
121 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
122 // Silently ignore unknown packages and packages with no actual
124 if(!pkg
.end() && !pkg
.VersionList().end()) {
125 short reason
= section
.FindI("Remove-Reason",
126 pkgCache::State::RemoveManual
);
127 PkgState
[pkg
->ID
].AutomaticRemove
= reason
;
128 //std::cout << "Set: " << pkgname << " to " << reason << std::endl;
130 Prog
->OverallProgress(amt
, file_size
, 1,
131 _("Reading extended state information"));
133 Prog
->OverallProgress(file_size
, file_size
, 1,
134 _("Reading extended state information"));
141 bool pkgDepCache::writeStateFile(OpProgress
*prog
)
143 // FIXME: this function needs to be called inside the commit()
144 // of the package manager. so after
147 string state
= _config
->FindDir("Dir::State") + "pkgstates";
149 if(!StateFile
.Open(state
, FileFd::WriteEmpty
))
150 return _error
->Error(_("Failed to write StateFile %s"),
153 std::ostringstream ostr
;
154 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end();pkg
++) {
156 // clear out no longer installed pkg
157 if(PkgState
[pkg
->ID
].Delete() || pkg
.CurrentVer() == NULL
)
158 PkgState
[pkg
->ID
].AutomaticRemove
= pkgCache::State::RemoveUnknown
;
160 // check if we have new information
161 if(PkgState
[pkg
->ID
].Flags
& pkgCache::Flag::Auto
) {
162 std::cout
<< "pkg: " << pkg
.Name() << " is auto-dep" << std::endl
;
163 PkgState
[pkg
->ID
].AutomaticRemove
= pkgCache::State::RemoveRequired
;
166 if(PkgState
[pkg
->ID
].AutomaticRemove
!= pkgCache::State::RemoveUnknown
) {
167 ostr
.str(string(""));
168 ostr
<< "Package: " << pkg
.Name()
169 << "\nRemove-Reason: "
170 << (int)(PkgState
[pkg
->ID
].AutomaticRemove
) << "\n\n";
171 StateFile
.Write(ostr
.str().c_str(), ostr
.str().size());
172 //std::cout << "Writing auto-mark: " << ostr.str() << endl;
178 // DepCache::CheckDep - Checks a single dependency /*{{{*/
179 // ---------------------------------------------------------------------
180 /* This first checks the dependency against the main target package and
181 then walks along the package provides list and checks if each provides
182 will be installed then checks the provides against the dep. Res will be
183 set to the package which was used to satisfy the dep. */
184 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
186 Res
= Dep
.TargetPkg();
188 /* Check simple depends. A depends -should- never self match but
189 we allow it anyhow because dpkg does. Technically it is a packaging
190 bug. Conflicts may never self match */
191 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
192 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::Obsoletes
))
194 PkgIterator Pkg
= Dep
.TargetPkg();
195 // Check the base package
196 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
197 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
198 Dep
.TargetVer()) == true)
201 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
202 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
203 Dep
->CompareOp
,Dep
.TargetVer()) == true)
206 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
207 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
208 Dep
->CompareOp
,Dep
.TargetVer()) == true)
212 if (Dep
->Type
== Dep::Obsoletes
)
215 // Check the providing packages
216 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
217 PkgIterator Pkg
= Dep
.ParentPkg();
218 for (; P
.end() != true; P
++)
220 /* Provides may never be applied against the same package if it is
221 a conflicts. See the comment above. */
222 if (P
.OwnerPkg() == Pkg
&& Dep
->Type
== Dep::Conflicts
)
225 // Check if the provides is a hit
226 if (Type
== NowVersion
)
228 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
232 if (Type
== InstallVersion
)
234 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
235 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
239 if (Type
== CandidateVersion
)
241 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
242 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
246 // Compare the versions.
247 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
257 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
258 // ---------------------------------------------------------------------
259 /* Call with Mult = -1 to preform the inverse opration */
260 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
262 StateCache
&P
= PkgState
[Pkg
->ID
];
264 if (Pkg
->VersionList
== 0)
267 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
271 // Compute the size data
272 if (P
.NewInstall() == true)
274 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
275 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
280 if (Pkg
->CurrentVer
!= 0 &&
281 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
282 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
284 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
285 (signed)Pkg
.CurrentVer()->InstalledSize
));
286 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
291 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
294 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
299 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
301 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
306 // DepCache::AddStates - Add the package to the state counter /*{{{*/
307 // ---------------------------------------------------------------------
308 /* This routine is tricky to use, you must make sure that it is never
309 called twice for the same package. This means the Remove/Add section
310 should be as short as possible and not encompass any code that will
311 calld Remove/Add itself. Remember, dependencies can be circular so
312 while processing a dep for Pkg it is possible that Add/Remove
313 will be called on Pkg */
314 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
316 StateCache
&State
= PkgState
[Pkg
->ID
];
318 // The Package is broken
319 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
323 if (Pkg
.State() != PkgIterator::NeedsNothing
)
327 if (Pkg
->CurrentVer
== 0)
329 if (State
.Mode
== ModeDelete
&&
330 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
333 if (State
.Mode
== ModeInstall
)
338 // Installed, no upgrade
339 if (State
.Status
== 0)
341 if (State
.Mode
== ModeDelete
)
344 if ((State
.iFlags
& ReInstall
) == ReInstall
)
350 // Alll 3 are possible
351 if (State
.Mode
== ModeDelete
)
353 if (State
.Mode
== ModeKeep
)
355 if (State
.Mode
== ModeInstall
)
359 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
360 // ---------------------------------------------------------------------
361 /* The or group results are stored in the last item of the or group. This
362 allows easy detection of the state of a whole or'd group. */
363 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
365 unsigned char Group
= 0;
367 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
369 // Build the dependency state.
370 unsigned char &State
= DepState
[D
->ID
];
372 /* Invert for Conflicts. We have to do this twice to get the
373 right sense for a conflicts group */
374 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
377 // Add to the group if we are within an or..
381 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
384 // Invert for Conflicts
385 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
390 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
391 // ---------------------------------------------------------------------
392 /* This is used to run over a dependency list and determine the dep
393 state of the list, filtering it through both a Min check and a Policy
394 check. The return result will have SetMin/SetPolicy low if a check
395 fails. It uses the DepState cache for it's computations. */
396 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
397 unsigned char SetMin
,
398 unsigned char SetPolicy
)
400 unsigned char Dep
= 0xFF;
402 while (D
.end() != true)
404 // Compute a single dependency element (glob or)
405 DepIterator Start
= D
;
406 unsigned char State
= 0;
407 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
409 State
|= DepState
[D
->ID
];
410 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
413 // Minimum deps that must be satisfied to have a working package
414 if (Start
.IsCritical() == true)
415 if ((State
& Check
) != Check
)
418 // Policy deps that must be satisfied to install the package
419 if (IsImportantDep(Start
) == true &&
420 (State
& Check
) != Check
)
427 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
428 // ---------------------------------------------------------------------
429 /* This is the main dependency computation bit. It computes the 3 main
430 results for a dependencys, Now, Install and Candidate. Callers must
431 invert the result if dealing with conflicts. */
432 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
434 unsigned char State
= 0;
436 if (CheckDep(D
,NowVersion
) == true)
438 if (CheckDep(D
,InstallVersion
) == true)
440 if (CheckDep(D
,CandidateVersion
) == true)
446 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
447 // ---------------------------------------------------------------------
448 /* This determines the combined dependency representation of a package
449 for its two states now and install. This is done by using the pre-generated
450 dependency information. */
451 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
453 // Empty deps are always true
454 StateCache
&State
= PkgState
[Pkg
->ID
];
455 State
.DepState
= 0xFF;
457 // Check the Current state
458 if (Pkg
->CurrentVer
!= 0)
460 DepIterator D
= Pkg
.CurrentVer().DependsList();
461 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
464 /* Check the candidate state. We do not compare against the whole as
465 a candidate state but check the candidate version against the
467 if (State
.CandidateVer
!= 0)
469 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
470 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
473 // Check target state which can only be current or installed
474 if (State
.InstallVer
!= 0)
476 DepIterator D
= State
.InstVerIter(*this).DependsList();
477 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
481 // DepCache::Update - Figure out all the state information /*{{{*/
482 // ---------------------------------------------------------------------
483 /* This will figure out the state of all the packages and all the
484 dependencies based on the current policy. */
485 void pkgDepCache::Update(OpProgress
*Prog
)
495 // Perform the depends pass
497 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
499 if (Prog
!= 0 && Done%20
== 0)
500 Prog
->Progress(Done
);
501 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
503 unsigned char Group
= 0;
505 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
507 // Build the dependency state.
508 unsigned char &State
= DepState
[D
->ID
];
509 State
= DependencyState(D
);
511 // Add to the group if we are within an or..
514 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
517 // Invert for Conflicts
518 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
523 // Compute the pacakge dependency state and size additions
532 Prog
->Progress(Done
);
535 // DepCache::Update - Update the deps list of a package /*{{{*/
536 // ---------------------------------------------------------------------
537 /* This is a helper for update that only does the dep portion of the scan.
538 It is mainly ment to scan reverse dependencies. */
539 void pkgDepCache::Update(DepIterator D
)
541 // Update the reverse deps
542 for (;D
.end() != true; D
++)
544 unsigned char &State
= DepState
[D
->ID
];
545 State
= DependencyState(D
);
547 // Invert for Conflicts
548 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
551 RemoveStates(D
.ParentPkg());
552 BuildGroupOrs(D
.ParentVer());
553 UpdateVerState(D
.ParentPkg());
554 AddStates(D
.ParentPkg());
558 // DepCache::Update - Update the related deps of a package /*{{{*/
559 // ---------------------------------------------------------------------
560 /* This is called whenever the state of a package changes. It updates
561 all cached dependencies related to this package. */
562 void pkgDepCache::Update(PkgIterator
const &Pkg
)
564 // Recompute the dep of the package
569 // Update the reverse deps
570 Update(Pkg
.RevDependsList());
572 // Update the provides map for the current ver
573 if (Pkg
->CurrentVer
!= 0)
574 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
575 P
.end() != true; P
++)
576 Update(P
.ParentPkg().RevDependsList());
578 // Update the provides map for the candidate ver
579 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
580 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
581 P
.end() != true; P
++)
582 Update(P
.ParentPkg().RevDependsList());
587 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
588 // ---------------------------------------------------------------------
590 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
,bool Soft
)
592 // Simplifies other routines.
593 if (Pkg
.end() == true)
596 /* Reject an attempt to keep a non-source broken installed package, those
598 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
599 Pkg
.CurrentVer().Downloadable() == false)
602 /* We changed the soft state all the time so the UI is a bit nicer
604 StateCache
&P
= PkgState
[Pkg
->ID
];
606 P
.iFlags
|= AutoKept
;
608 P
.iFlags
&= ~AutoKept
;
610 // Check that it is not already kept
611 if (P
.Mode
== ModeKeep
)
614 // We dont even try to keep virtual packages..
615 if (Pkg
->VersionList
== 0)
618 P
.Flags
&= ~Flag::Auto
;
623 if (Pkg
->CurrentVer
== 0)
626 P
.InstallVer
= Pkg
.CurrentVer();
635 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
636 // ---------------------------------------------------------------------
638 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
)
640 // Simplifies other routines.
641 if (Pkg
.end() == true)
644 // Check that it is not already marked for delete
645 StateCache
&P
= PkgState
[Pkg
->ID
];
646 P
.iFlags
&= ~(AutoKept
| Purge
);
650 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
651 (Pkg
.Purge() == true || rPurge
== false))
654 // We dont even try to delete virtual packages..
655 if (Pkg
->VersionList
== 0)
661 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
666 // This was not inverted before, but I think it should be
667 P
.Flags
&= ~Flag::Auto
;
674 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
675 // ---------------------------------------------------------------------
677 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
683 // Simplifies other routines.
684 if (Pkg
.end() == true)
687 /* Check that it is not already marked for install and that it can be
689 StateCache
&P
= PkgState
[Pkg
->ID
];
690 P
.iFlags
&= ~AutoKept
;
691 if (P
.InstBroken() == false && (P
.Mode
== ModeInstall
||
692 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
694 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
699 // See if there is even any possible instalation candidate
700 if (P
.CandidateVer
== 0)
703 // We dont even try to install virtual packages..
704 if (Pkg
->VersionList
== 0)
707 /* Target the candidate version and remove the autoflag. We reset the
708 autoflag below if this was called recursively. Otherwise the user
709 should have the ability to de-auto a package by changing its state */
713 P
.Mode
= ModeInstall
;
714 P
.InstallVer
= P
.CandidateVer
;
715 P
.Flags
&= ~Flag::Auto
;
716 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
723 if (AutoInst
== false)
726 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
727 for (; Dep
.end() != true;)
730 DepIterator Start
= Dep
;
733 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
735 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
737 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
741 // Dep is satisfied okay.
745 /* Check if this dep should be consider for install. If it is a user
746 defined important dep and we are installed a new package then
747 it will be installed. Otherwise we only worry about critical deps */
748 if (IsImportantDep(Start
) == false)
750 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false)
753 /* If we are in an or group locate the first or that can
754 succeed. We have already cached this.. */
755 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
758 /* This bit is for processing the possibilty of an install/upgrade
759 fixing the problem */
760 SPtrArray
<Version
*> List
= Start
.AllTargets();
761 if ((DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
763 // Right, find the best version to install..
764 Version
**Cur
= List
;
765 PkgIterator P
= Start
.TargetPkg();
766 PkgIterator
InstPkg(*Cache
,0);
768 // See if there are direct matches (at the start of the list)
769 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
771 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
772 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
778 // Select the highest priority providing package
779 if (InstPkg
.end() == true)
781 pkgPrioSortList(*Cache
,Cur
);
782 for (; *Cur
!= 0; Cur
++)
784 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
785 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
792 if (InstPkg
.end() == false)
794 MarkInstall(InstPkg
,true,Depth
+ 1);
796 // Set the autoflag, after MarkInstall because MarkInstall unsets it
797 if (P
->CurrentVer
== 0)
798 PkgState
[InstPkg
->ID
].Flags
|= Flag::Auto
;
804 /* For conflicts we just de-install the package and mark as auto,
805 Conflicts may not have or groups */
806 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
)
808 for (Version
**I
= List
; *I
!= 0; I
++)
810 VerIterator
Ver(*this,*I
);
811 PkgIterator Pkg
= Ver
.ParentPkg();
814 PkgState
[Pkg
->ID
].Flags
|= Flag::Auto
;
821 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
822 // ---------------------------------------------------------------------
824 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
829 StateCache
&P
= PkgState
[Pkg
->ID
];
831 P
.iFlags
|= ReInstall
;
833 P
.iFlags
&= ~ReInstall
;
839 // DepCache::SetDirty - Switch the package between dirty states /*{{{*/
840 // ---------------------------------------------------------------------
842 void pkgDepCache::SetDirty(PkgIterator
const &Pkg
, pkgCache::State::PkgRemoveState To
)
844 StateCache
&P
= PkgState
[Pkg
->ID
];
848 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
849 // ---------------------------------------------------------------------
851 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
853 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
854 StateCache
&P
= PkgState
[Pkg
->ID
];
859 if (P
.CandidateVer
== P
.InstallVer
)
860 P
.InstallVer
= (Version
*)TargetVer
;
861 P
.CandidateVer
= (Version
*)TargetVer
;
869 // StateCache::Update - Compute the various static display things /*{{{*/
870 // ---------------------------------------------------------------------
871 /* This is called whenever the Candidate version changes. */
872 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
875 VerIterator Ver
= CandidateVerIter(Cache
);
877 // Use a null string or the version string
878 if (Ver
.end() == true)
881 CandVersion
= Ver
.VerStr();
883 // Find the current version
885 if (Pkg
->CurrentVer
!= 0)
886 CurVersion
= Pkg
.CurrentVer().VerStr();
888 // Strip off the epochs for display
889 CurVersion
= StripEpoch(CurVersion
);
890 CandVersion
= StripEpoch(CandVersion
);
892 // Figure out if its up or down or equal
893 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
894 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
898 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
899 // ---------------------------------------------------------------------
901 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
907 for (const char *I
= Ver
; *I
!= 0; I
++)
914 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
915 // ---------------------------------------------------------------------
916 /* The default just returns the highest available version that is not
917 a source and automatic. */
918 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
920 /* Not source/not automatic versions cannot be a candidate version
921 unless they are already installed */
922 VerIterator
Last(*(pkgCache
*)this,0);
924 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
926 if (Pkg
.CurrentVer() == I
)
929 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
931 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
934 /* Stash the highest version of a not-automatic source, we use it
935 if there is nothing better */
936 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
938 if (Last
.end() == true)
950 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
951 // ---------------------------------------------------------------------
953 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
955 return Dep
.IsCritical();