]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/deb/deblistparser.cc
Fixed string case compare problem
[apt.git] / apt-pkg / deb / deblistparser.cc
index 3c82ee51da2dda5ceffa4d1e47fa9746c1371919..9da03a7f60793234d8d521a38d64962304b2be79 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: deblistparser.cc,v 1.5 1998/07/09 05:12:37 jgg Exp $
+// $Id: deblistparser.cc,v 1.23 1999/09/30 06:30:34 jgg Exp $
 /* ######################################################################
    
    Package Cache Generator - Generator for the cache structure.
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
-#include <pkglib/deblistparser.h>
-#include <pkglib/error.h>
-#include <pkglib/configuration.h>
-#include <strutl.h>
+#include <apt-pkg/deblistparser.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/crc-16.h>
 
 #include <system.h>
                                                                        /*}}}*/
 // ListParser::debListParser - Constructor                             /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-debListParser::debListParser(File &File) : Tags(File)
+debListParser::debListParser(FileFd &File) : Tags(File)
 {
-}
-                                                                       /*}}}*/
-// ListParser::FindTag - Find the tag and return a string              /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string debListParser::FindTag(const char *Tag)
-{
-   const char *Start;
-   const char *Stop;
-   if (Section.Find(Tag,Start,Stop) == false)
-      return string();
-   return string(Start,Stop - Start);
-}
-                                                                       /*}}}*/
-// ListParser::FindTagI - Find the tag and return an int               /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-signed long debListParser::FindTagI(const char *Tag,signed long Default)
-{
-   const char *Start;
-   const char *Stop;
-   if (Section.Find(Tag,Start,Stop) == false)
-      return Default;
-   
-   // Copy it into a temp buffer so we can use strtol
-   char S[300];
-   if ((unsigned)(Stop - Start) >= sizeof(S))
-      return Default;
-   strncpy(S,Start,Stop-Start);
-   S[Stop - Start] = 0;
-   
-   char *End;
-   signed long Result = strtol(S,&End,10);
-   if (S == End)
-      return Default;
-   return Result;
+   Arch = _config->Find("APT::architecture");
 }
                                                                        /*}}}*/
 // ListParser::UniqFindTagWrite - Find the tag and write a unq string  /*{{{*/
@@ -73,47 +39,14 @@ unsigned long debListParser::UniqFindTagWrite(const char *Tag)
    return WriteUniqString(Start,Stop - Start);
 }
                                                                        /*}}}*/
-// ListParser::HandleFlag - Sets a flag variable based on a tag                /*{{{*/
-// ---------------------------------------------------------------------
-/* This checks the tag for true/false yes/no etc */
-bool debListParser::HandleFlag(const char *Tag,unsigned long &Flags,
-                              unsigned long Flag)
-{
-   const char *Start;
-   const char *Stop;
-   if (Section.Find(Tag,Start,Stop) == false)
-      return true;
-   
-   int Set = 2;
-   if (stringcasecmp(Start,Stop,"yes") == 0)
-      Set = 1;
-   if (stringcasecmp(Start,Stop,"true") == 0)
-      Set = 1;
-   if (stringcasecmp(Start,Stop,"no") == 0)
-      Set = 0;
-   if (stringcasecmp(Start,Stop,"false") == 0)
-      Set = 0;
-   if (Set == 2)
-   {
-      _error->Warning("Unknown flag value");
-      return true;
-   }
-   
-   if (Set == 0)
-      Flags &= ~Flag;
-   if (Set == 1)
-      Flags |= Flag;
-   return true;
-}
-                                                                       /*}}}*/
 // ListParser::Package - Return the package name                       /*{{{*/
 // ---------------------------------------------------------------------
 /* This is to return the name of the package this section describes */
 string debListParser::Package()
 {
-   string Result = FindTag("Package");
+   string Result = Section.FindS("Package");
    if (Result.empty() == true)
-      _error->Error("Encoutered a section with no Package: header");
+      _error->Error("Encountered a section with no Package: header");
    return Result;
 }
                                                                        /*}}}*/
