]> git.saurik.com Git - apt.git/commitdiff
use pkgTagFile to parse "header" of Release files
authorDavid Kalnischkies <kalnischkies@gmail.com>
Wed, 7 Aug 2013 14:45:49 +0000 (16:45 +0200)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Thu, 8 Aug 2013 13:23:56 +0000 (15:23 +0200)
The handwritten parsing here was mostly done as we couldn't trust the
Release file we got, but nowadays we are sure that the Release file is
valid and contains just a single section we want it to include.

Beside reducing code it also fixes a bug: Fieldnames in deb822 formatted
files are case-insensitive and pkgTagFile does it correctly, but this
selfbuilt stuff here didn't.

apt-pkg/deb/deblistparser.cc

index 28857176b12818df2771d539fd3c9fc83f10e3d1..c2707d0a505fd35d71b13d96a334ee19967bddf0 100644 (file)
@@ -805,94 +805,28 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
    map_ptrloc const storage = WriteUniqString(component);
    FileI->Component = storage;
 
-   // FIXME: should use FileFd and TagSection
-   FILE* release = fdopen(dup(File.Fd()), "r");
-   if (release == NULL)
+   pkgTagFile TagFile(&File);
+   pkgTagSection Section;
+   if (_error->PendingError() == true || TagFile.Step(Section) == false)
       return false;
 
-   char buffer[101];
-   while (fgets(buffer, sizeof(buffer), release) != NULL)
-   {
-      size_t len = 0;
-
-      // Skip empty lines
-      for (; buffer[len] == '\r' && buffer[len] == '\n'; ++len)
-         /* nothing */
-         ;
-      if (buffer[len] == '\0')
-        continue;
-
-      // seperate the tag from the data
-      const char* dataStart = strchr(buffer + len, ':');
-      if (dataStart == NULL)
-        continue;
-      len = dataStart - buffer;
-      for (++dataStart; *dataStart == ' '; ++dataStart)
-         /* nothing */
-         ;
-      const char* dataEnd = (const char*)rawmemchr(dataStart, '\0');
-      // The last char should be a newline, but we can never be sure: #633350
-      const char* lineEnd = dataEnd;
-      for (--lineEnd; *lineEnd == '\r' || *lineEnd == '\n'; --lineEnd)
-         /* nothing */
-         ;
-      ++lineEnd;
-
-      // which datastorage need to be updated
-      enum { Suite, Component, Version, Origin, Codename, Label, None } writeTo = None;
-      if (buffer[0] == ' ')
-        ;
-      #define APT_PARSER_WRITETO(X) else if (strncmp(#X, buffer, len) == 0) writeTo = X;
-      APT_PARSER_WRITETO(Suite)
-      APT_PARSER_WRITETO(Component)
-      APT_PARSER_WRITETO(Version)
-      APT_PARSER_WRITETO(Origin)
-      APT_PARSER_WRITETO(Codename)
-      APT_PARSER_WRITETO(Label)
-      #undef APT_PARSER_WRITETO
-      #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
-        pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, lineEnd);
-      APT_PARSER_FLAGIT(NotAutomatic)
-      APT_PARSER_FLAGIT(ButAutomaticUpgrades)
-      #undef APT_PARSER_FLAGIT
-
-      // load all data from the line and save it
-      string data;
-      if (writeTo != None)
-        data.append(dataStart, dataEnd);
-      if (sizeof(buffer) - 1 == (dataEnd - buffer))
-      {
-        while (fgets(buffer, sizeof(buffer), release) != NULL)
-        {
-           if (writeTo != None)
-              data.append(buffer);
-           if (strlen(buffer) != sizeof(buffer) - 1)
-              break;
-        }
-      }
-      if (writeTo != None)
-      {
-        // remove spaces and stuff from the end of the data line
-        for (std::string::reverse_iterator s = data.rbegin();
-             s != data.rend(); ++s)
-        {
-           if (*s != '\r' && *s != '\n' && *s != ' ')
-              break;
-           *s = '\0';
-        }
-        map_ptrloc const storage = WriteUniqString(data);
-        switch (writeTo) {
-        case Suite: FileI->Archive = storage; break;
-        case Component: FileI->Component = storage; break;
-        case Version: FileI->Version = storage; break;
-        case Origin: FileI->Origin = storage; break;
-        case Codename: FileI->Codename = storage; break;
-        case Label: FileI->Label = storage; break;
-        case None: break;
-        }
-      }
+   std::string data;
+   #define APT_INRELEASE(TAG, STORE) \
+   data = Section.FindS(TAG); \
+   if (data.empty() == false) \
+   { \
+      map_ptrloc const storage = WriteUniqString(data); \
+      STORE = storage; \
    }
-   fclose(release);
+   APT_INRELEASE("Suite", FileI->Archive)
+   APT_INRELEASE("Component", FileI->Component)
+   APT_INRELEASE("Version", FileI->Version)
+   APT_INRELEASE("Origin", FileI->Origin)
+   APT_INRELEASE("Codename", FileI->Codename)
+   APT_INRELEASE("Label", FileI->Label)
+   #undef APT_INRELEASE
+   Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic);
+   Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades);
 
    return !_error->PendingError();
 }