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