]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/algorithms.cc
* slighly more debug output, renamed "--automatic-remove" to "--auto-remove"
[apt.git] / apt-pkg / algorithms.cc
index 11f5b5671679f313bcd5beffcbf98927f7cc0d8f..3978e7561a12a0e441ee6d62c9b3d8c126b75787 100644 (file)
@@ -26,7 +26,8 @@
 
     
 #include <apti18n.h>
 
     
 #include <apti18n.h>
-    
+#include <sys/types.h>
+#include <regex.h>
 #include <iostream>
                                                                        /*}}}*/
 using namespace std;
 #include <iostream>
                                                                        /*}}}*/
 using namespace std;
@@ -1329,6 +1330,19 @@ void pkgMarkPackage(pkgDepCache &Cache,
 }
 
 
 }
 
 
+// Helper for APT::NeverAutoRemove, always include the packages matching
+// this regexp into the root-set
+inline bool 
+pkgMarkAlwaysInclude(pkgCache::PkgIterator p, vector<regex_t*> alwaysMark)
+{
+   for(unsigned int i=0;i<alwaysMark.size();i++)
+      if (regexec(alwaysMark[i],p.Name(),0,0,0) == 0)
+        return true;
+
+   return false;
+}
+
+// the main mark algorithm
 bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func)
 {
    bool follow_recommends;
 bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func)
 {
    bool follow_recommends;
@@ -1339,6 +1353,11 @@ bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func)
    {
       Cache[p].Marked=false;
       Cache[p].Garbage=false;
    {
       Cache[p].Marked=false;
       Cache[p].Garbage=false;
+
+      // debug output
+      if(_config->FindB("Debug::pkgAutoRemove",false) 
+        && Cache[p].Flags & pkgCache::Flag::Auto)
+        std::clog << "AutoDep: " << p.Name() << std::endl;
    }
 
    // init vars
    }
 
    // init vars
@@ -1346,17 +1365,46 @@ bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func)
    follow_suggests=_config->FindB("APT::AutoRemove::SuggestsImportant", false);
 
 
    follow_suggests=_config->FindB("APT::AutoRemove::SuggestsImportant", false);
 
 
-   // do the mark part
+   // init the "NeverAutoRemove" variable
+   vector<regex_t *> neverAutoRemoveRegexp;
+   Configuration::Item const *Opts;
+   Opts = _config->Tree("APT::NeverAutoRemove");
+   if (Opts != 0 && Opts->Child != 0)
+   {
+      Opts = Opts->Child;
+      for (; Opts != 0; Opts = Opts->Next)
+      {
+        if (Opts->Value.empty() == true)
+           continue;
+
+        regex_t *p = new regex_t;
+        if(regcomp(p,Opts->Value.c_str(),
+                   REG_EXTENDED | REG_ICASE |  REG_NOSUB) != 0)
+        {
+           regfree(p);
+           for(unsigned int i=0;i<neverAutoRemoveRegexp.size();i++)
+              regfree(neverAutoRemoveRegexp[i]);
+           return _error->Error("Regex compilation error for APT::NeverAutoRemove");
+        }
+        neverAutoRemoveRegexp.push_back(p);
+      }
+   }
+
+
+   // do the mark part, this is the core bit of the algorithm
    for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p)
    {
       if( (func != NULL ? (*func)(p) : false) ||
    for(pkgCache::PkgIterator p=Cache.PkgBegin(); !p.end(); ++p)
    {
       if( (func != NULL ? (*func)(p) : false) ||
+          pkgMarkAlwaysInclude(p, neverAutoRemoveRegexp) ||
         !(Cache[p].Flags & pkgCache::Flag::Auto) ||
          (p->Flags & pkgCache::Flag::Essential))
           
       {
         !(Cache[p].Flags & pkgCache::Flag::Auto) ||
          (p->Flags & pkgCache::Flag::Essential))
           
       {
+        // the package is installed (and set to keep)
         if(Cache[p].Keep() && !p.CurrentVer().end())
            pkgMarkPackage(Cache, p, p.CurrentVer(),
                           follow_recommends, follow_suggests);
         if(Cache[p].Keep() && !p.CurrentVer().end())
            pkgMarkPackage(Cache, p, p.CurrentVer(),
                           follow_recommends, follow_suggests);
+        // the package is to be installed 
         else if(Cache[p].Install())
            pkgMarkPackage(Cache, p, Cache[p].InstVerIter(Cache),
                           follow_recommends, follow_suggests);
         else if(Cache[p].Install())
            pkgMarkPackage(Cache, p, Cache[p].InstVerIter(Cache),
                           follow_recommends, follow_suggests);
@@ -1369,14 +1417,13 @@ bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func)
   {
      pkgDepCache::StateCache &state=Cache[p];
 
   {
      pkgDepCache::StateCache &state=Cache[p];
 
-     if(!state.Marked)
+     // if it is not marked and it is installed, it's garbage 
+     if(!state.Marked && !p.CurrentVer().end())
      {
      {
-       // mark installed but not yet marked stuff as garbage
-       if(p->CurrentVer != 0) {
-          state.Garbage=true;
+       state.Garbage=true;
+       if(_config->FindB("Debug::pkgAutoRemove",false))
           std::cout << "Garbage: " << p.Name() << std::endl;
           std::cout << "Garbage: " << p.Name() << std::endl;
-       }
-
+     
 #if 0   // mvo: the below bits still needs to be ported
 
        // Be sure not to re-delete already deleted packages.
 #if 0   // mvo: the below bits still needs to be ported
 
        // Be sure not to re-delete already deleted packages.
@@ -1434,5 +1481,11 @@ bool pkgMarkUsed(pkgDepCache &Cache, InRootSetFunc func)
 #endif
      }
   }
 #endif
      }
   }
+
+   // cleanup
+   for(unsigned int i=0;i<neverAutoRemoveRegexp.size();i++)
+      regfree(neverAutoRemoveRegexp[i]);
+   
+
    return true;
 }
    return true;
 }