]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/tagfile.cc
sync TFRewrite*Order arrays with dpkg and dak
[apt.git] / apt-pkg / tagfile.cc
index 7085e7d6968606646c26b2e5ada590784522de1c..2f7900d93693676fd02a993bf992896097ed7514 100644 (file)
@@ -47,6 +47,23 @@ public:
    unsigned long long Size;
 };
 
+class pkgTagSectionPrivate
+{
+public:
+   pkgTagSectionPrivate()
+   {
+   }
+   struct TagData {
+      unsigned int StartTag;
+      unsigned int EndTag;
+      unsigned int StartValue;
+      unsigned int NextInBucket;
+
+      TagData(unsigned int const StartTag) : StartTag(StartTag), EndTag(0), StartValue(0), NextInBucket(0) {}
+   };
+   std::vector<TagData> Tags;
+};
+
 static unsigned long AlphaHash(const char *Text, size_t Length)                /*{{{*/
 {
    /* This very simple hash function for the last 8 letters gives
@@ -166,8 +183,8 @@ bool pkgTagFile::Step(pkgTagSection &Tag)
            break;
 
         if (Resize() == false)
-           return _error->Error(_("Unable to parse package file %s (1)"),
-                 d->Fd.Name().c_str());
+           return _error->Error(_("Unable to parse package file %s (%d)"),
+                 d->Fd.Name().c_str(), 1);
 
       } while (Tag.Scan(d->Start,d->End - d->Start, false) == false);
    }
@@ -266,7 +283,7 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset)
       return false;
    
    if (Tag.Scan(d->Start, d->End - d->Start, false) == false)
-      return _error->Error(_("Unable to parse package file %s (2)"),d->Fd.Name().c_str());
+      return _error->Error(_("Unable to parse package file %s (%d)"),d->Fd.Name().c_str(), 2);
    
    return true;
 }
@@ -274,21 +291,34 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset)
 // pkgTagSection::pkgTagSection - Constructor                          /*{{{*/
 // ---------------------------------------------------------------------
 /* */
+APT_IGNORE_DEPRECATED_PUSH
 pkgTagSection::pkgTagSection()
    : Section(0), d(NULL), Stop(0)
 {
-   memset(&LookupTable, 0, sizeof(LookupTable));
+   d = new pkgTagSectionPrivate();
+#if APT_PKG_ABI < 413
+   TagCount = 0;
+   memset(&Indexes, 0, sizeof(Indexes));
+#endif
+   memset(&AlphaIndexes, 0, sizeof(AlphaIndexes));
 }
+APT_IGNORE_DEPRECATED_POP
                                                                        /*}}}*/
 // TagSection::Scan - Scan for the end of the header information       /*{{{*/
+#if APT_PKG_ABI < 413
+bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
+{
+   return Scan(Start, MaxLength, true);
+}
+#endif
 bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const Restart)
 {
    Section = Start;
    const char *End = Start + MaxLength;
 
-   if (Restart == false && Tags.empty() == false)
+   if (Restart == false && d->Tags.empty() == false)
    {
-      Stop = Section + Tags.back().StartTag;
+      Stop = Section + d->Tags.back().StartTag;
       if (End <= Stop)
         return false;
       Stop = (const char *)memchr(Stop,'\n',End - Stop);
@@ -299,19 +329,23 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
    else
    {
       Stop = Section;
-      if (Tags.empty() == false)
+      if (d->Tags.empty() == false)
       {
-        memset(&LookupTable, 0, sizeof(LookupTable));
-        Tags.clear();
+        memset(&AlphaIndexes, 0, sizeof(AlphaIndexes));
+        d->Tags.clear();
       }
-      Tags.reserve(0x100);
+      d->Tags.reserve(0x100);
    }
-   size_t TagCount = Tags.size();
+#if APT_PKG_ABI >= 413
+   unsigned int TagCount = d->Tags.size();
+#else
+   APT_IGNORE_DEPRECATED(TagCount = d->Tags.size();)
+#endif
 
    if (Stop == 0)
       return false;
 
-   TagData lastTagData(0);
+   pkgTagSectionPrivate::TagData lastTagData(0);
    lastTagData.EndTag = 0;
    unsigned long lastTagHash = 0;
    while (Stop < End)
@@ -329,14 +363,20 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
         // store the last found tag
         if (lastTagData.EndTag != 0)
         {
-           if (LookupTable[lastTagHash] != 0)
-              lastTagData.NextInBucket = LookupTable[lastTagHash];
-           LookupTable[lastTagHash] = TagCount;
-           Tags.push_back(lastTagData);
+           if (AlphaIndexes[lastTagHash] != 0)
+              lastTagData.NextInBucket = AlphaIndexes[lastTagHash];
+           APT_IGNORE_DEPRECATED_PUSH
+           AlphaIndexes[lastTagHash] = TagCount;
+#if APT_PKG_ABI < 413
+           if (d->Tags.size() < sizeof(Indexes)/sizeof(Indexes[0]))
+              Indexes[d->Tags.size()] = lastTagData.StartTag;
+#endif
+           APT_IGNORE_DEPRECATED_POP
+           d->Tags.push_back(lastTagData);
         }
 
-        ++TagCount;
-        lastTagData = TagData(Stop - Section);
+        APT_IGNORE_DEPRECATED(++TagCount;)
+        lastTagData = pkgTagSectionPrivate::TagData(Stop - Section);
         // find the colon separating tag and value
         char const * Colon = (char const *) memchr(Stop, ':', End - Stop);
         if (Colon == NULL)
@@ -371,14 +411,20 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
       {
         if (lastTagData.EndTag != 0)
         {
-           if (LookupTable[lastTagHash] != 0)
-              lastTagData.NextInBucket = LookupTable[lastTagHash];
-           LookupTable[lastTagHash] = TagCount;
-           Tags.push_back(lastTagData);
+           if (AlphaIndexes[lastTagHash] != 0)
+              lastTagData.NextInBucket = AlphaIndexes[lastTagHash];
+           APT_IGNORE_DEPRECATED(AlphaIndexes[lastTagHash] = TagCount;)
+#if APT_PKG_ABI < 413
+           APT_IGNORE_DEPRECATED(Indexes[d->Tags.size()] = lastTagData.StartTag;)
+#endif
+           d->Tags.push_back(lastTagData);
         }
 
-        TagData const td(Stop - Section);
-        Tags.push_back(td);
+        pkgTagSectionPrivate::TagData const td(Stop - Section);
+#if APT_PKG_ABI < 413
+        APT_IGNORE_DEPRECATED(Indexes[d->Tags.size()] = td.StartTag;)
+#endif
+        d->Tags.push_back(td);
         TrimRecord(false,End);
         return true;
       }
@@ -408,7 +454,11 @@ void pkgTagSection::Trim()
 }
                                                                        /*}}}*/
 // TagSection::Exists - return True if a tag exists                    /*{{{*/
+#if APT_PKG_ABI >= 413
 bool pkgTagSection::Exists(const char* const Tag) const
+#else
+bool pkgTagSection::Exists(const char* const Tag)
+#endif
 {
    unsigned int tmp;
    return Find(Tag, tmp);
@@ -420,16 +470,16 @@ bool pkgTagSection::Exists(const char* const Tag) const
 bool pkgTagSection::Find(const char *Tag,unsigned int &Pos) const
 {
    size_t const Length = strlen(Tag);
-   unsigned int Bucket = LookupTable[AlphaHash(Tag, Length)];
+   unsigned int Bucket = AlphaIndexes[AlphaHash(Tag, Length)];
    if (Bucket == 0)
       return false;
 
-   for (; Bucket != 0; Bucket = Tags[Bucket - 1].NextInBucket)
+   for (; Bucket != 0; Bucket = d->Tags[Bucket - 1].NextInBucket)
    {
-      if ((Tags[Bucket - 1].EndTag - Tags[Bucket - 1].StartTag) != Length)
+      if ((d->Tags[Bucket - 1].EndTag - d->Tags[Bucket - 1].StartTag) != Length)
         continue;
 
-      char const * const St = Section + Tags[Bucket - 1].StartTag;
+      char const * const St = Section + d->Tags[Bucket - 1].StartTag;
       if (strncasecmp(Tag,St,Length) != 0)
         continue;
 
@@ -447,9 +497,9 @@ bool pkgTagSection::Find(const char *Tag,const char *&Start,
    if (Find(Tag, Pos) == false)
       return false;
 
-   Start = Section + Tags[Pos].StartValue;
+   Start = Section + d->Tags[Pos].StartValue;
    // Strip off the gunk from the end
-   End = Section + Tags[Pos + 1].StartTag;
+   End = Section + d->Tags[Pos + 1].StartTag;
    if (unlikely(Start > End))
       return _error->Error("Internal parsing error");
 
@@ -561,78 +611,26 @@ bool pkgTagSection::FindFlag(unsigned long &Flags, unsigned long Flag,
    return true;
 }
                                                                        /*}}}*/
+void pkgTagSection::Get(const char *&Start,const char *&Stop,unsigned int I) const
+{
+   Start = Section + d->Tags[I].StartTag;
+   Stop = Section + d->Tags[I+1].StartTag;
+}
 APT_PURE unsigned int pkgTagSection::Count() const {                   /*{{{*/
-   if (Tags.empty() == true)
+   if (d->Tags.empty() == true)
       return 0;
    // the last element is just marking the end and isn't a real one
-   return Tags.size() - 1;
+   return d->Tags.size() - 1;
 }
                                                                        /*}}}*/
+
+#include "tagfile-order.c"
+
 // TFRewrite - Rewrite a control record                                        /*{{{*/
 // ---------------------------------------------------------------------
 /* This writes the control record to stdout rewriting it as necessary. The
    override map item specificies the rewriting rules to follow. This also
    takes the time to sort the feild list. */
-
-/* The order of this list is taken from dpkg source lib/parse.c the fieldinfos
-   array. */
-static const char *iTFRewritePackageOrder[] = {
-                          "Package",
-                          "Essential",
-                          "Status",
-                          "Priority",
-                          "Section",
-                          "Installed-Size",
-                          "Maintainer",
-                          "Original-Maintainer",
-                          "Architecture",
-                          "Source",
-                          "Version",
-                           "Revision",         // Obsolete
-                           "Config-Version",   // Obsolete
-                          "Replaces",
-                          "Provides",
-                          "Depends",
-                          "Pre-Depends",
-                          "Recommends",
-                          "Suggests",
-                          "Conflicts",
-                          "Breaks",
-                          "Conffiles",
-                          "Filename",
-                          "Size",
-                          "MD5Sum",
-                          "SHA1",
-                          "SHA256",
-                          "SHA512",
-                           "MSDOS-Filename",   // Obsolete
-                          "Description",
-                          0};
-static const char *iTFRewriteSourceOrder[] = {"Package",
-                                      "Source",
-                                      "Binary",
-                                      "Version",
-                                      "Priority",
-                                      "Section",
-                                      "Maintainer",
-                                     "Original-Maintainer",
-                                      "Build-Depends",
-                                      "Build-Depends-Indep",
-                                      "Build-Conflicts",
-                                      "Build-Conflicts-Indep",
-                                      "Architecture",
-                                      "Standards-Version",
-                                      "Format",
-                                      "Directory",
-                                      "Files",
-                                      0};   
-
-/* Two levels of initialization are used because gcc will set the symbol
-   size of an array to the length of the array, causing dynamic relinking 
-   errors. Doing this makes the symbol size constant */
-const char **TFRewritePackageOrder = iTFRewritePackageOrder;
-const char **TFRewriteSourceOrder = iTFRewriteSourceOrder;
-   
 bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[],
               TFRewriteData *Rewrite)
 {
@@ -757,3 +755,5 @@ bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[],
    return true;
 }
                                                                        /*}}}*/
+
+pkgTagSection::~pkgTagSection() { delete d; }