@@ -124,7 +57,7 @@ string debListParser::Package()
    entry is assumed to only describe package properties */
 string debListParser::Version()
 {
-   return FindTag("Version");
+   return Section.FindS("Version");
 }
                                                                        /*}}}*/
 // ListParser::NewVersion - Fill in the version structure              /*{{{*/
@@ -133,16 +66,14 @@ string debListParser::Version()
 bool debListParser::NewVersion(pkgCache::VerIterator Ver)
 {
    // Parse the section
-   if ((Ver->Section = UniqFindTagWrite("Section")) == 0)
-      return _error->Warning("Missing Section tag");
+   Ver->Section = UniqFindTagWrite("Section");
+   Ver->Arch = UniqFindTagWrite("Architecture");
    
    // Archive Size
-   if ((Ver->Size = (unsigned)FindTagI("Size")) == 0)
-      return _error->Error("Unparsable Size field");
+   Ver->Size = (unsigned)Section.FindI("Size");
    
    // Unpacked Size (in K)
-   if ((Ver->InstalledSize = (unsigned)FindTagI("Installed-Size")) == 0)
-      return _error->Error("Unparsable Installed-Size field");
+   Ver->InstalledSize = (unsigned)Section.FindI("Installed-Size");
    Ver->InstalledSize *= 1024;
 
    // Priority
@@ -157,12 +88,12 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
                             {"extra",pkgCache::State::Extra}};
       if (GrabWord(string(Start,Stop-Start),PrioList,
                   _count(PrioList),Ver->Priority) == false)
-        return _error->Error("Malformed Priority line");
+        Ver->Priority = pkgCache::State::Extra;
    }
 
    if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false)
       return false;
-   if (ParseDepends(Ver,"PreDepends",pkgCache::Dep::PreDepends) == false)
+   if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false)
       return false;
    if (ParseDepends(Ver,"Suggests",pkgCache::Dep::Suggests) == false)
       return false;
@@ -170,7 +101,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
       return false;
    if (ParseDepends(Ver,"Conflicts",pkgCache::Dep::Conflicts) == false)
       return false;
-   if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Depends) == false)
+   if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false)
       return false;
 
    if (ParseProvides(Ver) == false)
@@ -187,24 +118,68 @@ bool debListParser::UsePackage(pkgCache::PkgIterator Pkg,
                               pkgCache::VerIterator Ver)
 {
    if (Pkg->Section == 0)
-      if ((Pkg->Section = UniqFindTagWrite("Section")) == 0)
-        return false;
-   if (HandleFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false)
+      Pkg->Section = UniqFindTagWrite("Section");
+   if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false)
       return false;
-   if (HandleFlag("Immediate-Configure",Pkg->Flags,pkgCache::Flag::ImmediateConf) == false)
+   if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false)
       return false;
+
+   if (strcmp(Pkg.Name(),"apt") == 0)
+      Pkg->Flags |= pkgCache::Flag::Important;
+   
    if (ParseStatus(Pkg,Ver) == false)
       return false;
    return true;
 }
                                                                        /*}}}*/
