[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#225947: apt-utils: please support architecture-specific extra overrides



So, here's something that does seem to work correctly. The idea is:

	* When dealing with /i386 things, make GetItem return a new object
	  that includes all the overrides.

	* So we can deal with this cleanly, make GetItem *always* return a
	  new object, and always delete what GetItem returns.

	* Since C++ doesn't do garbage collection, and those functions have
	  a few early returns, make use of some dummy variables to make sure
	  the deletions actually happen. This is the IHateCPP class :(

Upside: it works, and the patch isn't too intrusive. Downside: hella
ugly on so many levels.  I'm sure there's a C++ StdLib technique for
what the IHateCPP class does, at least.

diff -urb apt-0.6.21/ftparchive/override.h apt-aj/ftparchive/override.h
--- apt-0.6.21/ftparchive/override.h	Mon Jun 25 22:50:27 2001
+++ apt-aj/ftparchive/override.h	Fri Apr 16 04:01:27 2004
@@ -40,10 +40,37 @@
    
    inline Item *GetItem(string Package) 
    {
+      return GetItem(Package, "");
+   }
+
+   inline Item *GetItem(string Package, string Architecture) 
+   {
       map<string,Item>::iterator I = Mapping.find(Package);
-      if (I == Mapping.end())
+      map<string,Item>::iterator J = Mapping.find(Package + "/" + Architecture);
+      if (I == Mapping.end() && J == Mapping.end())
+      {
 	 return 0;
-      return &I->second;
+      }
+
+      Item *result = new Item;
+      if (I == Mapping.end()) *result = J->second;
+      else
+      {
+         *result = I->second;
+	 if (J != Mapping.end())
+         {
+             Item *R = &J->second;
+             if (R->Priority != "") result->Priority = R->Priority;
+             if (R->OldMaint != "") result->OldMaint = R->OldMaint;
+             if (R->NewMaint != "") result->NewMaint = R->NewMaint;
+	     for (map<string,string>::iterator foI = R->FieldOverride.begin();
+                  foI != R->FieldOverride.end(); foI++)
+             {
+                result->FieldOverride[foI->first] = foI->second;
+             }
+         } 
+      } 
+      return result;
    };
    
    bool ReadOverride(string File,bool Source = false);
diff -urb apt-0.6.21/ftparchive/writer.cc apt-aj/ftparchive/writer.cc
--- apt-0.6.21/ftparchive/writer.cc	Sat Jan  3 19:23:22 2004
+++ apt-aj/ftparchive/writer.cc	Fri Apr 16 04:29:06 2004
@@ -36,6 +36,12 @@
 #include "apt-ftparchive.h"
 #include "multicompress.h"
 									/*}}}*/
+class IHateCPP { 
+   Override::Item **x; 
+   public: 
+   IHateCPP(Override::Item *&delme) { x = &delme; }
+   ~IHateCPP() { if (*x) delete *x; } 
+};
 
 using namespace std;
 FTWScanner *FTWScanner::Owner;
@@ -371,8 +377,9 @@
    // Lookup the overide information
    pkgTagSection &Tags = Db.Control.Section;
    string Package = Tags.FindS("Package");
-   Override::Item Tmp;
-   Override::Item *OverItem = Over.GetItem(Package);
+   string Architecture = Tags.FindS("Architecture");
+   Override::Item *OverItem = Over.GetItem(Package,Architecture);
+   IHateCPP killOverItem(OverItem);
    
    if (Package.empty() == true)
       return _error->Error(_("Archive had no package field"));
@@ -386,9 +393,9 @@
 	 ioprintf(c1out, _("  %s has no override entry\n"), Package.c_str());
       }
       
-      OverItem = &Tmp;
-      Tmp.FieldOverride["Section"] = Tags.FindS("Section");
-      Tmp.Priority = Tags.FindS("Priority");
+      OverItem = new Override::Item;
+      OverItem->FieldOverride["Section"] = Tags.FindS("Section");
+      OverItem->Priority = Tags.FindS("Priority");
    }
 
    char Size[40];
@@ -558,6 +565,7 @@
    char Buffer[1000];
    string Bins = Tags.FindS("Binary");
    Override::Item *OverItem = 0;
+   IHateCPP killOverItem(OverItem);
    if (Bins.empty() == false && Bins.length() < sizeof(Buffer))
    {
       strcpy(Buffer,Bins.c_str());
@@ -582,11 +590,11 @@
 	    BestPrioV = NewPrioV;
 	    BestPrio = Itm->Priority;
 	 }	 
+	 if (OverItem != Itm) delete Itm;
       }
    }
    
    // If we need to do any rewriting of the header do it now..
-   Override::Item Tmp;   
    if (OverItem == 0)
    {
       if (NoOverride == false)
@@ -595,15 +603,19 @@
 	 ioprintf(c1out, _("  %s has no override entry\n"), Tags.FindS("Source").c_str());
       }
       
-      OverItem = &Tmp;
+      OverItem = new Override::Item;
    }
    
    Override::Item *SOverItem = SOver.GetItem(Tags.FindS("Source"));
+   IHateCPP killSOverItem(SOverItem);
    if (SOverItem == 0)
    {
       SOverItem = BOver.GetItem(Tags.FindS("Source"));
       if (SOverItem == 0)
-	 SOverItem = OverItem;
+      {
+	 SOverItem = new Override::Item;
+	 *SOverItem = *OverItem;
+      }
    }
    
    // Add the dsc to the files hash list



Attachment: signature.asc
Description: Digital signature


Reply to: