]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/pkgcachegen.cc
always create pkg at the time pkg:arch is created
[apt.git] / apt-pkg / pkgcachegen.cc
index 79d633cb72d7eb4ec77a1379142c068b7e09eb3b..6e307fba9b32df572709ea1a324815bb7aeeb3d5 100644 (file)
@@ -141,7 +141,7 @@ pkgCacheGenerator::~pkgCacheGenerator()
    Map.Sync(0,sizeof(pkgCache::Header));
 }
                                                                        /*}}}*/
-void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newMap) {/*{{{*/
+void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newMap, size_t oldSize) {/*{{{*/
    if (oldMap == newMap)
       return;
 
@@ -177,31 +177,42 @@ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newM
    for (std::vector<pkgCache::RlsFileIterator*>::const_iterator i = Dynamic<pkgCache::RlsFileIterator>::toReMap.begin();
        i != Dynamic<pkgCache::RlsFileIterator>::toReMap.end(); ++i)
       (*i)->ReMap(oldMap, newMap);
+   for (APT::StringView* ViewP : Dynamic<APT::StringView>::toReMap) {
+      // Ignore views outside of the cache.
+      if (ViewP->data() < static_cast<const char*>(oldMap)
+        || ViewP->data() > static_cast<const char*>(oldMap) + oldSize)
+        continue;
+      const char *data = ViewP->data() + (static_cast<const char*>(newMap) - static_cast<const char*>(oldMap));
+      *ViewP = StringView(data , ViewP->size());
+   }
 }                                                                      /*}}}*/
 // CacheGenerator::WriteStringInMap                                    /*{{{*/
 map_stringitem_t pkgCacheGenerator::WriteStringInMap(const char *String,
                                        const unsigned long &Len) {
+   size_t oldSize = Map.Size();
    void const * const oldMap = Map.Data();
    map_stringitem_t const index = Map.WriteString(String, Len);
    if (index != 0)
-      ReMap(oldMap, Map.Data());
+      ReMap(oldMap, Map.Data(), oldSize);
    return index;
 }
                                                                        /*}}}*/
 // CacheGenerator::WriteStringInMap                                    /*{{{*/
 map_stringitem_t pkgCacheGenerator::WriteStringInMap(const char *String) {
+   size_t oldSize = Map.Size();
    void const * const oldMap = Map.Data();
    map_stringitem_t const index = Map.WriteString(String);
    if (index != 0)
-      ReMap(oldMap, Map.Data());
+      ReMap(oldMap, Map.Data(), oldSize);
    return index;
 }
                                                                        /*}}}*/
 map_pointer_t pkgCacheGenerator::AllocateInMap(const unsigned long &size) {/*{{{*/
+   size_t oldSize = Map.Size();
    void const * const oldMap = Map.Data();
    map_pointer_t const index = Map.Allocate(size);
    if (index != 0)
-      ReMap(oldMap, Map.Data());
+      ReMap(oldMap, Map.Data(), oldSize);
    return index;
 }
                                                                        /*}}}*/
@@ -308,8 +319,6 @@ bool pkgCacheGenerator::MergeListPackage(ListParser &List, pkgCache::PkgIterator
 
    // Find the right version to write the description
    MD5SumValue CurMd5 = List.Description_md5();
-   if (CurMd5.Value().empty() == true && List.Description("").empty() == true)
-      return true;
    std::vector<std::string> availDesc = List.AvailableDescriptionLanguages();
    for (Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
    {
@@ -444,8 +453,6 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator
 
    /* Record the Description(s) based on their master md5sum */
    MD5SumValue CurMd5 = List.Description_md5();
-   if (CurMd5.Value().empty() == true && List.Description("").empty() == true)
-      return true;
 
    /* Before we add a new description we first search in the group for
       a version with a description of the same MD5 - if so we reuse this
@@ -504,6 +511,7 @@ bool pkgCacheGenerator::AddNewDescription(ListParser &List, pkgCache::VerIterato
 /* This creates a new group structure and adds it to the hash table */
 bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, StringView Name)
 {
+   Dynamic<StringView> DName(Name);
    Grp = Cache.FindGrp(Name);
    if (Grp.end() == false)
       return true;
@@ -522,7 +530,8 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, StringView Name)
    // Insert it into the hash table
    unsigned long const Hash = Cache.Hash(Name);
    map_pointer_t *insertAt = &Cache.HeaderP->GrpHashTableP()[Hash];
-   while (*insertAt != 0 && Name.compare(Cache.StrP + (Cache.GrpP + *insertAt)->Name) > 0)
+
+   while (*insertAt != 0 && Name.compare(Cache.ViewString((Cache.GrpP + *insertAt)->Name)) > 0)
       insertAt = &(Cache.GrpP + *insertAt)->Next;
    Grp->Next = *insertAt;
    *insertAt = Group;
@@ -537,6 +546,8 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, StringView Name)
 bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg, StringView Name,
                                        StringView Arch) {
    pkgCache::GrpIterator Grp;
+   Dynamic<StringView> DName(Name);
+   Dynamic<StringView> DArch(Arch);
    Dynamic<pkgCache::GrpIterator> DynGrp(Grp);
    if (unlikely(NewGroup(Grp, Name) == false))
       return false;
@@ -575,8 +586,7 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg, StringView Name,
    }
    else // Group the Packages together
    {
-      // but first get implicit provides done
-      if (APT::Configuration::checkArchitecture(Pkg.Arch()) == true)
+      // if sibling is provided by another package, this one is too
       {
         pkgCache::PkgIterator const M = Grp.FindPreferredPkg(false); // native or any foreign pkg will do
         if (M.end() == false) {
@@ -591,22 +601,31 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg, StringView Name,
               if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed ||
                   ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign &&
                        (Prv->Flags & pkgCache::Flag::MultiArchImplicit) == 0))
+              {
+                 if (APT::Configuration::checkArchitecture(Ver.ParentPkg().Arch()) == false)
+                    continue;
                  if (NewProvides(Ver, Pkg, Prv->ProvideVersion, Prv->Flags) == false)
                     return false;
+              }
            }
         }
