Fixed typo in the shared lib rule
[ntk/apt.git] / apt-pkg / depcache.cc
CommitLineData
6c139d6e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
e5a1f2ff 3// $Id: depcache.cc,v 1.15 1999/03/26 07:38:43 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
e5a1f2ff
AL
218 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
219 P.Keep() == true)
2cca3bd9
AL
220 {
221 iUsrSize += Mult*P.InstVerIter(*this)->InstalledSize;
222 return;
223 }
224
6c139d6e
AL
225 // Compute the size data
226 if (P.NewInstall() == true)
227 {
228 iUsrSize += Mult*P.InstVerIter(*this)->InstalledSize;
229 iDownloadSize += Mult*P.InstVerIter(*this)->Size;
d38b7b3d 230 return;
6c139d6e
AL
231 }
232
233 // Upgrading
234 if (Pkg->CurrentVer != 0 && P.InstallVer != (Version *)Pkg.CurrentVer() &&
235 P.InstallVer != 0)
236 {
7a658e66
AL
237 iUsrSize += Mult*((signed)P.InstVerIter(*this)->InstalledSize -
238 (signed)Pkg.CurrentVer()->InstalledSize);
6c139d6e 239 iDownloadSize += Mult*P.InstVerIter(*this)->Size;
d38b7b3d
AL
240 return;
241 }
242
243 // Reinstall
2cca3bd9
AL
244 if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack &&
245 P.Delete() == false)
d38b7b3d
AL
246 {
247 iDownloadSize += Mult*P.InstVerIter(*this)->Size;
248 return;
6c139d6e
AL
249 }
250
251 // Removing
252 if (Pkg->CurrentVer != 0 && P.InstallVer == 0)
d38b7b3d 253 {
6c139d6e 254 iUsrSize -= Mult*Pkg.CurrentVer()->InstalledSize;
d38b7b3d
AL
255 return;
256 }
6c139d6e
AL
257}
258 /*}}}*/
259// DepCache::AddStates - Add the package to the state counter /*{{{*/
260// ---------------------------------------------------------------------
261/* This routine is tricky to use, you must make sure that it is never
262 called twice for the same package. This means the Remove/Add section
263 should be as short as possible and not encompass any code that will
264 calld Remove/Add itself. Remember, dependencies can be circular so
265 while processing a dep for Pkg it is possible that Add/Remove
266 will be called on Pkg */
267void pkgDepCache::AddStates(const PkgIterator &Pkg,int Add)
268{
269 StateCache &State = PkgState[Pkg->ID];
270
271 // The Package is broken
272 if ((State.DepState & DepInstMin) != DepInstMin)
273 iBrokenCount += Add;
274
275 // Bad state
276 if (Pkg.State() != PkgIterator::NeedsNothing)
277 iBadCount += Add;
278
279 // Not installed
280 if (Pkg->CurrentVer == 0)
281 {
282 if (State.Mode == ModeInstall)
283 iInstCount += Add;
284 return;
285 }
286
287 // Installed, no upgrade
288 if (State.Upgradable() == false)
289 {
290 if (State.Mode == ModeDelete)
291 iDelCount += Add;
292 return;
293 }
294
295 // Alll 3 are possible
296 if (State.Mode == ModeDelete)
297 iDelCount += Add;
298 if (State.Mode == ModeKeep)
299 iKeepCount += Add;
300 if (State.Mode == ModeInstall)
301 iInstCount += Add;
302}
303 /*}}}*/
304// DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
305// ---------------------------------------------------------------------
306/* The or group results are stored in the last item of the or group. This
307 allows easy detection of the state of a whole or'd group. */
308void pkgDepCache::BuildGroupOrs(VerIterator const &V)
309{
310 unsigned char Group = 0;
311
312 for (DepIterator D = V.DependsList(); D.end() != true; D++)
313 {
314 // Build the dependency state.
315 unsigned char &State = DepState[D->ID];
316
317 /* Invert for Conflicts. We have to do this twice to get the
318 right sense for a conflicts group */
319 if (D->Type == Dep::Conflicts)
320 State = ~State;
321
322 // Add to the group if we are within an or..
d2685fd6 323 State &= 0x7;
6c139d6e
AL
324 Group |= State;
325 State |= Group << 3;
326 if ((D->CompareOp & Dep::Or) != Dep::Or)
327 Group = 0;
328
329 // Invert for Conflicts
330 if (D->Type == Dep::Conflicts)
331 State = ~State;
332 }
333}
334 /*}}}*/
335// DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
336// ---------------------------------------------------------------------
337/* This is used to run over a dependency list and determine the dep
338 state of the list, filtering it through both a Min check and a Policy
339 check. The return result will have SetMin/SetPolicy low if a check
340 fails. It uses the DepState cache for it's computations. */
341unsigned char pkgDepCache::VersionState(DepIterator D,unsigned char Check,
342 unsigned char SetMin,
343 unsigned char SetPolicy)
344{
345 unsigned char Dep = 0xFF;
346
347 while (D.end() != true)
348 {
349 // Compute a single dependency element (glob or)
350 DepIterator Start = D;
351 unsigned char State = 0;
352 for (bool LastOR = true; D.end() == false && LastOR == true; D++)
353 {
354 State |= DepState[D->ID];
355 LastOR = (D->CompareOp & Dep::Or) == Dep::Or;
356 }
357
358 // Minimum deps that must be satisfied to have a working package
359 if (Start.IsCritical() == true)
360 if ((State & Check) != Check)
361 Dep &= ~SetMin;
362
363 // Policy deps that must be satisfied to install the package
364 if (IsImportantDep(Start) == true &&
365 (State & Check) != Check)
366 Dep &= ~SetPolicy;
367 }
368
369 return Dep;
370}
371 /*}}}*/
372// DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
373// ---------------------------------------------------------------------
374/* This is the main dependency computation bit. It computes the 3 main
375 results for a dependencys, Now, Install and Candidate. Callers must
376 invert the result if dealing with conflicts. */
377unsigned char pkgDepCache::DependencyState(DepIterator &D)
378{
379 unsigned char State = 0;
380
381 if (CheckDep(D,NowVersion) == true)
382 State |= DepNow;
383 if (CheckDep(D,InstallVersion) == true)
384 State |= DepInstall;
385 if (CheckDep(D,CandidateVersion) == true)
386 State |= DepCVer;
387
388 return State;
389}
390 /*}}}*/
391// DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
392// ---------------------------------------------------------------------
393/* This determines the combined dependency representation of a package
394 for its two states now and install. This is done by using the pre-generated
395 dependency information. */
396void pkgDepCache::UpdateVerState(PkgIterator Pkg)
397{
398 // Empty deps are always true
399 StateCache &State = PkgState[Pkg->ID];
400 State.DepState = 0xFF;
401
402 // Check the Current state
403 if (Pkg->CurrentVer != 0)
404 {
405 DepIterator D = Pkg.CurrentVer().DependsList();
406 State.DepState &= VersionState(D,DepNow,DepNowMin,DepNowPolicy);
407 }
408
409 /* Check the candidate state. We do not compare against the whole as
410 a candidate state but check the candidate version against the
411 install states */
412 if (State.CandidateVer != 0)
413 {
414 DepIterator D = State.CandidateVerIter(*this).DependsList();
415 State.DepState &= VersionState(D,DepInstall,DepCandMin,DepCandPolicy);
416 }
417
418 // Check target state which can only be current or installed
419 if (State.InstallVer != 0)
420 {
421 DepIterator D = State.InstVerIter(*this).DependsList();
422 State.DepState &= VersionState(D,DepInstall,DepInstMin,DepInstPolicy);
423 }
424}
425 /*}}}*/
426// DepCache::Update - Figure out all the state information /*{{{*/
427// ---------------------------------------------------------------------
428/* This will figure out the state of all the packages and all the
429 dependencies based on the current policy. */
a246f2dc 430void pkgDepCache::Update(OpProgress *Prog)
6c139d6e
AL
431{
432 iUsrSize = 0;
433 iDownloadSize = 0;
434 iDelCount = 0;
435 iInstCount = 0;
436 iKeepCount = 0;
437 iBrokenCount = 0;
438 iBadCount = 0;
439
440 // Perform the depends pass
a246f2dc
AL
441 int Done = 0;
442 for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
6c139d6e 443 {
a246f2dc
AL
444 if (Prog != 0 && Done%20 == 0)
445 Prog->Progress(Done);
6c139d6e
AL
446 for (VerIterator V = I.VersionList(); V.end() != true; V++)
447 {
448 unsigned char Group = 0;
449
450 for (DepIterator D = V.DependsList(); D.end() != true; D++)
451 {
452 // Build the dependency state.
453 unsigned char &State = DepState[D->ID];
454 State = DependencyState(D);;
455
456 // Add to the group if we are within an or..
457 Group |= State;
458 State |= Group << 3;
459 if ((D->CompareOp & Dep::Or) != Dep::Or)
460 Group = 0;
461
462 // Invert for Conflicts
463 if (D->Type == Dep::Conflicts)
464 State = ~State;
465 }
466 }
467
468 // Compute the pacakge dependency state and size additions
469 AddSizes(I);
470 UpdateVerState(I);
471 AddStates(I);
472 }
a246f2dc
AL
473
474 if (Prog != 0)
475 Prog->Progress(Done);
6c139d6e
AL
476}
477 /*}}}*/
478// DepCache::Update - Update the deps list of a package /*{{{*/
479// ---------------------------------------------------------------------
480/* This is a helper for update that only does the dep portion of the scan.
481 It is mainly ment to scan reverse dependencies. */
482void pkgDepCache::Update(DepIterator D)
483{
484 // Update the reverse deps
485 for (;D.end() != true; D++)
486 {
487 unsigned char &State = DepState[D->ID];
488 State = DependencyState(D);
489
490 // Invert for Conflicts
491 if (D->Type == Dep::Conflicts)
492 State = ~State;
493
494 RemoveStates(D.ParentPkg());
495 BuildGroupOrs(D.ParentVer());
496 UpdateVerState(D.ParentPkg());
497 AddStates(D.ParentPkg());
498 }
499}
500 /*}}}*/
501// DepCache::Update - Update the related deps of a package /*{{{*/
502// ---------------------------------------------------------------------
503/* This is called whenever the state of a package changes. It updates
504 all cached dependencies related to this package. */
505void pkgDepCache::Update(PkgIterator const &Pkg)
506{
507 // Recompute the dep of the package
508 RemoveStates(Pkg);
509 UpdateVerState(Pkg);
510 AddStates(Pkg);
511
512 // Update the reverse deps
513 Update(Pkg.RevDependsList());
514
515 // Update the provides map for the current ver
516 if (Pkg->CurrentVer != 0)
517 for (PrvIterator P = Pkg.CurrentVer().ProvidesList();
518 P.end() != true; P++)
519 Update(P.ParentPkg().RevDependsList());
520
521 // Update the provides map for the candidate ver
522 for (PrvIterator P = PkgState[Pkg->ID].CandidateVerIter(*this).ProvidesList();
523 P.end() != true; P++)
524 Update(P.ParentPkg().RevDependsList());
525}
526
527 /*}}}*/
528
529// DepCache::MarkKeep - Put the package in the keep state /*{{{*/
530// ---------------------------------------------------------------------
531/* */
532void pkgDepCache::MarkKeep(PkgIterator const &Pkg,bool Soft)
533{
534 // Simplifies other routines.
535 if (Pkg.end() == true)
536 return;
537
538 /* We changed the soft state all the time so the UI is a bit nicer
539 to use */
540 StateCache &P = PkgState[Pkg->ID];
541 if (Soft == true)
542 P.iFlags |= AutoKept;
543 else
544 P.iFlags &= ~AutoKept;
545
546 // Check that it is not already kept
547 if (P.Mode == ModeKeep)
548 return;
549
550 // We dont even try to keep virtual packages..
551 if (Pkg->VersionList == 0)
552 return;
553
554 P.Flags &= ~Flag::Auto;
555 RemoveSizes(Pkg);
556 RemoveStates(Pkg);
557
558 P.Mode = ModeKeep;
559 if (Pkg->CurrentVer == 0)
560 P.InstallVer = 0;
561 else
562 P.InstallVer = Pkg.CurrentVer();
563
564 AddStates(Pkg);
565
566 Update(Pkg);
567
568 AddSizes(Pkg);
569}
570 /*}}}*/
571// DepCache::MarkDelete - Put the package in the delete state /*{{{*/
572// ---------------------------------------------------------------------
573/* */
574void pkgDepCache::MarkDelete(PkgIterator const &Pkg)
575{
576 // Simplifies other routines.
577 if (Pkg.end() == true)
578 return;
579
580 // Check that it is not already marked for delete
581 StateCache &P = PkgState[Pkg->ID];
582 P.iFlags &= ~AutoKept;
583 if (P.Mode == ModeDelete || P.InstallVer == 0)
584 return;
585
586 // We dont even try to delete virtual packages..
587 if (Pkg->VersionList == 0)
588 return;
589
590 RemoveSizes(Pkg);
591 RemoveStates(Pkg);
592
3d615484
AL
593 if (Pkg->CurrentVer == 0)
594 P.Mode = ModeKeep;
595 else
596 P.Mode = ModeDelete;
6c139d6e
AL
597 P.InstallVer = 0;
598 P.Flags &= Flag::Auto;
599
600 AddStates(Pkg);
601 Update(Pkg);
602 AddSizes(Pkg);
603}
604 /*}}}*/
605// DepCache::MarkInstall - Put the package in the install state /*{{{*/
606// ---------------------------------------------------------------------
607/* */
608void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst)
609{
610 // Simplifies other routines.
611 if (Pkg.end() == true)
612 return;
613
614 /* Check that it is not already marked for install and that it can be
615 installed */
616 StateCache &P = PkgState[Pkg->ID];
617 P.iFlags &= ~AutoKept;
618 if (P.InstBroken() == false && (P.Mode == ModeInstall ||
619 P.CandidateVer == (Version *)Pkg.CurrentVer()))
620 {
621 if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
622 MarkKeep(Pkg);
623 return;
624 }
625
626 // We dont even try to install virtual packages..
627 if (Pkg->VersionList == 0)
628 return;
629
630 /* Target the candidate version and remove the autoflag. We reset the
631 autoflag below if this was called recursively. Otherwise the user
632 should have the ability to de-auto a package by changing its state */
633 RemoveSizes(Pkg);
634 RemoveStates(Pkg);
635
636 P.Mode = ModeInstall;
637 P.InstallVer = P.CandidateVer;
638 P.Flags &= ~Flag::Auto;
639 if (P.CandidateVer == (Version *)Pkg.CurrentVer())
640 P.Mode = ModeKeep;
641
642 AddStates(Pkg);
643 Update(Pkg);
644 AddSizes(Pkg);
645
646 if (AutoInst == false)
647 return;
648
649 DepIterator Dep = P.InstVerIter(*this).DependsList();
650 for (; Dep.end() != true;)
651 {
652 // Grok or groups
653 DepIterator Start = Dep;
654 bool Result = true;
655 for (bool LastOR = true; Dep.end() == false && LastOR == true; Dep++)
656 {
657 LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or;
658
659 if ((DepState[Dep->ID] & DepInstall) == DepInstall)
660 Result = false;
661 }
662
663 // Dep is satisfied okay.
664 if (Result == false)
665 continue;
666
667 /* Check if this dep should be consider for install. If it is a user
668 defined important dep and we are installed a new package then
669 it will be installed. Otherwise we only worry about critical deps */
670 if (IsImportantDep(Start) == false)
671 continue;
672 if (Pkg->CurrentVer != 0 && Start.IsCritical() == false)
673 continue;
674
675 // Now we have to take action...
676 PkgIterator P = Start.SmartTargetPkg();
677 if ((DepState[Start->ID] & DepCVer) == DepCVer)
678 {
679 MarkInstall(P,true);
680
681 // Set the autoflag, after MarkInstall because MarkInstall unsets it
682 if (P->CurrentVer == 0)
683 PkgState[P->ID].Flags |= Flag::Auto;
684
685 continue;
686 }
687
688 // For conflicts we just de-install the package and mark as auto
689 if (Start->Type == Dep::Conflicts)
690 {
691 Version **List = Start.AllTargets();
692 for (Version **I = List; *I != 0; I++)
693 {
694 VerIterator Ver(*this,*I);
695 PkgIterator Pkg = Ver.ParentPkg();
696
697 MarkDelete(Pkg);
698 PkgState[Pkg->ID].Flags |= Flag::Auto;
699 }
700 delete [] List;
701 continue;
702 }
703 }
704}
705 /*}}}*/
706
6c139d6e
AL
707// StateCache::Update - Compute the various static display things /*{{{*/
708// ---------------------------------------------------------------------
709/* This is called whenever the Candidate version changes. */
710void pkgDepCache::StateCache::Update(PkgIterator Pkg,pkgCache &Cache)
711{
712 // Some info
713 VerIterator Ver = CandidateVerIter(Cache);
714
715 // Use a null string or the version string
716 if (Ver.end() == true)
717 CandVersion = "";
718 else
719 CandVersion = Ver.VerStr();
720
721 // Find the current version
722 CurVersion = "";
723 if (Pkg->CurrentVer != 0)
724 CurVersion = Pkg.CurrentVer().VerStr();
725
726 // Strip off the epochs for display
727 CurVersion = StripEpoch(CurVersion);
728 CandVersion = StripEpoch(CandVersion);
729
730 // Figure out if its up or down or equal
731 Status = Ver.CompareVer(Pkg.CurrentVer());
732 if (Pkg->CurrentVer == 0 || Pkg->VersionList == 0 || CandidateVer == 0)
733 Status = 2;
734}
735 /*}}}*/
736// StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
737// ---------------------------------------------------------------------
738/* */
739const char *pkgDepCache::StateCache::StripEpoch(const char *Ver)
740{
741 if (Ver == 0)
742 return 0;
743
744 // Strip any epoch
745 for (const char *I = Ver; *I != 0; I++)
746 if (*I == ':')
747 return I + 1;
748 return Ver;
749}
750 /*}}}*/