]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/algorithms.cc
Bug fixes
[apt.git] / apt-pkg / algorithms.cc
index 21db989419d4b91a72dbeec97f7e7649494ab3d7..dd0928562ffcbb5b98f86e6d6b71a934b94318ec 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: algorithms.cc,v 1.20 1999/07/03 03:10:35 jgg Exp $
+// $Id: algorithms.cc,v 1.24 1999/09/30 06:30:34 jgg Exp $
 /* ######################################################################
 
    Algorithms - A set of misc algorithms
@@ -36,7 +36,7 @@ pkgSimulate::pkgSimulate(pkgDepCache &Cache) : pkgPackageManager(Cache),
 
    // Fake a filename so as not to activate the media swapping
    string Jnk = "SIMULATE";
-   for (int I = 0; I != Cache.Head().PackageCount; I++)
+   for (unsigned int I = 0; I != Cache.Head().PackageCount; I++)
       FileNames[I] = Jnk;
 }
                                                                        /*}}}*/
@@ -125,14 +125,17 @@ bool pkgSimulate::Configure(PkgIterator iPkg)
 // Simulate::Remove - Simulate the removal of a package                        /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-bool pkgSimulate::Remove(PkgIterator iPkg)
+bool pkgSimulate::Remove(PkgIterator iPkg,bool Purge)
 {
    // Adapt the iterator
    PkgIterator Pkg = Sim.FindPkg(iPkg.Name());
 
    Flags[Pkg->ID] = 3;
    Sim.MarkDelete(Pkg);
-   cout << "Remv " << Pkg.Name();
+   if (Purge == true)
+      cout << "Purg " << Pkg.Name();
+   else
+      cout << "Remv " << Pkg.Name();
 
    if (Sim.BrokenCount() != 0)
       ShortBreaks();
@@ -337,6 +340,7 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache)
    
    // We loop indefinately to get the minimal set size.
    bool Change = false;
+   unsigned int Count = 0;
    do
    {
       Change = false;
@@ -345,16 +349,21 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache)
         // Not interesting
         if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
            continue;
-        
+
         // Keep it and see if that is OK
         Cache.MarkKeep(I);
         if (Cache.BrokenCount() != 0)
            Cache.MarkInstall(I,false);
         else
-           Change = true;
+        {
+           // If keep didnt actually do anything then there was no change..
+           if (Cache[I].Upgrade() == false)
+              Change = true;
+        }       
       }      
+      Count++;
    }
-   while (Change == true);
+   while (Change == true && Count < 10);
 
    if (Cache.BrokenCount() != 0)
       return _error->Error("Internal Error in pkgMinimizeUpgrade");
@@ -706,13 +715,18 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
         // Isolate the problem dependency
         PackageKill KillList[100];
         PackageKill *LEnd = KillList;
