]> git.saurik.com Git - apt.git/blame - apt-pkg/depcache.cc
Hopefully fixed the scan bug
[apt.git] / apt-pkg / depcache.cc
CommitLineData
6c139d6e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
9df5e357 3// $Id: depcache.cc,v 1.14 1998/12/22 08:01:04 jgg Exp $
6c139d6e
AL
4/* ######################################################################
5
6 Dependency Cache - Caches Dependency information.
7
8 ##################################################################### */
9 /*}}}*/
10// Include Files /*{{{*/
11#ifdef __GNUG__
094a497d 12#pragma implementation "apt-pkg/depcache.h"
6c139d6e 13#endif
094a497d 14#include <apt-pkg/depcache.h>
6c139d6e 15
094a497d
AL
16#include <apt-pkg/version.h>
17#include <apt-pkg/error.h>
6c139d6e
AL
18 /*}}}*/
19
20// DepCache::pkgDepCache - Constructors /*{{{*/
21// ---------------------------------------------------------------------
22/* */
a246f2dc
AL
23pkgDepCache::pkgDepCache(MMap &Map,OpProgress &Prog) :
24 pkgCache(Map), PkgState(0), DepState(0)
6c139d6e
AL
25{
26 if (_error->PendingError() == false)
a246f2dc 27 Init(&Prog);
981d20eb
AL
28}
29pkgDepCache::pkgDepCache(MMap &Map) :
30 pkgCache(Map), PkgState(0), DepState(0)
31{
32 if (_error->PendingError() == false)
33 Init(0);
6c139d6e
AL
34}
35 /*}}}*/
36// DepCache::~pkgDepCache - Destructor /*{{{*/
37// ---------------------------------------------------------------------
38/* */
39pkgDepCache::~pkgDepCache()
40{
41 delete [] PkgState;
42 delete [] DepState;
43}
44 /*}}}*/
6c139d6e
AL
45// DepCache::Init - Generate the initial extra structures. /*{{{*/
46// ---------------------------------------------------------------------
47/* This allocats the extension buffers and initializes them. */
a246f2dc 48bool pkgDepCache::Init(OpProgress *Prog)
6c139d6e
AL
49{
50 delete [] PkgState;
51 delete [] DepState;
52 PkgState = new StateCache[Head().PackageCount];
53 DepState = new unsigned char[Head().DependsCount];
54 memset(PkgState,0,sizeof(*PkgState)*Head().PackageCount);
55 memset(DepState,0,sizeof(*DepState)*Head().DependsCount);
56
a246f2dc
AL
57 if (Prog != 0)
58 {
59 Prog->OverallProgress(0,2*Head().PackageCount,Head().PackageCount,
c217f42a 60 "Building Dependency Tree");
a246f2dc
AL
61 Prog->SubProgress(Head().PackageCount,"Candidate Versions");
62 }
63
6c139d6e
AL
64 /* Set the current state of everything. In this state all of the
65 packages are kept exactly as is. See AllUpgrade */
a246f2dc
AL
66 int Done = 0;
67 for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
6c139d6e 68 {
a246f2dc
AL
69 if (Prog != 0)
70 Prog->Progress(Done);
71
6c139d6e
AL
72 // Find the proper cache slot
73 StateCache &State = PkgState[I->ID];
74 State.iFlags = 0;
75
76 // Figure out the install version
77 State.CandidateVer = GetCandidateVer(I);
78 State.InstallVer = I.CurrentVer();
79 State.Mode = ModeKeep;
80
81 State.Update(I,*this);
82 }
83
a246f2dc
AL
84 if (Prog != 0)
85 {
86
87 Prog->OverallProgress(Head().PackageCount,2*Head().PackageCount,
88 Head().PackageCount,
c217f42a 89 "Building Dependency Tree");
a246f2dc
AL
90 Prog->SubProgress(Head().PackageCount,"Dependency Generation");
91 }
92
93 Update(Prog);
6c139d6e
AL
94
95 return true;
96}
97 /*}}}*/
98// DepCache::GetCandidateVer - Returns the Candidate install version /*{{{*/
99// ---------------------------------------------------------------------
100/* The default just returns the target version if it exists or the
101 highest version. */
102pkgDepCache::VerIterator pkgDepCache::GetCandidateVer(PkgIterator Pkg)
103{
104 // Try to use an explicit target
105 if (Pkg->TargetVer == 0)
106 {
9df5e357
AL
107 /* Not source/not automatic versions cannot be a candidate version
108 unless they are already installed */
109 for (VerIterator I = Pkg.VersionList(); I.end() == false; I++)
54db1034 110 {
9df5e357
AL
111 if (Pkg.CurrentVer() == I)
112 return I;
113 for (VerFileIterator J = I.FileList(); J.end() == false; J++)
114 if ((J.File()->Flags & Flag::NotSource) == 0 &&
115 (J.File()->Flags & Flag::NotAutomatic) == 0)
116 return I;
54db1034 117 }
9df5e357 118
6c139d6e
AL
119 return VerIterator(*this,0);
120 }
121 else
122 return Pkg.TargetVer();
123}
124 /*}}}*/
125// DepCache::IsImportantDep - True if the dependency is important /*{{{*/
126// ---------------------------------------------------------------------
127/* */
128bool pkgDepCache::IsImportantDep(DepIterator Dep)
129{
130 return Dep.IsCritical();
131}
132 /*}}}*/
133
134// DepCache::CheckDep - Checks a single dependency /*{{{*/
135// ---------------------------------------------------------------------
136/* This first checks the dependency against the main target package and
137 then walks along the package provides list and checks if each provides
138 will be installed then checks the provides against the dep. Res will be
139 set to the package which was used to satisfy the dep. */
140bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
141{
142 Res = Dep.TargetPkg();
143
144 /* Check simple depends. A depends -should- never self match but
145 we allow it anyhow because dpkg does. Technically it is a packaging
146 bug. Conflicts may never self match */
147 if (Dep.TargetPkg() != Dep.ParentPkg() || Dep->Type != Dep::Conflicts)
148 {
149 PkgIterator Pkg = Dep.TargetPkg();
150 // Check the base package
151 if (Type == NowVersion && Pkg->CurrentVer != 0)
152 if (pkgCheckDep(Dep.TargetVer(),
153 Pkg.CurrentVer().VerStr(),Dep->CompareOp) == true)
154 return true;
155
156 if (Type == InstallVersion && PkgState[Pkg->ID].InstallVer != 0)
157 if (pkgCheckDep(Dep.TargetVer(),
158 PkgState[Pkg->ID].InstVerIter(*this).VerStr(),
159 Dep->CompareOp) == true)
160 return true;
161
162 if (Type == CandidateVersion && PkgState[Pkg->ID].CandidateVer != 0)
163 if (pkgCheckDep(Dep.TargetVer(),
164 PkgState[Pkg->ID].CandidateVerIter(*this).VerStr(),
165 Dep->CompareOp) == true)
166 return true;
167 }
168
169 // Check the providing packages
170 PrvIterator P = Dep.TargetPkg().ProvidesList();
171 PkgIterator Pkg = Dep.ParentPkg();
172 for (; P.end() != true; P++)
173 {
174 /* Provides may never be applied against the same package if it is
175 a conflicts. See the comment above. */
176 if (P.OwnerPkg() == Pkg && Dep->Type == Dep::Conflicts)
177 continue;
178
179 // Check if the provides is a hit
180 if (Type == NowVersion)
181 {
182 if (P.OwnerPkg().CurrentVer() != P.OwnerVer())
183 continue;
184 }
185
186 if (Type == InstallVersion)
187 {
188 StateCache &State = PkgState[P.OwnerPkg()->ID];
189 if (State.InstallVer != (Version *)P.OwnerVer())
190 continue;
191 }
192
193 if (Type == CandidateVersion)
194 {
195 StateCache &State = PkgState[P.OwnerPkg()->ID];
196 if (State.CandidateVer != (Version *)P.OwnerVer())
197 continue;
198 }
199
200 // Compare the versions.
201 if (pkgCheckDep(Dep.TargetVer(),P.ProvideVersion(),Dep->CompareOp) == true)
202 {
203 Res = P.OwnerPkg();
204 return true;
205 }
206 }
207
208 return false;
209}
210 /*}}}*/
211// DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
212// ---------------------------------------------------------------------
213/* Call with Mult = -1 to preform the inverse opration */
214void pkgDepCache::AddSizes(const PkgIterator &Pkg,long Mult)
215{
216 StateCache &P = PkgState[Pkg->ID];
217
2cca3bd9
AL
218 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure)
219 {
220 iUsrSize += Mult*P.InstVerIter(*this)->InstalledSize;
221 return;
222 }
223
6c139d6e
AL
224 // Compute the size data
225 if (P.NewInstall() == true)
226 {
227 iUsrSize += Mult*P.InstVerIter(*this)->InstalledSize;
228 iDownloadSize += Mult*P.InstVerIter(*this)->Size;
d38b7b3d 229 return;
6c139d6e
AL
230 }
231
232 // Upgrading
233 if (Pkg->CurrentVer != 0 && P.InstallVer != (Version *)Pkg.CurrentVer() &&
234 P.InstallVer != 0)
235 {
7a658e66
AL
236 iUsrSize += Mult*((signed)P.InstVerIter(*this)->InstalledSize -
237 (signed)Pkg.CurrentVer()->InstalledSize);
6c139d6e 238 iDownloadSize += Mult*P.InstVerIter(*this)->Size;
d38b7b3d
AL
239 return;
240 }
241
242 // Reinstall
2cca3bd9
AL
243 if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack &&
244 P.Delete() == false)
d38b7b3d
AL
245 {
246 iDownloadSize += Mult*P.InstVerIter(*this)->Size;
247 return;
6c139d6e
AL
248 }
249
250 // Removing
251 if (Pkg->CurrentVer != 0 && P.InstallVer == 0)
d38b7b3d 252 {
6c139d6e 253 iUsrSize -= Mult*Pkg.CurrentVer()->InstalledSize;
d38b7b3d
AL
254 return;
255 }
6c139d6e
AL
256}
257 /*}}}*/
258// DepCache::AddStates - Add the package to the state counter /*{{{*/
259// ---------------------------------------------------------------------
260/* This routine is tricky to use, you must make sure that it is never
261 called twice for the same package. This means the Remove/Add section
262 should be as short as possible and not encompass any code that will
263 calld Remove/Add itself. Remember, dependencies can be circular so
264 while processing a dep for Pkg it is possible that Add/Remove
265 will be called on Pkg */
266void pkgDepCache::AddStates(const PkgIterator &Pkg,int Add)
267{
268 StateCache &State = PkgState[Pkg->ID];
269
270 // The Package is broken
271 if ((State.DepState & DepInstMin) != DepInstMin)
272 iBrokenCount += Add;
273
274 // Bad state
275 if (Pkg.State() != PkgIterator::NeedsNothing)
276 iBadCount += Add;
277
278 // Not installed
279 if (Pkg->CurrentVer == 0)
280 {
281 if (State.Mode == ModeInstall)
282 iInstCount += Add;
283 return;
284 }
285
286 // Installed, no upgrade
287 if (State.Upgradable() == false)
288 {
289 if (State.Mode == ModeDelete)
290 iDelCount += Add;
291 return;
292 }
293
294 // Alll 3 are possible
295 if (State.Mode == ModeDelete)
296 iDelCount += Add;
297 if (State.Mode == ModeKeep)
298 iKeepCount += Add;
299 if (State.Mode == ModeInstall)
300 iInstCount += Add;
301}
302 /*}}}*/
303// DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
304// ---------------------------------------------------------------------
305/* The or group results are stored in the last item of the or group. This
306 allows easy detection of the state of a whole or'd group. */
307void pkgDepCache::BuildGroupOrs(VerIterator const &V)
308{
309 unsigned char Group = 0;
310
311 for (DepIterator D = V.DependsList(); D.end() != true; D++)
312 {
313 // Build the dependency state.
314 unsigned char &State = DepState[D->ID];
315
316 /* Invert for Conflicts. We have to do this twice to get the
317 right sense for a conflicts group */
318 if (D->Type == Dep::Conflicts)
319 State = ~State;
320
321 // Add to the group if we are within an or..
d2685fd6 322 State &= 0x7;
6c139d6e
AL
323 Group |= State;
324 State |= Group << 3;
325 if ((D->CompareOp & Dep::Or) != Dep::Or)
326 Group = 0;
327
328 // Invert for Conflicts
329 if (D->Type == Dep::Conflicts)
330 State = ~State;
331 }
332}
333 /*}}}*/
334// DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
335// ---------------------------------------------------------------------
336/* This is used to run over a dependency list and determine the dep
337 state of the list, filtering it through both a Min check and a Policy
338 check. The return result will have SetMin/SetPolicy low if a check
339 fails. It uses the DepState cache for it's computations. */
340unsigned char pkgDepCache::VersionState(DepIterator D,unsigned char Check,
341 unsigned char SetMin,
342 unsigned char SetPolicy)
343{
344 unsigned char Dep = 0xFF;
345
346 while (D.end() != true)
347 {
348 // Compute a single dependency element (glob or)
349 DepIterator Start = D;
350 unsigned char State = 0;
351 for (bool LastOR = true; D.end() == false && LastOR == true; D++)
352 {
353 State |= DepState[D->ID];
354 LastOR = (D->CompareOp & Dep::Or) == Dep::Or;
355 }
356
357 // Minimum deps that must be satisfied to have a working package
358 if (Start.IsCritical() == true)
359 if ((State & Check) != Check)
360 Dep &= ~SetMin;
361
362 // Policy deps that must be satisfied to install the package
363 if (IsImportantDep(Start) == true &&
364 (State & Check) != Check)
365 Dep &= ~SetPolicy;
366 }
367
368 return Dep;
369}
370 /*}}}*/
371// DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
372// ---------------------------------------------------------------------
373/* This is the main dependency computation bit. It computes the 3 main
374 results for a dependencys, Now, Install and Candidate. Callers must
375 invert the result if dealing with conflicts. */
376unsigned char pkgDepCache::DependencyState(DepIterator &D)
377{
378 unsigned char State = 0;
379
380 if (CheckDep(D,NowVersion) == true)
381 State |= DepNow;
382 if (CheckDep(D,InstallVersion) == true)
383 State |= DepInstall;
384 if (CheckDep(D,CandidateVersion) == true)
385 State |= DepCVer;
386
387 return State;
388}
389 /*}}}*/
390// DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
391// ---------------------------------------------------------------------
392/* This determines the combined dependency representation of a package
393 for its two states now and install. This is done by using the pre-generated
394 dependency information. */
395void pkgDepCache::UpdateVerState(PkgIterator Pkg)
396{
397 // Empty deps are always true
398 StateCache &State = PkgState[Pkg->ID];
399 State.DepState = 0xFF;
400
401 // Check the Current state
402 if (Pkg->CurrentVer != 0)
403 {
404 DepIterator D = Pkg.CurrentVer().DependsList();
405 State.DepState &= VersionState(D,DepNow,DepNowMin,DepNowPolicy);
406 }
407
408 /* Check the candidate state. We do not compare against the whole as
409 a candidate state but check the candidate version against the
410 install states */
411 if (State.CandidateVer != 0)
412 {
413 DepIterator D = State.CandidateVerIter(*this).DependsList();
414 State.DepState &= VersionState(D,DepInstall,DepCandMin,DepCandPolicy);
415 }
416
417 // Check target state which can only be current or installed
418 if (State.InstallVer != 0)
419 {
420 DepIterator D = State.InstVerIter(*this).DependsList();
421 State.DepState &= VersionState(D,DepInstall,DepInstMin,DepInstPolicy);
422 }
423}
424 /*}}}*/
425// DepCache::Update - Figure out all the state information /*{{{*/
426// ---------------------------------------------------------------------
427/* This will figure out the state of all the packages and all the
428 dependencies based on the current policy. */
a246f2dc 429void pkgDepCache::Update(OpProgress *Prog)
6c139d6e
AL
430{
431 iUsrSize = 0;
432 iDownloadSize = 0;
433 iDelCount = 0;
434 iInstCount = 0;
435 iKeepCount = 0;
436 iBrokenCount = 0;
437 iBadCount = 0;
438
439 // Perform the depends pass
a246f2dc
AL
440 int Done = 0;
441 for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
6c139d6e 442 {
a246f2dc
AL
443 if (Prog != 0 && Done%20 == 0)
444 Prog->Progress(Done);
6c139d6e
AL
445 for (VerIterator V = I.VersionList(); V.end() != true; V++)
446 {
447 unsigned char Group = 0;
448
449 for (DepIterator D = V.DependsList(); D.end() != true; D++)
450 {
451 // Build the dependency state.
452 unsigned char &State = DepState[D->ID];
453 State = DependencyState(D);;
454
455 // Add to the group if we are within an or..
456 Group |= State;
457 State |= Group << 3;
458 if ((D->CompareOp & Dep::Or) != Dep::Or)
459 Group = 0;
460
461 // Invert for Conflicts
462 if (D->Type == Dep::Conflicts)
463 State = ~State;
464 }
465 }
466
467 // Compute the pacakge dependency state and size additions
468 AddSizes(I);
469 UpdateVerState(I);
470 AddStates(I);
471 }
a246f2dc
AL
472
473 if (Prog != 0)
474 Prog->Progress(Done);
6c139d6e
AL
475}
476 /*}}}*/
477// DepCache::Update - Update the deps list of a package /*{{{*/
478// ---------------------------------------------------------------------
479/* This is a helper for update that only does the dep portion of the scan.
480 It is mainly ment to scan reverse dependencies. */
481void pkgDepCache::Update(DepIterator D)
482{
483 // Update the reverse deps
484 for (;D.end() != true; D++)
485 {
486 unsigned char &State = DepState[D->ID];
487 State = DependencyState(D);
488
489 // Invert for Conflicts
490 if (D->Type == Dep::Conflicts)
491 State = ~State;
492
493 RemoveStates(D.ParentPkg());
494 BuildGroupOrs(D.ParentVer());
495 UpdateVerState(D.ParentPkg());
496 AddStates(D.ParentPkg());
497 }
498}
499 /*}}}*/
500// DepCache::Update - Update the related deps of a package /*{{{*/
501// ---------------------------------------------------------------------
502/* This is called whenever the state of a package changes. It updates
503 all cached dependencies related to this package. */
504void pkgDepCache::Update(PkgIterator const &Pkg)
505{
506 // Recompute the dep of the package
507 RemoveStates(Pkg);
508 UpdateVerState(Pkg);
509 AddStates(Pkg);
510
511 // Update the reverse deps
512 Update(Pkg.RevDependsList());
513
514 // Update the provides map for the current ver
515 if (Pkg->CurrentVer != 0)
516 for (PrvIterator P = Pkg.CurrentVer().ProvidesList();
517 P.end() != true; P++)
518 Update(P.ParentPkg().RevDependsList());
519
520 // Update the provides map for the candidate ver
521 for (PrvIterator P = PkgState[Pkg->ID].CandidateVerIter(*this).ProvidesList();
522 P.end() != true; P++)
523 Update(P.ParentPkg().RevDependsList());
524}
525
526 /*}}}*/
527
528// DepCache::MarkKeep - Put the package in the keep state /*{{{*/
529// ---------------------------------------------------------------------
530/* */
531void pkgDepCache::MarkKeep(PkgIterator const &Pkg,bool Soft)
532{
533 // Simplifies other routines.
534 if (Pkg.end() == true)
535 return;
536
537 /* We changed the soft state all the time so the UI is a bit nicer
538 to use */
539 StateCache &P = PkgState[Pkg->ID];
540 if (Soft == true)
541 P.iFlags |= AutoKept;
542 else
543 P.iFlags &= ~AutoKept;
544
545 // Check that it is not already kept
546 if (P.Mode == ModeKeep)
547 return;
548
549 // We dont even try to keep virtual packages..
550 if (Pkg->VersionList == 0)
551 return;
552
553 P.Flags &= ~Flag::Auto;
554 RemoveSizes(Pkg);
555 RemoveStates(Pkg);
556
557 P.Mode = ModeKeep;
558 if (Pkg->CurrentVer == 0)
559 P.InstallVer = 0;
560 else
561 P.InstallVer = Pkg.CurrentVer();
562
563 AddStates(Pkg);
564
565 Update(Pkg);
566
567 AddSizes(Pkg);
568}
569 /*}}}*/
570// DepCache::MarkDelete - Put the package in the delete state /*{{{*/
571// ---------------------------------------------------------------------
572/* */
573void pkgDepCache::MarkDelete(PkgIterator const &Pkg)
574{
575 // Simplifies other routines.
576 if (Pkg.end() == true)
577 return;
578
579 // Check that it is not already marked for delete
580 StateCache &P = PkgState[Pkg->ID];
581 P.iFlags &= ~AutoKept;
582 if (P.Mode == ModeDelete || P.InstallVer == 0)
583 return;
584
585 // We dont even try to delete virtual packages..
586 if (Pkg->VersionList == 0)
587 return;
588
589 RemoveSizes(Pkg);
590 RemoveStates(Pkg);
591
3d615484
AL
592 if (Pkg->CurrentVer == 0)
593 P.Mode = ModeKeep;
594 else
595 P.Mode = ModeDelete;
6c139d6e
AL
596 P.InstallVer = 0;
597 P.Flags &= Flag::Auto;
598
599 AddStates(Pkg);
600 Update(Pkg);
601 AddSizes(Pkg);
602}
603 /*}}}*/
604// DepCache::MarkInstall - Put the package in the install state /*{{{*/
605// ---------------------------------------------------------------------
606/* */
607void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst)
608{
609 // Simplifies other routines.
610 if (Pkg.end() == true)
611 return;
612
613 /* Check that it is not already marked for install and that it can be
614 installed */
615 StateCache &P = PkgState[Pkg->ID];
616 P.iFlags &= ~AutoKept;
617 if (P.InstBroken() == false && (P.Mode == ModeInstall ||
618 P.CandidateVer == (Version *)Pkg.CurrentVer()))
619 {
620 if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
621 MarkKeep(Pkg);
622 return;
623 }
624
625 // We dont even try to install virtual packages..
626 if (Pkg->VersionList == 0)
627 return;
628
629 /* Target the candidate version and remove the autoflag. We reset the
630 autoflag below if this was called recursively. Otherwise the user
631 should have the ability to de-auto a package by changing its state */
632 RemoveSizes(Pkg);
633 RemoveStates(Pkg);
634
635 P.Mode = ModeInstall;
636 P.InstallVer = P.CandidateVer;
637 P.Flags &= ~Flag::Auto;
638 if (P.CandidateVer == (Version *)Pkg.CurrentVer())
639 P.Mode = ModeKeep;
640
641 AddStates(Pkg);
642 Update(Pkg);
643 AddSizes(Pkg);
644
645 if (AutoInst == false)
646 return;
647
648 DepIterator Dep = P.InstVerIter(*this).DependsList();
649 for (; Dep.end() != true;)
650 {
651 // Grok or groups
652 DepIterator Start = Dep;
653 bool Result = true;
654 for (bool LastOR = true; Dep.end() == false && LastOR == true; Dep++)
655 {
656 LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or;
657
658 if ((DepState[Dep->ID] & DepInstall) == DepInstall)
659 Result = false;
660 }
661
662 // Dep is satisfied okay.
663 if (Result == false)
664 continue;
665
666 /* Check if this dep should be consider for install. If it is a user
667 defined important dep and we are installed a new package then
668 it will be installed. Otherwise we only worry about critical deps */
669 if (IsImportantDep(Start) == false)
670 continue;
671 if (Pkg->CurrentVer != 0 && Start.IsCritical() == false)
672 continue;
673
674 // Now we have to take action...
675 PkgIterator P = Start.SmartTargetPkg();
676 if ((DepState[Start->ID] & DepCVer) == DepCVer)
677 {
678 MarkInstall(P,true);
679
680 // Set the autoflag, after MarkInstall because MarkInstall unsets it
681 if (P->CurrentVer == 0)
682 PkgState[P->ID].Flags |= Flag::Auto;
683
684 continue;
685 }
686
687 // For conflicts we just de-install the package and mark as auto
688 if (Start->Type == Dep::Conflicts)
689 {
690 Version **List = Start.AllTargets();
691 for (Version **I = List; *I != 0; I++)
692 {
693 VerIterator Ver(*this,*I);
694 PkgIterator Pkg = Ver.ParentPkg();
695
696 MarkDelete(Pkg);
697 PkgState[Pkg->ID].Flags |= Flag::Auto;
698 }
699 delete [] List;
700 continue;
701 }
702 }
703}
704 /*}}}*/
705
6c139d6e
AL
706// StateCache::Update - Compute the various static display things /*{{{*/
707// ---------------------------------------------------------------------
708/* This is called whenever the Candidate version changes. */
709void pkgDepCache::StateCache::Update(PkgIterator Pkg,pkgCache &Cache)
710{
711 // Some info
712 VerIterator Ver = CandidateVerIter(Cache);
713
714 // Use a null string or the version string
715 if (Ver.end() == true)
716 CandVersion = "";
717 else
718 CandVersion = Ver.VerStr();
719
720 // Find the current version
721 CurVersion = "";
722 if (Pkg->CurrentVer != 0)
723 CurVersion = Pkg.CurrentVer().VerStr();
724
725 // Strip off the epochs for display
726 CurVersion = StripEpoch(CurVersion);
727 CandVersion = StripEpoch(CandVersion);
728
729 // Figure out if its up or down or equal
730 Status = Ver.CompareVer(Pkg.CurrentVer());
731 if (Pkg->CurrentVer == 0 || Pkg->VersionList == 0 || CandidateVer == 0)
732 Status = 2;
733}
734 /*}}}*/
735// StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
736// ---------------------------------------------------------------------
737/* */
738const char *pkgDepCache::StateCache::StripEpoch(const char *Ver)
739{
740 if (Ver == 0)
741 return 0;
742
743 // Strip any epoch
744 for (const char *I = Ver; *I != 0; I++)
745 if (*I == ':')
746 return I + 1;
747 return Ver;
748}
749 /*}}}*/