]>
git.saurik.com Git - apt.git/blob - apt-pkg/pkgcache.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: pkgcache.cc,v 1.37 2003/02/10 01:40:58 doogie Exp $
4 /* ######################################################################
6 Package Cache - Accessor code for the cache
8 Please see doc/apt-pkg/cache.sgml for a more detailed description of
9 this format. Also be sure to keep that file up-to-date!!
11 This is the general utility functions for cache management. They provide
12 a complete set of accessor functions for the cache. The cacheiterators
13 header contains the STL-like iterators that can be used to easially
14 navigate the cache as well as seemlessly dereference the mmap'd
15 indexes. Use these always.
17 The main class provides for ways to get package indexes and some
18 general lookup functions to start the iterators.
20 ##################################################################### */
22 // Include Files /*{{{*/
25 #include <apt-pkg/pkgcache.h>
26 #include <apt-pkg/policy.h>
27 #include <apt-pkg/version.h>
28 #include <apt-pkg/error.h>
29 #include <apt-pkg/strutl.h>
30 #include <apt-pkg/configuration.h>
31 #include <apt-pkg/aptconfiguration.h>
32 #include <apt-pkg/mmap.h>
33 #include <apt-pkg/macros.h>
48 // Cache::Header::Header - Constructor /*{{{*/
49 // ---------------------------------------------------------------------
50 /* Simply initialize the header */
51 pkgCache::Header::Header()
53 Signature
= 0x98FE76DC;
55 /* Whenever the structures change the major version should be bumped,
56 whenever the generator changes the minor version should be bumped. */
61 HeaderSz
= sizeof(pkgCache::Header
);
62 GroupSz
= sizeof(pkgCache::Group
);
63 PackageSz
= sizeof(pkgCache::Package
);
64 PackageFileSz
= sizeof(pkgCache::PackageFile
);
65 VersionSz
= sizeof(pkgCache::Version
);
66 DescriptionSz
= sizeof(pkgCache::Description
);
67 DependencySz
= sizeof(pkgCache::Dependency
);
68 ProvidesSz
= sizeof(pkgCache::Provides
);
69 VerFileSz
= sizeof(pkgCache::VerFile
);
70 DescFileSz
= sizeof(pkgCache::DescFile
);
88 memset(PkgHashTable
,0,sizeof(PkgHashTable
));
89 memset(GrpHashTable
,0,sizeof(GrpHashTable
));
90 memset(Pools
,0,sizeof(Pools
));
95 // Cache::Header::CheckSizes - Check if the two headers have same *sz /*{{{*/
96 // ---------------------------------------------------------------------
98 bool pkgCache::Header::CheckSizes(Header
&Against
) const
100 if (HeaderSz
== Against
.HeaderSz
&&
101 GroupSz
== Against
.GroupSz
&&
102 PackageSz
== Against
.PackageSz
&&
103 PackageFileSz
== Against
.PackageFileSz
&&
104 VersionSz
== Against
.VersionSz
&&
105 DescriptionSz
== Against
.DescriptionSz
&&
106 DependencySz
== Against
.DependencySz
&&
107 VerFileSz
== Against
.VerFileSz
&&
108 DescFileSz
== Against
.DescFileSz
&&
109 ProvidesSz
== Against
.ProvidesSz
)
115 // Cache::pkgCache - Constructor /*{{{*/
116 // ---------------------------------------------------------------------
118 pkgCache::pkgCache(MMap
*Map
, bool DoMap
) : Map(*Map
)
120 // call getArchitectures() with cached=false to ensure that the
121 // architectures cache is re-evaulated. this is needed in cases
122 // when the APT::Architecture field changes between two cache creations
123 MultiArchEnabled
= APT::Configuration::getArchitectures(false).size() > 1;
128 // Cache::ReMap - Reopen the cache file /*{{{*/
129 // ---------------------------------------------------------------------
130 /* If the file is already closed then this will open it open it. */
131 bool pkgCache::ReMap(bool const &Errorchecks
)
133 // Apply the typecasts.
134 HeaderP
= (Header
*)Map
.Data();
135 GrpP
= (Group
*)Map
.Data();
136 PkgP
= (Package
*)Map
.Data();
137 VerFileP
= (VerFile
*)Map
.Data();
138 DescFileP
= (DescFile
*)Map
.Data();
139 PkgFileP
= (PackageFile
*)Map
.Data();
140 VerP
= (Version
*)Map
.Data();
141 DescP
= (Description
*)Map
.Data();
142 ProvideP
= (Provides
*)Map
.Data();
143 DepP
= (Dependency
*)Map
.Data();
144 StringItemP
= (StringItem
*)Map
.Data();
145 StrP
= (char *)Map
.Data();
147 if (Errorchecks
== false)
150 if (Map
.Size() == 0 || HeaderP
== 0)
151 return _error
->Error(_("Empty package cache"));
155 if (HeaderP
->Signature
!= DefHeader
.Signature
||
156 HeaderP
->Dirty
== true)
157 return _error
->Error(_("The package cache file is corrupted"));
159 if (HeaderP
->MajorVersion
!= DefHeader
.MajorVersion
||
160 HeaderP
->MinorVersion
!= DefHeader
.MinorVersion
||
161 HeaderP
->CheckSizes(DefHeader
) == false)
162 return _error
->Error(_("The package cache file is an incompatible version"));
164 if (Map
.Size() < HeaderP
->CacheFileSize
)
165 return _error
->Error(_("The package cache file is corrupted, it is too small"));
167 if (HeaderP
->VerSysName
== 0 || HeaderP
->Architecture
== 0 || HeaderP
->Architectures
== 0)
168 return _error
->Error(_("The package cache file is corrupted"));
171 if ((VS
= pkgVersioningSystem::GetVS(StrP
+ HeaderP
->VerSysName
)) == 0)
172 return _error
->Error(_("This APT does not support the versioning system '%s'"),StrP
+ HeaderP
->VerSysName
);
174 // Check the architecture
175 std::vector
<std::string
> archs
= APT::Configuration::getArchitectures();
176 std::vector
<std::string
>::const_iterator a
= archs
.begin();
177 std::string list
= *a
;
178 for (++a
; a
!= archs
.end(); ++a
)
179 list
.append(",").append(*a
);
180 if (_config
->Find("APT::Architecture") != StrP
+ HeaderP
->Architecture
||
181 list
!= StrP
+ HeaderP
->Architectures
)
182 return _error
->Error(_("The package cache was built for different architectures: %s vs %s"), StrP
+ HeaderP
->Architectures
, list
.c_str());
187 // Cache::Hash - Hash a string /*{{{*/
188 // ---------------------------------------------------------------------
189 /* This is used to generate the hash entries for the HashTable. With my
190 package list from bo this function gets 94% table usage on a 512 item
191 table (480 used items) */
192 unsigned long pkgCache::sHash(const string
&Str
) const
194 unsigned long Hash
= 0;
195 for (string::const_iterator I
= Str
.begin(); I
!= Str
.end(); ++I
)
196 Hash
= 41 * Hash
+ tolower_ascii(*I
);
197 return Hash
% _count(HeaderP
->PkgHashTable
);
200 unsigned long pkgCache::sHash(const char *Str
) const
202 unsigned long Hash
= tolower_ascii(*Str
);
203 for (const char *I
= Str
+ 1; *I
!= 0; ++I
)
204 Hash
= 41 * Hash
+ tolower_ascii(*I
);
205 return Hash
% _count(HeaderP
->PkgHashTable
);
208 // Cache::SingleArchFindPkg - Locate a package by name /*{{{*/
209 // ---------------------------------------------------------------------
210 /* Returns 0 on error, pointer to the package otherwise
211 The multiArch enabled methods will fallback to this one as it is (a bit)
212 faster for single arch environments and realworld is mostly singlearch… */
213 pkgCache::PkgIterator
pkgCache::SingleArchFindPkg(const string
&Name
)
215 // Look at the hash bucket
216 Package
*Pkg
= PkgP
+ HeaderP
->PkgHashTable
[Hash(Name
)];
217 for (; Pkg
!= PkgP
; Pkg
= PkgP
+ Pkg
->Next
)
219 if (unlikely(Pkg
->Name
== 0))
222 int const cmp
= strcasecmp(Name
.c_str(), StrP
+ Pkg
->Name
);
224 return PkgIterator(*this, Pkg
);
228 return PkgIterator(*this,0);
231 // Cache::FindPkg - Locate a package by name /*{{{*/
232 // ---------------------------------------------------------------------
233 /* Returns 0 on error, pointer to the package otherwise */
234 pkgCache::PkgIterator
pkgCache::FindPkg(const string
&Name
) {
235 size_t const found
= Name
.find(':');
236 if (found
== string::npos
)
238 if (MultiArchCache() == false)
239 return SingleArchFindPkg(Name
);
241 return FindPkg(Name
, "native");
243 string
const Arch
= Name
.substr(found
+1);
244 /* Beware: This is specialcased to handle pkg:any in dependencies as
245 these are linked to virtual pkg:any named packages with all archs.
246 If you want any arch from a given pkg, use FindPkg(pkg,arch) */
248 return FindPkg(Name
, "any");
249 return FindPkg(Name
.substr(0, found
), Arch
);
252 // Cache::FindPkg - Locate a package by name /*{{{*/
253 // ---------------------------------------------------------------------
254 /* Returns 0 on error, pointer to the package otherwise */
255 pkgCache::PkgIterator
pkgCache::FindPkg(const string
&Name
, string
const &Arch
) {
256 if (MultiArchCache() == false && Arch
!= "none") {
257 if (Arch
== "native" || Arch
== "all" || Arch
== "any" ||
258 Arch
== NativeArch())
259 return SingleArchFindPkg(Name
);
261 return PkgIterator(*this,0);
263 /* We make a detour via the GrpIterator here as
264 on a multi-arch environment a group is easier to
265 find than a package (less entries in the buckets) */
266 pkgCache::GrpIterator Grp
= FindGrp(Name
);
267 if (Grp
.end() == true)
268 return PkgIterator(*this,0);
270 return Grp
.FindPkg(Arch
);
273 // Cache::FindGrp - Locate a group by name /*{{{*/
274 // ---------------------------------------------------------------------
275 /* Returns End-Pointer on error, pointer to the group otherwise */
276 pkgCache::GrpIterator
pkgCache::FindGrp(const string
&Name
) {
277 if (unlikely(Name
.empty() == true))
278 return GrpIterator(*this,0);
280 // Look at the hash bucket for the group
281 Group
*Grp
= GrpP
+ HeaderP
->GrpHashTable
[sHash(Name
)];
282 for (; Grp
!= GrpP
; Grp
= GrpP
+ Grp
->Next
) {
283 if (unlikely(Grp
->Name
== 0))
286 int const cmp
= strcasecmp(Name
.c_str(), StrP
+ Grp
->Name
);
288 return GrpIterator(*this, Grp
);
293 return GrpIterator(*this,0);
296 // Cache::CompTypeDeb - Return a string describing the compare type /*{{{*/
297 // ---------------------------------------------------------------------
298 /* This returns a string representation of the dependency compare
299 type in the weird debian style.. */
300 const char *pkgCache::CompTypeDeb(unsigned char Comp
)
302 const char * const Ops
[] = {"","<=",">=","<<",">>","=","!="};
303 if (unlikely((unsigned)(Comp
& 0xF) >= sizeof(Ops
)/sizeof(Ops
[0])))
305 return Ops
[Comp
& 0xF];
308 // Cache::CompType - Return a string describing the compare type /*{{{*/
309 // ---------------------------------------------------------------------
310 /* This returns a string representation of the dependency compare
312 const char *pkgCache::CompType(unsigned char Comp
)
314 const char * const Ops
[] = {"","<=",">=","<",">","=","!="};
315 if (unlikely((unsigned)(Comp
& 0xF) >= sizeof(Ops
)/sizeof(Ops
[0])))
317 return Ops
[Comp
& 0xF];
320 // Cache::DepType - Return a string describing the dep type /*{{{*/
321 // ---------------------------------------------------------------------
323 const char *pkgCache::DepType(unsigned char Type
)
325 const char *Types
[] = {"",_("Depends"),_("PreDepends"),_("Suggests"),
326 _("Recommends"),_("Conflicts"),_("Replaces"),
327 _("Obsoletes"),_("Breaks"), _("Enhances")};
328 if (Type
< sizeof(Types
)/sizeof(*Types
))
333 // Cache::Priority - Convert a priority value to a string /*{{{*/
334 // ---------------------------------------------------------------------
336 const char *pkgCache::Priority(unsigned char Prio
)
338 const char *Mapping
[] = {0,_("important"),_("required"),_("standard"),
339 _("optional"),_("extra")};
340 if (Prio
< _count(Mapping
))
341 return Mapping
[Prio
];
345 // GrpIterator::FindPkg - Locate a package by arch /*{{{*/
346 // ---------------------------------------------------------------------
347 /* Returns an End-Pointer on error, pointer to the package otherwise */
348 pkgCache::PkgIterator
pkgCache::GrpIterator::FindPkg(string Arch
) const {
349 if (unlikely(IsGood() == false || S
->FirstPackage
== 0))
350 return PkgIterator(*Owner
, 0);
352 /* If we accept any package we simply return the "first"
353 package in this group (the last one added). */
355 return PkgIterator(*Owner
, Owner
->PkgP
+ S
->FirstPackage
);
357 char const* const myArch
= Owner
->NativeArch();
358 /* Most of the time the package for our native architecture is
359 the one we add at first to the cache, but this would be the
360 last one we check, so we do it now. */
361 if (Arch
== "native" || Arch
== myArch
|| Arch
== "all") {
362 pkgCache::Package
*Pkg
= Owner
->PkgP
+ S
->LastPackage
;
363 if (strcasecmp(myArch
, Owner
->StrP
+ Pkg
->Arch
) == 0)
364 return PkgIterator(*Owner
, Pkg
);
368 /* Iterate over the list to find the matching arch
369 unfortunately this list includes "package noise"
370 (= different packages with same calculated hash),
371 so we need to check the name also */
372 for (pkgCache::Package
*Pkg
= PackageList(); Pkg
!= Owner
->PkgP
;
373 Pkg
= Owner
->PkgP
+ Pkg
->Next
) {
374 if (S
->Name
== Pkg
->Name
&&
375 stringcasecmp(Arch
, Owner
->StrP
+ Pkg
->Arch
) == 0)
376 return PkgIterator(*Owner
, Pkg
);
377 if ((Owner
->PkgP
+ S
->LastPackage
) == Pkg
)
381 return PkgIterator(*Owner
, 0);
384 // GrpIterator::FindPreferredPkg - Locate the "best" package /*{{{*/
385 // ---------------------------------------------------------------------
386 /* Returns an End-Pointer on error, pointer to the package otherwise */
387 pkgCache::PkgIterator
pkgCache::GrpIterator::FindPreferredPkg(bool const &PreferNonVirtual
) const {
388 pkgCache::PkgIterator Pkg
= FindPkg("native");
389 if (Pkg
.end() == false && (PreferNonVirtual
== false || Pkg
->VersionList
!= 0))
392 std::vector
<std::string
> const archs
= APT::Configuration::getArchitectures();
393 for (std::vector
<std::string
>::const_iterator a
= archs
.begin();
394 a
!= archs
.end(); ++a
) {
396 if (Pkg
.end() == false && (PreferNonVirtual
== false || Pkg
->VersionList
!= 0))
399 // packages without an architecture
400 Pkg
= FindPkg("none");
401 if (Pkg
.end() == false && (PreferNonVirtual
== false || Pkg
->VersionList
!= 0))
404 if (PreferNonVirtual
== true)
405 return FindPreferredPkg(false);
406 return PkgIterator(*Owner
, 0);
409 // GrpIterator::NextPkg - Locate the next package in the group /*{{{*/
410 // ---------------------------------------------------------------------
411 /* Returns an End-Pointer on error, pointer to the package otherwise.
412 We can't simply ++ to the next as the next package of the last will
413 be from a different group (with the same hash value) */
414 pkgCache::PkgIterator
pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator
const &LastPkg
) const {
415 if (unlikely(IsGood() == false || S
->FirstPackage
== 0 ||
416 LastPkg
.end() == true))
417 return PkgIterator(*Owner
, 0);
419 if (S
->LastPackage
== LastPkg
.Index())
420 return PkgIterator(*Owner
, 0);
422 return PkgIterator(*Owner
, Owner
->PkgP
+ LastPkg
->Next
);
425 // GrpIterator::operator ++ - Postfix incr /*{{{*/
426 // ---------------------------------------------------------------------
427 /* This will advance to the next logical group in the hash table. */
428 void pkgCache::GrpIterator::operator ++(int)
430 // Follow the current links
431 if (S
!= Owner
->GrpP
)
432 S
= Owner
->GrpP
+ S
->Next
;
434 // Follow the hash table
435 while (S
== Owner
->GrpP
&& (HashIndex
+1) < (signed)_count(Owner
->HeaderP
->GrpHashTable
))
438 S
= Owner
->GrpP
+ Owner
->HeaderP
->GrpHashTable
[HashIndex
];
442 // PkgIterator::operator ++ - Postfix incr /*{{{*/
443 // ---------------------------------------------------------------------
444 /* This will advance to the next logical package in the hash table. */
445 void pkgCache::PkgIterator::operator ++(int)
447 // Follow the current links
448 if (S
!= Owner
->PkgP
)
449 S
= Owner
->PkgP
+ S
->Next
;
451 // Follow the hash table
452 while (S
== Owner
->PkgP
&& (HashIndex
+1) < (signed)_count(Owner
->HeaderP
->PkgHashTable
))
455 S
= Owner
->PkgP
+ Owner
->HeaderP
->PkgHashTable
[HashIndex
];
459 // PkgIterator::State - Check the State of the package /*{{{*/
460 // ---------------------------------------------------------------------
461 /* By this we mean if it is either cleanly installed or cleanly removed. */
462 pkgCache::PkgIterator::OkState
pkgCache::PkgIterator::State() const
464 if (S
->InstState
== pkgCache::State::ReInstReq
||
465 S
->InstState
== pkgCache::State::HoldReInstReq
)
468 if (S
->CurrentState
== pkgCache::State::UnPacked
||
469 S
->CurrentState
== pkgCache::State::HalfConfigured
)
470 // we leave triggers alone complettely. dpkg deals with
471 // them in a hard-to-predict manner and if they get
472 // resolved by dpkg before apt run dpkg --configure on
473 // the TriggersPending package dpkg returns a error
474 //Pkg->CurrentState == pkgCache::State::TriggersAwaited
475 //Pkg->CurrentState == pkgCache::State::TriggersPending)
476 return NeedsConfigure
;
478 if (S
->CurrentState
== pkgCache::State::HalfInstalled
||
479 S
->InstState
!= pkgCache::State::Ok
)
485 // PkgIterator::CandVersion - Returns the candidate version string /*{{{*/
486 // ---------------------------------------------------------------------
487 /* Return string representing of the candidate version. */
489 pkgCache::PkgIterator::CandVersion() const
491 //TargetVer is empty, so don't use it.
492 VerIterator version
= pkgPolicy(Owner
).GetCandidateVer(*this);
493 if (version
.IsGood())
494 return version
.VerStr();
498 // PkgIterator::CurVersion - Returns the current version string /*{{{*/
499 // ---------------------------------------------------------------------
500 /* Return string representing of the current version. */
502 pkgCache::PkgIterator::CurVersion() const
504 VerIterator version
= CurrentVer();
505 if (version
.IsGood())
506 return CurrentVer().VerStr();
510 // ostream operator to handle string representation of a package /*{{{*/
511 // ---------------------------------------------------------------------
512 /* Output name < cur.rent.version -> candid.ate.version | new.est.version > (section)
513 Note that the characters <|>() are all literal above. Versions will be omitted
514 if they provide no new information (e.g. there is no newer version than candidate)
515 If no version and/or section can be found "none" is used. */
517 operator<<(std::ostream
& out
, pkgCache::PkgIterator Pkg
)
519 if (Pkg
.end() == true)
520 return out
<< "invalid package";
522 string current
= string(Pkg
.CurVersion() == 0 ? "none" : Pkg
.CurVersion());
523 string candidate
= string(Pkg
.CandVersion() == 0 ? "none" : Pkg
.CandVersion());
524 string newest
= string(Pkg
.VersionList().end() ? "none" : Pkg
.VersionList().VerStr());
526 out
<< Pkg
.Name() << " [ " << Pkg
.Arch() << " ] < " << current
;
527 if (current
!= candidate
)
528 out
<< " -> " << candidate
;
529 if ( newest
!= "none" && candidate
!= newest
)
530 out
<< " | " << newest
;
531 out
<< " > ( " << string(Pkg
.Section()==0?"none":Pkg
.Section()) << " )";
535 // PkgIterator::FullName - Returns Name and (maybe) Architecture /*{{{*/
536 // ---------------------------------------------------------------------
537 /* Returns a name:arch string */
538 std::string
pkgCache::PkgIterator::FullName(bool const &Pretty
) const
540 string fullname
= Name();
541 if (Pretty
== false ||
542 (strcmp(Arch(), "all") != 0 &&
543 strcmp(Owner
->NativeArch(), Arch()) != 0))
544 return fullname
.append(":").append(Arch());
548 // DepIterator::IsCritical - Returns true if the dep is important /*{{{*/
549 // ---------------------------------------------------------------------
550 /* Currently critical deps are defined as depends, predepends and
551 conflicts (including dpkg's Breaks fields). */
552 bool pkgCache::DepIterator::IsCritical() const
554 if (IsNegative() == true ||
555 S
->Type
== pkgCache::Dep::Depends
||
556 S
->Type
== pkgCache::Dep::PreDepends
)
561 // DepIterator::IsNegative - Returns true if the dep is a negative one /*{{{*/
562 // ---------------------------------------------------------------------
563 /* Some dependencies are positive like Depends and Recommends, others
564 are negative like Conflicts which can and should be handled differently */
565 bool pkgCache::DepIterator::IsNegative() const
567 return S
->Type
== Dep::DpkgBreaks
||
568 S
->Type
== Dep::Conflicts
||
569 S
->Type
== Dep::Obsoletes
;
572 // DepIterator::SmartTargetPkg - Resolve dep target pointers w/provides /*{{{*/
573 // ---------------------------------------------------------------------
574 /* This intellegently looks at dep target packages and tries to figure
575 out which package should be used. This is needed to nicely handle
576 provide mapping. If the target package has no other providing packages
577 then it returned. Otherwise the providing list is looked at to
578 see if there is one one unique providing package if so it is returned.
579 Otherwise true is returned and the target package is set. The return
580 result indicates whether the node should be expandable
582 In Conjunction with the DepCache the value of Result may not be
583 super-good since the policy may have made it uninstallable. Using
584 AllTargets is better in this case. */
585 bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator
&Result
) const
587 Result
= TargetPkg();
589 // No provides at all
590 if (Result
->ProvidesList
== 0)
593 // There is the Base package and the providing ones which is at least 2
594 if (Result
->VersionList
!= 0)
597 /* We have to skip over indirect provisions of the package that
598 owns the dependency. For instance, if libc5-dev depends on the
599 virtual package libc-dev which is provided by libc5-dev and libc6-dev
600 we must ignore libc5-dev when considering the provides list. */
601 PrvIterator PStart
= Result
.ProvidesList();
602 for (; PStart
.end() != true && PStart
.OwnerPkg() == ParentPkg(); ++PStart
);
604 // Nothing but indirect self provides
605 if (PStart
.end() == true)
608 // Check for single packages in the provides list
609 PrvIterator P
= PStart
;
610 for (; P
.end() != true; ++P
)
612 // Skip over self provides
613 if (P
.OwnerPkg() == ParentPkg())
615 if (PStart
.OwnerPkg() != P
.OwnerPkg())
619 Result
= PStart
.OwnerPkg();
621 // Check for non dups
628 // DepIterator::AllTargets - Returns the set of all possible targets /*{{{*/
629 // ---------------------------------------------------------------------
630 /* This is a more useful version of TargetPkg() that follows versioned
631 provides. It includes every possible package-version that could satisfy
632 the dependency. The last item in the list has a 0. The resulting pointer
633 must be delete [] 'd */
634 pkgCache::Version
**pkgCache::DepIterator::AllTargets() const
637 unsigned long Size
=0;
641 PkgIterator DPkg
= TargetPkg();
643 // Walk along the actual package providing versions
644 for (VerIterator I
= DPkg
.VersionList(); I
.end() == false; ++I
)
646 if (IsIgnorable(I
.ParentPkg()) == true)
648 if (IsSatisfied(I
) == false)
656 // Follow all provides
657 for (PrvIterator I
= DPkg
.ProvidesList(); I
.end() == false; ++I
)
659 if (IsIgnorable(I
) == true)
661 if (IsSatisfied(I
) == false)
666 *End
++ = I
.OwnerVer();
669 // Do it again and write it into the array
672 Res
= new Version
*[Size
+1];
685 // DepIterator::GlobOr - Compute an OR group /*{{{*/
686 // ---------------------------------------------------------------------
687 /* This Takes an iterator, iterates past the current dependency grouping
688 and returns Start and End so that so End is the final element
689 in the group, if End == Start then D is End++ and End is the
690 dependency D was pointing to. Use in loops to iterate sensibly. */
691 void pkgCache::DepIterator::GlobOr(DepIterator
&Start
,DepIterator
&End
)
693 // Compute a single dependency element (glob or)
696 for (bool LastOR
= true; end() == false && LastOR
== true;)
698 LastOR
= (S
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
705 // DepIterator::IsIgnorable - should this packag/providr be ignored? /*{{{*/
706 // ---------------------------------------------------------------------
707 /* Deps like self-conflicts should be ignored as well as implicit conflicts
708 on virtual packages. */
709 bool pkgCache::DepIterator::IsIgnorable(PkgIterator
const &/*Pkg*/) const
711 if (IsNegative() == false)
714 pkgCache::PkgIterator PP
= ParentPkg();
715 pkgCache::PkgIterator PT
= TargetPkg();
716 if (PP
->Group
!= PT
->Group
)
721 pkgCache::VerIterator PV
= ParentVer();
722 // ignore group-conflict on a M-A:same package - but not our implicit dependencies
723 // so that we can have M-A:same packages conflicting with their own real name
724 if ((PV
->MultiArch
& pkgCache::Version::Same
) == pkgCache::Version::Same
)
726 // Replaces: ${self}:other ( << ${binary:Version})
727 if (S
->Type
== pkgCache::Dep::Replaces
&& S
->CompareOp
== pkgCache::Dep::Less
&& strcmp(PV
.VerStr(), TargetVer()) == 0)
729 // Breaks: ${self}:other (!= ${binary:Version})
730 if (S
->Type
== pkgCache::Dep::DpkgBreaks
&& S
->CompareOp
== pkgCache::Dep::NotEquals
&& strcmp(PV
.VerStr(), TargetVer()) == 0)
737 bool pkgCache::DepIterator::IsIgnorable(PrvIterator
const &Prv
) const
739 if (IsNegative() == false)
742 PkgIterator
const Pkg
= ParentPkg();
743 /* Provides may never be applied against the same package (or group)
744 if it is a conflicts. See the comment above. */
745 if (Prv
.OwnerPkg()->Group
== Pkg
->Group
)
747 // Implicit group-conflicts should not be applied on providers of other groups
748 if (Pkg
->Group
== TargetPkg()->Group
&& Prv
.OwnerPkg()->Group
!= Pkg
->Group
)
754 // DepIterator::IsMultiArchImplicit - added by the cache generation /*{{{*/
755 // ---------------------------------------------------------------------
756 /* MultiArch can be translated to SingleArch for an resolver and we did so,
757 by adding dependencies to help the resolver understand the problem, but
758 sometimes it is needed to identify these to ignore them… */
759 bool pkgCache::DepIterator::IsMultiArchImplicit() const
761 if (ParentPkg()->Arch
!= TargetPkg()->Arch
&&
762 (S
->Type
== pkgCache::Dep::Replaces
||
763 S
->Type
== pkgCache::Dep::DpkgBreaks
||
764 S
->Type
== pkgCache::Dep::Conflicts
))
769 // DepIterator::IsSatisfied - check if a version satisfied the dependency /*{{{*/
770 bool pkgCache::DepIterator::IsSatisfied(VerIterator
const &Ver
) const
772 return Owner
->VS
->CheckDep(Ver
.VerStr(),S
->CompareOp
,TargetVer());
774 bool pkgCache::DepIterator::IsSatisfied(PrvIterator
const &Prv
) const
776 return Owner
->VS
->CheckDep(Prv
.ProvideVersion(),S
->CompareOp
,TargetVer());
779 // ostream operator to handle string representation of a dependecy /*{{{*/
780 // ---------------------------------------------------------------------
782 std::ostream
& operator<<(std::ostream
& out
, pkgCache::DepIterator D
)
785 return out
<< "invalid dependency";
787 pkgCache::PkgIterator P
= D
.ParentPkg();
788 pkgCache::PkgIterator T
= D
.TargetPkg();
790 out
<< (P
.end() ? "invalid pkg" : P
.FullName(false)) << " " << D
.DepType()
793 out
<< "invalid pkg";
798 out
<< " (" << D
.CompType() << " " << D
.TargetVer() << ")";
803 // VerIterator::CompareVer - Fast version compare for same pkgs /*{{{*/
804 // ---------------------------------------------------------------------
805 /* This just looks over the version list to see if B is listed before A. In
806 most cases this will return in under 4 checks, ver lists are short. */
807 int pkgCache::VerIterator::CompareVer(const VerIterator
&B
) const
809 // Check if they are equal
817 /* Start at A and look for B. If B is found then A > B otherwise
818 B was before A so A < B */
819 VerIterator I
= *this;
820 for (;I
.end() == false; ++I
)
826 // VerIterator::Downloadable - Checks if the version is downloadable /*{{{*/
827 // ---------------------------------------------------------------------
829 APT_PURE
bool pkgCache::VerIterator::Downloadable() const
831 VerFileIterator Files
= FileList();
832 for (; Files
.end() == false; ++Files
)
833 if ((Files
.File()->Flags
& pkgCache::Flag::NotSource
) != pkgCache::Flag::NotSource
)
838 // VerIterator::Automatic - Check if this version is 'automatic' /*{{{*/
839 // ---------------------------------------------------------------------
840 /* This checks to see if any of the versions files are not NotAutomatic.
841 True if this version is selectable for automatic installation. */
842 APT_PURE
bool pkgCache::VerIterator::Automatic() const
844 VerFileIterator Files
= FileList();
845 for (; Files
.end() == false; ++Files
)
846 // Do not check ButAutomaticUpgrades here as it is kind of automatic…
847 if ((Files
.File()->Flags
& pkgCache::Flag::NotAutomatic
) != pkgCache::Flag::NotAutomatic
)
852 // VerIterator::NewestFile - Return the newest file version relation /*{{{*/
853 // ---------------------------------------------------------------------
854 /* This looks at the version numbers associated with all of the sources
855 this version is in and returns the highest.*/
856 pkgCache::VerFileIterator
pkgCache::VerIterator::NewestFile() const
858 VerFileIterator Files
= FileList();
859 VerFileIterator Highest
= Files
;
860 for (; Files
.end() == false; ++Files
)
862 if (Owner
->VS
->CmpReleaseVer(Files
.File().Version(),Highest
.File().Version()) > 0)
869 // VerIterator::RelStr - Release description string /*{{{*/
870 // ---------------------------------------------------------------------
871 /* This describes the version from a release-centric manner. The output is a
872 list of Label:Version/Archive */
873 string
pkgCache::VerIterator::RelStr() const
877 for (pkgCache::VerFileIterator I
= this->FileList(); I
.end() == false; ++I
)
879 // Do not print 'not source' entries'
880 pkgCache::PkgFileIterator File
= I
.File();
881 if ((File
->Flags
& pkgCache::Flag::NotSource
) == pkgCache::Flag::NotSource
)
884 // See if we have already printed this out..
886 for (pkgCache::VerFileIterator J
= this->FileList(); I
!= J
; ++J
)
888 pkgCache::PkgFileIterator File2
= J
.File();
889 if (File2
->Label
== 0 || File
->Label
== 0)
892 if (strcmp(File
.Label(),File2
.Label()) != 0)
895 if (File2
->Version
== File
->Version
)
900 if (File2
->Version
== 0 || File
->Version
== 0)
902 if (strcmp(File
.Version(),File2
.Version()) == 0)
914 if (File
->Label
!= 0)
915 Res
= Res
+ File
.Label() + ':';
917 if (File
->Archive
!= 0)
919 if (File
->Version
== 0)
920 Res
+= File
.Archive();
922 Res
= Res
+ File
.Version() + '/' + File
.Archive();
926 // No release file, print the host name that this came from
927 if (File
->Site
== 0 || File
.Site()[0] == 0)
933 if (S
->ParentPkg
!= 0)
934 Res
.append(" [").append(Arch()).append("]");
938 // VerIterator::MultiArchType - string representing MultiArch flag /*{{{*/
939 const char * pkgCache::VerIterator::MultiArchType() const
941 if ((S
->MultiArch
& pkgCache::Version::Same
) == pkgCache::Version::Same
)
943 else if ((S
->MultiArch
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
)
945 else if ((S
->MultiArch
& pkgCache::Version::Allowed
) == pkgCache::Version::Allowed
)
950 // PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/
951 // ---------------------------------------------------------------------
952 /* This stats the file and compares its stats with the ones that were
953 stored during generation. Date checks should probably also be
955 bool pkgCache::PkgFileIterator::IsOk()
958 if (stat(FileName(),&Buf
) != 0)
961 if (Buf
.st_size
!= (signed)S
->Size
|| Buf
.st_mtime
!= S
->mtime
)
967 // PkgFileIterator::RelStr - Return the release string /*{{{*/
968 // ---------------------------------------------------------------------
970 string
pkgCache::PkgFileIterator::RelStr()
974 Res
= Res
+ (Res
.empty() == true?"v=":",v=") + Version();
976 Res
= Res
+ (Res
.empty() == true?"o=":",o=") + Origin();
978 Res
= Res
+ (Res
.empty() == true?"a=":",a=") + Archive();
980 Res
= Res
+ (Res
.empty() == true?"n=":",n=") + Codename();
982 Res
= Res
+ (Res
.empty() == true?"l=":",l=") + Label();
983 if (Component() != 0)
984 Res
= Res
+ (Res
.empty() == true?"c=":",c=") + Component();
985 if (Architecture() != 0)
986 Res
= Res
+ (Res
.empty() == true?"b=":",b=") + Architecture();
990 // VerIterator::TranslatedDescription - Return the a DescIter for locale/*{{{*/
991 // ---------------------------------------------------------------------
992 /* return a DescIter for the current locale or the default if none is
995 pkgCache::DescIterator
pkgCache::VerIterator::TranslatedDescription() const
997 std::vector
<string
> const lang
= APT::Configuration::getLanguages();
998 for (std::vector
<string
>::const_iterator l
= lang
.begin();
999 l
!= lang
.end(); ++l
)
1001 pkgCache::DescIterator Desc
= DescriptionList();
1002 for (; Desc
.end() == false; ++Desc
)
1003 if (*l
== Desc
.LanguageCode())
1005 if (Desc
.end() == true)
1009 Desc
= DescriptionList();
1010 for (; Desc
.end() == false; ++Desc
)
1011 if (strcmp(Desc
.LanguageCode(), "") == 0)
1013 if (Desc
.end() == true)
1021 for (pkgCache::DescIterator Desc
= DescriptionList();
1022 Desc
.end() == false; ++Desc
)
1023 if (strcmp(Desc
.LanguageCode(), "") == 0)
1025 return DescriptionList();
1029 // PrvIterator::IsMultiArchImplicit - added by the cache generation /*{{{*/
1030 // ---------------------------------------------------------------------
1031 /* MultiArch can be translated to SingleArch for an resolver and we did so,
1032 by adding provides to help the resolver understand the problem, but
1033 sometimes it is needed to identify these to ignore them… */
1034 bool pkgCache::PrvIterator::IsMultiArchImplicit() const
1036 pkgCache::PkgIterator
const Owner
= OwnerPkg();
1037 pkgCache::PkgIterator
const Parent
= ParentPkg();
1038 if (strcmp(Owner
.Arch(), Parent
.Arch()) != 0 || Owner
->Name
== Parent
->Name
)