-        for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false;)
+        bool InOr = false;
+        pkgCache::DepIterator Start;
+        pkgCache::DepIterator End;
+        for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList();
+             D.end() == false || InOr == true;)
         {
            // Compute a single dependency element (glob or)
-           pkgCache::DepIterator Start;
-           pkgCache::DepIterator End;
-           D.GlobOr(Start,End);
-           
+           if (InOr == false)
+              D.GlobOr(Start,End);
+           else
+              Start++;
+
            // We only worry about critical deps.
            if (End.IsCritical() != true)
               continue;
@@ -721,25 +735,27 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
            if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
               continue;
            
+           InOr = Start != End;
+           
            // Hm, the group is broken.. I have no idea how to handle this
-           if (Start != End)
+/*         if (Start != End)
            {
               if (Debug == true)
                  clog << "Note, a broken or group was found in " << I.Name() << "." << endl;
               if ((Flags[I->ID] & Protected) != Protected)
                  Cache.MarkDelete(I);
               break;
-           }
+           }*/
                    
            if (Debug == true)
-              clog << "Package " << I.Name() << " has broken dep on " << End.TargetPkg().Name() << endl;
+              clog << "Package " << I.Name() << " has broken dep on " << Start.TargetPkg().Name() << endl;
 
            /* Look across the version list. If there are no possible
               targets then we keep the package and bail. This is necessary
               if a package has a dep on another package that cant be found */
-           pkgCache::Version **VList = End.AllTargets();
+           pkgCache::Version **VList = Start.AllTargets();
            if (*VList == 0 && (Flags[I->ID] & Protected) != Protected &&
-               End->Type != pkgCache::Dep::Conflicts && 
+               Start->Type != pkgCache::Dep::Conflicts && 
                Cache[I].NowBroken() == false)
            {
               Change = true;
@@ -754,10 +770,10 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
               pkgCache::PkgIterator Pkg = Ver.ParentPkg();
            
               if (Debug == true)
-                 clog << "  Considering " << Pkg.Name() << ' ' << (int)Scores[Pkg->ID] << 
+                 clog << "  Considering " << Pkg.Name() << ' ' << (int)Scores[Pkg->ID] <<
                  " as a solution to " << I.Name() << ' ' << (int)Scores[I->ID] << endl;
               if (Scores[I->ID] <= Scores[Pkg->ID] ||
-                  ((Cache[End] & pkgDepCache::DepGNow) == 0 &&
+                  ((Cache[Start] & pkgDepCache::DepNow) == 0 &&
                    End->Type != pkgCache::Dep::Conflicts))
               {
                  // Try a little harder to fix protected packages..
@@ -774,17 +790,21 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
                  if (Cache[I].InstBroken() == false)
                  {
                     if (Debug == true)
-                       clog << "  Holding Back " << I.Name() << " rather than change " << End.TargetPkg().Name() << endl;
+                       clog << "  Holding Back " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl;
                  }               
                  else
-                 {
+                 {                  
                     if (BrokenFix == false || DoUpgrade(I) == false)
                     {
-                       if (Debug == true)
-                          clog << "  Removing " << I.Name() << " rather than change " << End.TargetPkg().Name() << endl;
-                       Cache.MarkDelete(I);
-                       if (Counter > 1)
-                          Scores[I->ID] = Scores[Pkg->ID];
+                       // Consider other options
+                       if (InOr == false)
+                       {
+                          if (Debug == true)
+                             clog << "  Removing " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl;
+                          Cache.MarkDelete(I);
+                          if (Counter > 1)
+                             Scores[I->ID] = Scores[Pkg->ID];
+                       }                       
                     }
                  }
                                  
@@ -802,25 +822,25 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
                  LEnd->Dep = End;
                  LEnd++;
                  
-                 if (End->Type != pkgCache::Dep::Conflicts)
+                 if (Start->Type != pkgCache::Dep::Conflicts)
                     break;
               }
            }
 
            // Hm, nothing can possibly satisify this dep. Nuke it.
-           if (VList[0] == 0 && End->Type != pkgCache::Dep::Conflicts &&
-               (Flags[I->ID] & Protected) != Protected)
+           if (VList[0] == 0 && Start->Type != pkgCache::Dep::Conflicts &&
+               (Flags[I->ID] & Protected) != Protected && InOr == false)
            {
               Cache.MarkKeep(I);
               if (Cache[I].InstBroken() == false)
               {
                  if (Debug == true)
-                    clog << "  Holding Back " << I.Name() << " because I can't find " << End.TargetPkg().Name() << endl;
+                    clog << "  Holding Back " << I.Name() << " because I can't find " << Start.TargetPkg().Name() << endl;
               }               
               else
               {
                  if (Debug == true)
-                    clog << "  Removing " << I.Name() << " because I can't find " << End.TargetPkg().Name() << endl;
+                    clog << "  Removing " << I.Name() << " because I can't find " << Start.TargetPkg().Name() << endl;
                  Cache.MarkDelete(I);
               }
 
@@ -828,6 +848,10 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
               Done = true;
            }
            
+           // Try some more
+           if (InOr == true)
+              continue;
+           
            delete [] VList;
            if (Done == true)
               break;