Handle virtual packages
authorMichael Spang <mspang@csclub.uwaterloo.ca>
Sat, 12 Dec 2009 08:06:03 +0000 (03:06 -0500)
committerMichael Spang <mspang@csclub.uwaterloo.ca>
Tue, 22 Dec 2009 03:11:48 +0000 (22:11 -0500)
Signed-off-by: Michael Spang <mspang@csclub.uwaterloo.ca>
Makefile
inapt.cc
inapt.h
parser.rl

index 501efa3..eaf7630 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-CPPFLAGS := -g3 -O2 -Wall -Werror
+CPPFLAGS := -g3 -O0 -Wall -Werror
 LDFLAGS  := -Wl,--as-needed
 INCLUDES := $(shell krb5-config --cflags)
 override CFLAGS  += -std=gnu99 $(INCLUDES)
index d8f93b9..3e6ac19 100644 (file)
--- a/inapt.cc
+++ b/inapt.cc
@@ -220,14 +220,31 @@ static void exec_actions(std::vector<inapt_action *> *final_actions) {
         pkgCache::PkgIterator pkg = cache->FindPkg((*i)->package);
         if (pkg.end())
             fatal("%s:%d: No such package: %s", (*i)->filename, (*i)->linenum, (*i)->package);
-        (*i)->obj = &pkg;
+        (*i)->pkg = pkg;
+        if (!cachef[pkg].CandidateVer) {
+            if (pkg->ProvidesList) {
+                if (!pkg.ProvidesList()->NextProvides) {
+                    pkgCache::PkgIterator tmp = pkg.ProvidesList().OwnerPkg();
+                    if ((*i)->action == inapt_action::INSTALL) {
+                        debug("selecting %s instead of %s", tmp.Name(), pkg.Name());
+                        (*i)->pkg = tmp;
+                    } else {
+                        debug("will not remove %s instead of virtual package %s", tmp.Name(), pkg.Name());
+                    }
+                } else {
+                    fatal("%s is a virtual package", pkg.Name());
+                }
+            } else {
+                fatal("%s is a virtual packages with no provides", pkg.Name());
+            }
+        }
     }
 
     for (vector<inapt_action *>::iterator i = final_actions->begin(); i < final_actions->end(); i++) {
-        pkgCache::PkgIterator j = *(pkgCache::PkgIterator *)(*i)->obj;
+        pkgCache::PkgIterator j = (*i)->pkg;
         switch ((*i)->action) {
             case inapt_action::INSTALL:
-                if (!cachef[j].InstallVer || cachef[j].Delete()) {
+                if (!j.CurVersion() || cachef[j].Delete()) {
                     printf("preinstall %s %s:%d\n", (*i)->package, (*i)->filename, (*i)->linenum);
                     DCache->MarkInstall(j, true);
                 }
@@ -240,20 +257,22 @@ static void exec_actions(std::vector<inapt_action *> *final_actions) {
     }
 
     for (vector<inapt_action *>::iterator i = final_actions->begin(); i < final_actions->end(); i++) {
-        pkgCache::PkgIterator j = *(pkgCache::PkgIterator *)(*i)->obj;
+        pkgCache::PkgIterator j = (*i)->pkg;
         switch ((*i)->action) {
             case inapt_action::INSTALL:
-                if (!cachef[j].InstallVer || cachef[j].Delete()) {
+                if (!j.CurVersion() || cachef[j].Delete()) {
                     printf("install %s %s:%d\n", (*i)->package, (*i)->filename, (*i)->linenum);
                     DCache->MarkInstall(j, false);
                 } else {
-                    printf("install %s %s:%d\n", (*i)->package, (*i)->filename, (*i)->linenum);
+                    //printf("install %s %s:%d NTD\n", (*i)->package, (*i)->filename, (*i)->linenum);
                 }
                 break;
             case inapt_action::REMOVE:
-                if (cachef[j].InstallVer || cachef[j].Delete()) {
-                    printf("remove %s %s:%d\n", (*i)->package, (*i)->filename, (*i)->linenum);
+                if (j.CurVersion() || cachef[j].Install()) {
+                    printf("remove %s %s:%d %s\n", (*i)->package, (*i)->filename, (*i)->linenum, j.CurVersion());
                     DCache->MarkDelete(j, false);
+                } else {
+                    //printf("remove %s %s:%d NTD\n", (*i)->package, (*i)->filename, (*i)->linenum);
                 }
                 break;
             default:
diff --git a/inapt.h b/inapt.h
index 8b600a7..c00f44e 100644 (file)
--- a/inapt.h
+++ b/inapt.h
@@ -1,4 +1,5 @@
 #include <vector>
+#include <apt-pkg/pkgcache.h>
 
 struct inapt_conditional;
 
@@ -7,7 +8,7 @@ struct inapt_action {
     enum action_t { INSTALL, REMOVE, UNSET } action;
     const char *filename;
     int linenum;
-    void *obj;
+    pkgCache::PkgIterator pkg;
 };
 
 struct inapt_block {
index 977f154..a434b94 100644 (file)
--- a/parser.rl
+++ b/parser.rl
@@ -21,7 +21,7 @@ using namespace std;
 
     action add_list {
         inapt_action *tmp_action = new inapt_action;
-        tmp_action->package = xstrndup(ts, p - ts);
+        tmp_action->package = xstrndup(ts, p - ts); ts = 0;
         tmp_action->action = curaction;
         tmp_action->linenum = curline;
         tmp_action->filename = curfile;
@@ -60,7 +60,7 @@ using namespace std;
 
     action start_conditional {
         inapt_conditional *cond = new inapt_conditional;
-        cond->condition = xstrndup(ts, p - ts);
+        cond->condition = xstrndup(ts, p - ts); ts = 0;
         conditional_stack.push_back(cond);
     }