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