+// ListParser::VersionHash - Compute a unique hash for this version    /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+unsigned short debListParser::VersionHash()
+{
+   const char *Sections[] ={"Installed-Size",
+                            "Depends",
+                            "Pre-Depends",
+//                            "Suggests",
+//                            "Recommends",
+                            "Conflicts",
+                            "Replaces",0};
+   unsigned long Result = INIT_FCS;
+   char S[300];
+   for (const char **I = Sections; *I != 0; I++)
+   {
+      const char *Start;
+      const char *End;
+      if (Section.Find(*I,Start,End) == false || End - Start >= (signed)sizeof(S))
+        continue;
+      
+      /* Strip out any spaces from the text, this undoes dpkgs reformatting
+         of certain fields. dpkg also has the rather interesting notion of
+         reformatting depends operators < -> <= */
+      char *I = S;
+      for (; Start != End; Start++)
+      {
+        if (isspace(*Start) == 0)
+           *I++ = tolower(*Start);
+        if (*Start == '<' && Start[1] != '<' && Start[1] != '=')
+           *I++ = '=';
+        if (*Start == '>' && Start[1] != '>' && Start[1] != '=')
+           *I++ = '=';
+      }
+      
+      Result = AddCRC16(Result,S,I - S);
+   }
+   
+   return Result;
+}
+                                                                       /*}}}*/
 // ListParser::ParseStatus - Parse the status field                    /*{{{*/
 // ---------------------------------------------------------------------
 /* Status lines are of the form,
      Status: want flag status
    want = unknown, install, hold, deinstall, purge
    flag = ok, reinstreq, hold, hold-reinstreq
-   status = not-installed, unpacked, half-configured, uninstalled,
+   status = not-installed, unpacked, half-configured,
             half-installed, config-files, post-inst-failed, 
             removal-failed, installed
    
@@ -263,7 +238,6 @@ bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg,
                             {"unpacked",pkgCache::State::UnPacked},
                             {"half-configured",pkgCache::State::HalfConfigured},
                             {"installed",pkgCache::State::Installed},
-                            {"uninstalled",pkgCache::State::UnInstalled},
                             {"half-installed",pkgCache::State::HalfInstalled},
                             {"config-files",pkgCache::State::ConfigFiles},
                             {"post-inst-failed",pkgCache::State::HalfConfigured},
@@ -386,7 +360,11 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
       if (I == Stop || Start == I)
         return 0;     
       
-      Ver = string(Start,I-Start);
+      // Skip trailing whitespace
+      const char *End = I;
+      for (; End > Start && isspace(End[-1]); End--);
+      
+      Ver = string(Start,End-Start);
       I++;
    }
    else
@@ -426,13 +404,16 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
    string Version;
    unsigned int Op;
 
-   while ((Start = ParseDepends(Start,Stop,Package,Version,Op)) != Stop)
+   while (1)
    {
+      Start = ParseDepends(Start,Stop,Package,Version,Op);
       if (Start == 0)
         return _error->Error("Problem parsing dependency %s",Tag);
-
+      
       if (NewDepends(Ver,Package,Version,Op,Type) == false)
         return false;
+      if (Start == Stop)
+        break;
    }
    return true;
 }
@@ -492,11 +473,11 @@ bool debListParser::GrabWord(string Word,WordList *List,int Count,
 bool debListParser::Step()
 {
    iOffset = Tags.Offset();
-   string Arch = _config->Find("APT::architecture");
    while (Tags.Step(Section) == true)
-   {
-      /* See if this is the correct Architecture, if it isnt then we
-         drop the whole section */
+   {      
+      /* See if this is the correct Architecture, if it isn't then we
+         drop the whole section. A missing arch tag only happens (in theory)
+         inside the Status file, so that is a positive return */
       const char *Start;
       const char *Stop;
       if (Section.Find("Architecture",Start,Stop) == false)
@@ -513,3 +494,36 @@ bool debListParser::Step()
    return false;
 }
                                                                        /*}}}*/
+// ListParser::LoadReleaseInfo - Load the release information          /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
+                                   FileFd &File)
+{
+   pkgTagFile Tags(File);
+   pkgTagSection Section;
+   if (Tags.Step(Section) == false)
+      return false;
+
+   const char *Start;
+   const char *Stop;
+   if (Section.Find("Archive",Start,Stop) == true)
+      FileI->Archive = WriteUniqString(Start,Stop - Start);
+   if (Section.Find("Component",Start,Stop) == true)
+      FileI->Component = WriteUniqString(Start,Stop - Start);
+   if (Section.Find("Version",Start,Stop) == true)
+      FileI->Version = WriteUniqString(Start,Stop - Start);
+   if (Section.Find("Origin",Start,Stop) == true)
+      FileI->Origin = WriteUniqString(Start,Stop - Start);
+   if (Section.Find("Label",Start,Stop) == true)
+      FileI->Label = WriteUniqString(Start,Stop - Start);
+   if (Section.Find("Architecture",Start,Stop) == true)
+      FileI->Architecture = WriteUniqString(Start,Stop - Start);
+   
+   if (Section.FindFlag("NotAutomatic",FileI->Flags,
+                       pkgCache::Flag::NotAutomatic) == false)
+      _error->Warning("Bad NotAutomatic flag");
+   
+   return !_error->PendingError();
+}
+                                                                       /*}}}*/