fix typo (mkostemp->mkstemp)
[ntk/apt.git] / ftparchive / override.cc
index 93cc34e..1288ff1 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: override.cc,v 1.2 2001/02/20 07:03:18 jgg Exp $
+// $Id: override.cc,v 1.4 2003/02/10 07:34:41 doogie Exp $
 /* ######################################################################
 
    Override
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
-#ifdef __GNUG__
-#pragma implementation "override.h"
-#endif
+#include <config.h>
 
-#include "override.h"
-    
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/error.h>
 
 #include <stdio.h>
-    
+
 #include "override.h"
+
+#include <apti18n.h>
                                                                        /*}}}*/
 
 // Override::ReadOverride - Read the override file                     /*{{{*/
 // ---------------------------------------------------------------------
 /* This parses the override file and reads it into the map */
-bool Override::ReadOverride(string File,bool Source)
+bool Override::ReadOverride(string const &File,bool const &Source)
 {
    if (File.empty() == true)
       return true;
    
    FILE *F = fopen(File.c_str(),"r");
    if (F == 0)
-      return _error->Errno("fopen","Unable to open %s",File.c_str());
+      return _error->Errno("fopen",_("Unable to open %s"),File.c_str());
    
    char Line[500];
-   unsigned long Counter = 0;
+   unsigned long long Counter = 0;
    while (fgets(Line,sizeof(Line),F) != 0)
    {
       Counter++;
@@ -51,7 +49,7 @@ bool Override::ReadOverride(string File,bool Source)
       // Strip space leading up to the package name, skip blank lines
       char *Pkg = Line;
       for (; isspace(*Pkg) && *Pkg != 0;Pkg++);
-      if (Pkg == 0)
+      if (*Pkg == 0)
         continue;
 
       // Find the package and zero..
@@ -60,7 +58,7 @@ bool Override::ReadOverride(string File,bool Source)
       for (; isspace(*End) == 0 && *End != 0; End++);
       if (*End == 0)
       {
-        _error->Warning("Malformed override %s line %lu #1",File.c_str(),
+        _error->Warning(_("Malformed override %s line %llu #1"),File.c_str(),
                         Counter);
         continue;
       }      
@@ -74,7 +72,7 @@ bool Override::ReadOverride(string File,bool Source)
         for (; isspace(*End) == 0 && *End != 0; End++);
         if (*End == 0)
         {
-           _error->Warning("Malformed override %s line %lu #2",File.c_str(),
+           _error->Warning(_("Malformed override %s line %llu #2"),File.c_str(),
                            Counter);
            continue;
         }
@@ -88,12 +86,12 @@ bool Override::ReadOverride(string File,bool Source)
       for (; isspace(*End) == 0 && *End != 0; End++);
       if (*End == 0)
       {
-        _error->Warning("Malformed override %s line %lu #3",File.c_str(),
+        _error->Warning(_("Malformed override %s line %llu #3"),File.c_str(),
                         Counter);
         continue;
       }      
       *End = 0;
-      Itm.Section = Start;
+      Itm.FieldOverride["Section"] = Start;
 
       // Source override files only have the two columns
       if (Source == true)
@@ -127,18 +125,130 @@ bool Override::ReadOverride(string File,bool Source)
    }
 
    if (ferror(F))
-      _error->Errno("fgets","Failed to read the override file %s",File.c_str());
+      _error->Errno("fgets",_("Failed to read the override file %s"),File.c_str());
    fclose(F);
    return true;
 }
                                                                        /*}}}*/
+// Override::ReadExtraOverride - Read the extra override file          /*{{{*/
+// ---------------------------------------------------------------------
+/* This parses the extra override file and reads it into the map */
+bool Override::ReadExtraOverride(string const &File,bool const &Source)
+{
+   if (File.empty() == true)
+      return true;
+   
+   FILE *F = fopen(File.c_str(),"r");
+   if (F == 0)
+      return _error->Errno("fopen",_("Unable to open %s"),File.c_str());
+  
+   char Line[500];
+   unsigned long long Counter = 0;
+   while (fgets(Line,sizeof(Line),F) != 0)
+   {
+      Counter++;
+
+      // Silence 
+      for (char *I = Line; *I != 0; I++)
+        if (*I == '#')
+           *I = 0;
+
+      // Strip space leading up to the package name, skip blank lines
+      char *Pkg = Line;
+      for (; isspace(*Pkg) && *Pkg != 0;Pkg++);
+      if (Pkg == 0)
+        continue;
+
+      // Find the package and zero..
+      char *End = Pkg;
+      for (; isspace(*End) == 0 && *End != 0; End++);
+      if (*End == 0)
+      {
+        _error->Warning(_("Malformed override %s line %llu #1"),File.c_str(),
+                        Counter);
+        continue;
+      }      
+      *End = 0;
+
+      // Find the field
+      for (End++; isspace(*End) != 0 && *End != 0; End++);
+      char *Field = End;
+      for (; isspace(*End) == 0 && *End != 0; End++);
+      if (*End == 0)
+      {
+        _error->Warning(_("Malformed override %s line %llu #2"),File.c_str(),
+                        Counter);
+        continue;
+      }
+      *End = 0;
+      
+      // Find the field value 
+      for (End++; isspace(*End) != 0 && *End != 0; End++);
+      char *Value = End;
+      for (; *End != 0; End++);
+      for (; isspace(*(End-1)) && End > Value; End--);
+      if (End == Value)
+      {
+        _error->Warning(_("Malformed override %s line %llu #3"),File.c_str(),
+                        Counter);
+        continue;
+      }      
+      *End = 0;
+
+      Mapping[Pkg].FieldOverride[Field] = Value;
+   }
+
+   if (ferror(F))
+      _error->Errno("fgets",_("Failed to read the override file %s"),File.c_str());
+   fclose(F);
+   return true;
+}
+                                                                       /*}}}*/
+
+// Override::GetItem - Get a architecture specific item        /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns a override item for the given package and the given architecture.
+ * Treats "all" special
+ */
+Override::Item* Override::GetItem(string const &Package, string const &Architecture)
+{
+   map<string,Item>::const_iterator I = Mapping.find(Package);
+   map<string,Item>::iterator J = Mapping.find(Package + "/" + Architecture);
+
+   if (I == Mapping.end() && J == Mapping.end())
+   {
+      return 0;
+   }
+
+   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>::const_iterator foI = R->FieldOverride.begin();
+             foI != R->FieldOverride.end(); ++foI)
+         {
+           result->FieldOverride[foI->first] = foI->second;
+        }
+      } 
+   } 
+   return result;
+};
+
+
 // Override::Item::SwapMaint - Swap the maintainer field if necessary  /*{{{*/
 // ---------------------------------------------------------------------
 /* Returns the new maintainer string after evaluating the rewriting rule. If
    there is a rule but it does not match then the empty string is returned,
    also if there was no rewrite rule the empty string is returned. Failed
    indicates if there was some kind of problem while rewriting. */
