]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/depcache.cc
fix the gcc warning about the initialisation order of variables caused
[apt.git] / apt-pkg / depcache.cc
index 786b20ec0fb8e36796285bdbfc572296c7814f49..d082b8404075f98eb4b36e8a1ee825289db62c39 100644 (file)
@@ -165,7 +165,7 @@ bool pkgDepCache::Init(OpProgress *Prog)
 bool pkgDepCache::readStateFile(OpProgress *Prog)                      /*{{{*/
 {
    FileFd state_file;
-   string const state = _config->FindDir("Dir::State") + "extended_states";
+   string const state = _config->FindFile("Dir::State::extended_states");
    if(FileExists(state)) {
       state_file.Open(state, FileFd::ReadOnly);
       int const file_size = state_file.Size();
@@ -222,7 +222,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)      /*{{{*/
       std::clog << "pkgDepCache::writeStateFile()" << std::endl;
 
    FileFd StateFile;
-   string const state = _config->FindDir("Dir::State") + "extended_states";
+   string const state = _config->FindFile("Dir::State::extended_states");
 
    // if it does not exist, create a empty one
    if(!FileExists(state)) 
@@ -875,7 +875,7 @@ void pkgDepCache::Update(OpProgress *Prog)
                a bit we increase with a kill, but we should do something more clever… */
       while(recheck.empty() == false)
         for (std::set<unsigned long>::const_iterator p = recheck.begin();
-            p != recheck.end(); ++p) {
+            p != recheck.end();) {
            if (Prog != 0 && Done%20 == 0)
               Prog->Progress(Done);
            PkgIterator P = PkgIterator(*Cache, Cache->PkgP + *p);
@@ -883,7 +883,7 @@ void pkgDepCache::Update(OpProgress *Prog)
               ++killed;
               ++Done;
            }
-           recheck.erase(p);
+           recheck.erase(p++);
         }
 
       /* Okay, we have killed a great amount of pseudopackages -
@@ -918,7 +918,7 @@ void pkgDepCache::Update(OpProgress *Prog)
         unsigned long const G = *g;
         recheck.erase(g);
         if (unlikely(ReInstallPseudoForGroup(G, recheck) == false))
-           _error->Warning(_("Internal error, group '%s' has no installable pseudo package"), GrpIterator(*Cache, Cache->GrpP + *g).Name());
+           _error->Warning(_("Internal error, group '%s' has no installable pseudo package"), GrpIterator(*Cache, Cache->GrpP + G).Name());
       }
    }
 
@@ -1453,6 +1453,9 @@ bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst,
 /* */
 void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
 {
+   if (unlikely(Pkg.end() == true))
+      return;
+
    ActionGroup group(*this);
 
    RemoveSizes(Pkg);
@@ -1466,12 +1469,17 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
    
    AddStates(Pkg);
    AddSizes(Pkg);
+
+   if (unlikely(Pkg.CurrentVer().end() == true) || Pkg.CurrentVer().Pseudo() == false)
+      return;
+
+   SetReInstall(Pkg.Group().FindPkg("all"), To);
 }
                                                                        /*}}}*/
 // DepCache::SetCandidateVersion - Change the candidate version                /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgDepCache::SetCandidateVersion(VerIterator TargetVer)
+void pkgDepCache::SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo)
 {
    ActionGroup group(*this);
 
@@ -1489,6 +1497,28 @@ void pkgDepCache::SetCandidateVersion(VerIterator TargetVer)
    AddStates(Pkg);
    Update(Pkg);
    AddSizes(Pkg);
+
+   if (TargetVer.Pseudo() == false || Pseudo == false)
+      return;
+
+   // the version was pseudo: set all other pseudos also
+   pkgCache::GrpIterator Grp = Pkg.Group();
+   for (Pkg = Grp.FindPkg("any"); Pkg.end() == false; ++Pkg)
+   {
+      StateCache &P = PkgState[Pkg->ID];
+      if (TargetVer.SimilarVer(P.CandidateVerIter(*this)) == true ||
+         (P.CandidateVerIter(*this).Pseudo() == false &&
+          strcmp(Pkg.Arch(), "all") != 0))
+        continue;
+
+      for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
+      {
+        if (TargetVer.SimilarVer(Ver) == false)
+           continue;
+        SetCandidateVersion(Ver, false);
+        break;
+      }
+   }
 }
 
 void pkgDepCache::MarkAuto(const PkgIterator &Pkg, bool Auto)
@@ -1707,8 +1737,11 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
    {
       if(!(PkgState[p->ID].Flags & Flag::Auto) ||
          (p->Flags & Flag::Essential) ||
-         userFunc.InRootSet(p))
-          
+         userFunc.InRootSet(p) ||
+         // be nice even then a required package violates the policy (#583517)
+         // and do the full mark process also for required packages
+         (p.CurrentVer().end() != true &&
+          p.CurrentVer()->Priority == pkgCache::State::Required))
       {
         // the package is installed (and set to keep)
         if(PkgState[p->ID].Keep() && !p.CurrentVer().end())
@@ -1785,10 +1818,6 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
 
    // If the version belongs to a Multi-Arch all package
    // we will mark all others in this Group with this version also
-   // Beware: We compare versions here the lazy way: string comparision
-   // this is bad if multiple repositories provide different versions
-   // of the package with an identical version number - but even in this
-   // case the dependencies are likely the same.
    if (ver->MultiArch == pkgCache::Version::All &&
        strcmp(ver.Arch(true), "all") == 0)
    {
@@ -1800,7 +1829,8 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
         for (VerIterator V = P.VersionList();
              V.end() != true; ++V)
         {
-           if (strcmp(VerStr, V.VerStr()) != 0)
+           if (ver->Hash != V->Hash ||
+               strcmp(VerStr, V.VerStr()) != 0)
               continue;
            MarkPackage(P, V, follow_recommends, follow_suggests);
            break;