]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/deb/deblistparser.cc
deblistparser: Make PrioList const
[apt.git] / apt-pkg / deb / deblistparser.cc
index 6a802b39f73568e35a41ff1bdd270b0c0a2704a8..229cfc29b2803c1628b99cb5c399c847f1e6e56f 100644 (file)
@@ -35,7 +35,7 @@
 
 using std::string;
 
-static debListParser::WordList PrioList[] = {
+static const debListParser::WordList PrioList[] = {
    {"required",pkgCache::State::Required},
    {"important",pkgCache::State::Important},
    {"standard",pkgCache::State::Standard},
@@ -803,13 +803,12 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
       }
       else
       {
-        string Arch = Package.substr(found+1, string::npos);
-        Package = Package.substr(0, found);
         // Such dependencies are not supposed to be accepted …
         // … but this is probably the best thing to do anyway
-        if (Arch == "native")
-           Arch = _config->Find("APT::Architecture");
-        if (NewDepends(Ver,Package,Arch,Version,Op | pkgCache::Dep::ArchSpecific,Type) == false)
+        if (Package.substr(found + 1) == "native")
+           Package = Package.substr(0, found) + ':' + Ver.Cache()->NativeArch();
+
+        if (NewDepends(Ver, Package, "any", Version, Op | pkgCache::Dep::ArchSpecific, Type) == false)
            return false;
       }
 
@@ -824,56 +823,105 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
 /* */
 bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
 {
+   /* it is unlikely, but while parsing dependencies, we might have already
+      picked up multi-arch implicit provides which we do not want to duplicate here */
+   bool hasProvidesAlready = false;
+   std::string const spzName = Ver.ParentPkg().FullName(false);
+   {
+      for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv)
+      {
+        if (Prv.IsMultiArchImplicit() == false || (Prv->Flags & pkgCache::Flag::ArchSpecific) == 0)
+           continue;
+        if (spzName != Prv.OwnerPkg().FullName(false))
+           continue;
+        hasProvidesAlready = true;
+        break;
+      }
+   }
+
+   string const Arch = Ver.Arch();
    const char *Start;
    const char *Stop;
    if (Section.Find("Provides",Start,Stop) == true)
    {
       string Package;
       string Version;
-      string const Arch = Ver.Arch();
       unsigned int Op;
 
-      while (1)
+      do
       {
-        Start = ParseDepends(Start,Stop,Package,Version,Op);
+        Start = ParseDepends(Start,Stop,Package,Version,Op, false, false, false);
         const size_t archfound = Package.rfind(':');
         if (Start == 0)
            return _error->Error("Problem parsing Provides line");
         if (Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals) {
            _error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.c_str());
         } else if (archfound != string::npos) {
-           string OtherArch = Package.substr(archfound+1, string::npos);
-           Package = Package.substr(0, archfound);
-           if (NewProvides(Ver, Package, OtherArch, Version, pkgCache::Flag::ArchSpecific) == false)
+           std::string spzArch = Package.substr(archfound + 1);
+           if (spzArch != "any")
+           {
+              if (NewProvides(Ver, Package.substr(0, archfound), spzArch, Version, pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific) == false)
+                 return false;
+           }
+           if (NewProvides(Ver, Package, "any", Version, pkgCache::Flag::ArchSpecific) == false)
               return false;
         } else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) {
-           if (NewProvidesAllArch(Ver, Package, Version, 0) == false)
-              return false;
+           if (APT::Configuration::checkArchitecture(Arch))
+              if (NewProvidesAllArch(Ver, Package, Version, 0) == false)
+                 return false;
         } else {
+           if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
+           {
+              if (NewProvides(Ver, Package + ":any", "any", Version, pkgCache::Flag::MultiArchImplicit) == false)
+                 return false;
+           }
            if (NewProvides(Ver, Package, Arch, Version, 0) == false)
               return false;
         }
+        if (archfound == std::string::npos)
+        {
+           std::string const spzName = Package + ':' + Ver.ParentPkg().Arch();
+           pkgCache::PkgIterator const spzPkg = Ver.Cache()->FindPkg(spzName, "any");
+           if (spzPkg.end() == false)
+           {
+              if (NewProvides(Ver, spzName, "any", Version, pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific) == false)
+                 return false;
+           }
+        }
+      } while (Start != Stop);
+   }
 
-        if (Start == Stop)
-           break;
+   if (APT::Configuration::checkArchitecture(Arch))
+   {
+      if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
+      {
+        string const Package = string(Ver.ParentPkg().Name()).append(":").append("any");
+        if (NewProvides(Ver, Package, "any", Ver.VerStr(), pkgCache::Flag::MultiArchImplicit) == false)
+           return false;
+      }
+      else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
+      {
+        if (NewProvidesAllArch(Ver, Ver.ParentPkg().Name(), Ver.VerStr(), pkgCache::Flag::MultiArchImplicit) == false)
+           return false;
       }
    }
 
-   if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
+   if (hasProvidesAlready == false)
    {
-      string const Package = string(Ver.ParentPkg().Name()).append(":").append("any");
-      return NewProvides(Ver, Package, "any", Ver.VerStr(), pkgCache::Flag::MultiArchImplicit);
+      pkgCache::PkgIterator const spzPkg = Ver.Cache()->FindPkg(spzName, "any");
+      if (spzPkg.end() == false)
+      {
+        if (NewProvides(Ver, spzName, "any", Ver.VerStr(), pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific) == false)
+           return false;
+      }
    }
-   else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
-      return NewProvidesAllArch(Ver, Ver.ParentPkg().Name(), Ver.VerStr(), pkgCache::Flag::MultiArchImplicit);
-
    return true;
 }
                                                                        /*}}}*/
 // ListParser::GrabWord - Matches a word and returns                   /*{{{*/
 // ---------------------------------------------------------------------
 /* Looks for a word in a list of words - for ParseStatus */
-bool debListParser::GrabWord(string Word,WordList *List,unsigned char &Out)
+bool debListParser::GrabWord(string Word,const WordList *List,unsigned char &Out)
 {
    for (unsigned int C = 0; List[C].Str != 0; C++)
    {