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