-
-
+      }
+      // let M-A:foreign package siblings provide this package
+      {
         pkgCache::PkgIterator P;
         pkgCache::VerIterator Ver;
         Dynamic<pkgCache::PkgIterator> DynP(P);
         Dynamic<pkgCache::VerIterator> DynVer(Ver);
 
         for (P = Grp.PackageList(); P.end() == false;  P = Grp.NextPkg(P))
+        {
+           if (APT::Configuration::checkArchitecture(P.Arch()) == false)
+              continue;
            for (Ver = P.VersionList(); Ver.end() == false; ++Ver)
               if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
                  if (NewProvides(Ver, Pkg, Ver->VerStr, pkgCache::Flag::MultiArchImplicit) == false)
                     return false;
+        }
       }
       // and negative dependencies, don't forget negative dependencies
       {
@@ -641,29 +660,44 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg, StringView Name,
    if (Arch == "any")
    {
       size_t const found = Name.find(':');
-      StringView const NameA = Name.substr(0, found);
-      StringView const ArchA = Name.substr(found + 1);
-      pkgCache::PkgIterator PkgA = Cache.FindPkg(NameA, ArchA);
-      if (PkgA.end() == false)
+      StringView ArchA = Name.substr(found + 1);
+      if (ArchA != "any")
       {
+        // ArchA is used inside the loop which might remap (NameA is not used)
+        Dynamic<StringView> DynArchA(ArchA);
+        StringView NameA = Name.substr(0, found);
+        pkgCache::PkgIterator PkgA = Cache.FindPkg(NameA, ArchA);
         Dynamic<pkgCache::PkgIterator> DynPkgA(PkgA);
-        pkgCache::PrvIterator Prv = PkgA.ProvidesList();
-        for (; Prv.end() == false; ++Prv)
+        if (PkgA.end())
         {
-           if (Prv.IsMultiArchImplicit())
-              continue;
-           pkgCache::VerIterator V = Prv.OwnerVer();
-           if (ArchA != V.ParentPkg().Arch())
-              continue;
-           if (NewProvides(V, Pkg, V->VerStr, pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific) == false)
+           Dynamic<StringView> DynNameA(NameA);
+           if (NewPackage(PkgA, NameA, ArchA) == false)
               return false;
         }
-        pkgCache::VerIterator V = PkgA.VersionList();
-        Dynamic<pkgCache::VerIterator> DynV(V);
-        for (; V.end() == false; ++V)
+        if (unlikely(PkgA.end()))
+           return _error->Fatal("NewPackage was successful for %s:%s,"
+                 "but the package doesn't exist anyhow!",
+                 NameA.to_string().c_str(), ArchA.to_string().c_str());
+        else
         {
-           if (NewProvides(V, Pkg, V->VerStr, pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific) == false)
-              return false;
+           pkgCache::PrvIterator Prv = PkgA.ProvidesList();
+           for (; Prv.end() == false; ++Prv)
+           {
+              if (Prv.IsMultiArchImplicit())
+                 continue;
+              pkgCache::VerIterator V = Prv.OwnerVer();
+              if (ArchA != V.ParentPkg().Arch())
+                 continue;
+              if (NewProvides(V, Pkg, V->VerStr, pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific) == false)
+                 return false;
+           }
+           pkgCache::VerIterator V = PkgA.VersionList();
+           Dynamic<pkgCache::VerIterator> DynV(V);
+           for (; V.end() == false; ++V)
+           {
+              if (NewProvides(V, Pkg, V->VerStr, pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific) == false)
+                 return false;
+           }
         }
       }
    }
@@ -1006,6 +1040,9 @@ bool pkgCacheListParser::NewDepends(pkgCache::VerIterator &Ver,
 {
    pkgCache::GrpIterator Grp;
    Dynamic<pkgCache::GrpIterator> DynGrp(Grp);
+   Dynamic<StringView> DynPackageName(PackageName);
+   Dynamic<StringView> DynArch(Arch);
+   Dynamic<StringView> DynVersion(Version);
    if (unlikely(Owner->NewGroup(Grp, PackageName) == false))
       return false;
 
@@ -1073,6 +1110,9 @@ bool pkgCacheListParser::NewProvides(pkgCache::VerIterator &Ver,
                                                uint8_t const Flags)
 {
    pkgCache const &Cache = Owner->Cache;
+   Dynamic<StringView> DynPkgName(PkgName);
+   Dynamic<StringView> DynArch(PkgArch);
+   Dynamic<StringView> DynVersion(Version);
 
    // We do not add self referencing provides
    if (Ver.ParentPkg().Name() == PkgName && (PkgArch == Ver.ParentPkg().Arch() ||
@@ -1126,6 +1166,8 @@ bool pkgCacheListParser::NewProvidesAllArch(pkgCache::VerIterator &Ver, StringVi
    pkgCache &Cache = Owner->Cache;
    pkgCache::GrpIterator Grp = Cache.FindGrp(Package);
    Dynamic<pkgCache::GrpIterator> DynGrp(Grp);
+   Dynamic<StringView> DynPackage(Package);
+   Dynamic<StringView> DynVersion(Version);
 
    if (Grp.end() == true)
       return NewProvides(Ver, Package, Cache.NativeArch(), Version, Flags);