-string Override::Item::SwapMaint(string Orig,bool &Failed)
+string Override::Item::SwapMaint(string const &Orig,bool &Failed)
 {
    Failed = false;
    
@@ -153,13 +263,13 @@ string Override::Item::SwapMaint(string Orig,bool &Failed)
       override file. Thus it persists.*/
 #if 1
    // Break OldMaint up into little bits on double slash boundaries.
-   string::iterator End = OldMaint.begin();
+   string::const_iterator End = OldMaint.begin();
    while (1)
    {
-      string::iterator Start = End;      
+      string::const_iterator Start = End;      
       for (; End < OldMaint.end() &&
           (End + 3 >= OldMaint.end() || End[0] != ' ' || 
-           End[1] != '/' || End[2] != '/'); End++);
+           End[1] != '/' || End[2] != '/'); ++End);
       if (stringcasecmp(Start,End,Orig.begin(),Orig.end()) == 0)
         return NewMaint;
       
@@ -167,7 +277,7 @@ string Override::Item::SwapMaint(string Orig,bool &Failed)
         break;
 
       // Skip the divider and white space
-      for (; End < OldMaint.end() && (*End == '/' || *End == ' '); End++);
+      for (; End < OldMaint.end() && (*End == '/' || *End == ' '); ++End);
    }
 #else
    if (stringcasecmp(OldMaint.begin(),OldMaint.end(),Orig.begin(),Orig.end()) == 0)