Просмотр исходного кода

* merged latest fixes from debian-sid
* apt-pkg/contrib/sha1.cc:
- fix illegally casts of on-stack buffer to a type requiring more
alignment than it has resulting in segfaults on sparc (Closes: #634696)
* apt-pkg/contrib/cdromutl.cc:
- fix escape problem when looking for the mounted devices
* apt-pkg/contrib/strutl.{h,cc}, test/libapt/strutil_test.cc:
- add new DeEscapeString() similar to DeQuoteString but
unescape character escapes like \0XX and \xXX (plus added
test)
* refresh po/*

* cmdline/apt-get.cc:
- fix missing download progress in apt-get download
- do not require unused partial dirs in 'source' (Closes: #633510)
- buildconflicts effect all architectures
- implement MultiarchCross for build-dep and source (Closes: #632221)
* cmdline/apt-key:
- use a tmpfile instead of /etc/apt/secring.gpg (Closes: #632596)
* debian/apt.postinst:
- remove /etc/apt/secring.gpg if it is an empty file
* doc/apt-cache.8.xml:
- apply madison typofix from John Feuerstein, thanks! (Closes: #633455)
* apt-pkg/policy.cc:
- emit an error on unknown APT::Default-Release value (Closes: #407511)
* apt-pkg/aptconfiguration.cc:
- ensure that native architecture is if not specified otherwise the
first architecture in the Architectures vector
* apt-pkg/deb/deblistparser.cc:
- Strip only :any and :native if MultiArch should be stripped as it is
save to ignore them in non-MultiArch contexts but if the dependency
is a specific architecture (and not the native) do not strip

Michael Vogt лет назад: 15
Родитель
Сommit
0b7d641cf1
76 измененных файлов с 23142 добавлено и 18282 удалено
  1. 2 0
      apt-pkg/acquire.h
  2. 1 1
      apt-pkg/aptconfiguration.cc
  3. 3 1
      apt-pkg/contrib/cdromutl.cc
  4. 1 1
      apt-pkg/contrib/configuration.cc
  5. 1 1
      apt-pkg/contrib/configuration.h
  6. 2 3
      apt-pkg/contrib/sha1.cc
  7. 61 0
      apt-pkg/contrib/strutl.cc
  8. 4 0
      apt-pkg/contrib/strutl.h
  9. 6 3
      apt-pkg/deb/deblistparser.cc
  10. 16 2
      apt-pkg/policy.cc
  11. 203 104
      cmdline/apt-get.cc
  12. 4 1
      cmdline/apt-key
  13. 5 0
      debian/apt.postinst
  14. 44 2
      debian/changelog
  15. 1 1
      doc/apt-cache.8.xml
  16. 24 3
      doc/apt-get.8.xml
  17. 1 0
      doc/examples/configure-index
  18. 1 1
      doc/po/apt-doc.pot
  19. 2 2
      doc/po/de.po
  20. 1 1
      doc/po/es.po
  21. 1 1
      doc/po/fr.po
  22. 1 1
      doc/po/it.po
  23. 2 2
      doc/po/ja.po
  24. 2 2
      doc/po/pl.po
  25. 2 2
      doc/po/pt.po
  26. 4 1
      doc/po/pt_BR.po
  27. 519 416
      po/ar.po
  28. 533 420
      po/ast.po
  29. 535 421
      po/bg.po
  30. 515 415
      po/bs.po
  31. 620 631
      po/ca.po
  32. 529 420
      po/cs.po
  33. 527 420
      po/cy.po
  34. 531 420
      po/da.po
  35. 533 420
      po/de.po
  36. 523 420
      po/dz.po
  37. 524 419
      po/el.po
  38. 534 420
      po/es.po
  39. 524 419
      po/eu.po
  40. 524 419
      po/fi.po
  41. 536 420
      po/fr.po
  42. 596 559
      po/gl.po
  43. 526 419
      po/hu.po
  44. 597 562
      po/it.po
  45. 534 421
      po/ja.po
  46. 521 418
      po/km.po
  47. 533 420
      po/ko.po
  48. 515 415
      po/ku.po
  49. 521 419
      po/lt.po
  50. 521 418
      po/mr.po
  51. 530 421
      po/nb.po
  52. 521 418
      po/ne.po
  53. 526 419
      po/nl.po
  54. 522 419
      po/nn.po
  55. 526 419
      po/pl.po
  56. 533 420
      po/pt.po
  57. 526 419
      po/pt_BR.po
  58. 526 419
      po/ro.po
  59. 534 420
      po/ru.po
  60. 529 420
      po/sk.po
  61. 545 454
      po/sl.po
  62. 533 420
      po/sv.po
  63. 521 418
      po/th.po
  64. 526 419
      po/tl.po
  65. 524 419
      po/uk.po
  66. 529 420
      po/vi.po
  67. 528 422
      po/zh_CN.po
  68. 527 420
      po/zh_TW.po
  69. 42 3
      test/integration/framework
  70. 47 0
      test/integration/test-bug-407511-fail-invalid-default-release
  71. 183 0
      test/integration/test-bug-632221-cross-dependency-satisfaction
  72. 38 4
      test/libapt/assert.h
  73. 6 0
      test/libapt/getarchitectures_test.cc
  74. 2 2
      test/libapt/getlanguages_test.cc
  75. 6 0
      test/libapt/makefile
  76. 46 0
      test/libapt/strutil_test.cc

+ 2 - 0
apt-pkg/acquire.h

@@ -349,6 +349,8 @@ class pkgAcquire
     */
     */
    bool Setup(pkgAcquireStatus *Progress = NULL, string const &Lock = "");
    bool Setup(pkgAcquireStatus *Progress = NULL, string const &Lock = "");
 
 
+   void SetLog(pkgAcquireStatus *Progress) { Log = Progress; }
+
    /** \brief Construct a new pkgAcquire. */
    /** \brief Construct a new pkgAcquire. */
    pkgAcquire(pkgAcquireStatus *Log) __deprecated;
    pkgAcquire(pkgAcquireStatus *Log) __deprecated;
    pkgAcquire();
    pkgAcquire();

+ 1 - 1
apt-pkg/aptconfiguration.cc

@@ -352,7 +352,7 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache
 
 
 	if (archs.empty() == true ||
 	if (archs.empty() == true ||
 	    std::find(archs.begin(), archs.end(), arch) == archs.end())
 	    std::find(archs.begin(), archs.end(), arch) == archs.end())
-		archs.push_back(arch);
+		archs.insert(archs.begin(), arch);
 
 
 	// erase duplicates and empty strings
 	// erase duplicates and empty strings
 	for (std::vector<string>::reverse_iterator a = archs.rbegin();
 	for (std::vector<string>::reverse_iterator a = archs.rbegin();

+ 3 - 1
apt-pkg/contrib/cdromutl.cc

@@ -258,7 +258,9 @@ string FindMountPointForDevice(const char *devnode)
                if(TokSplitString(' ', buf, out, 10))
                if(TokSplitString(' ', buf, out, 10))
                {
                {
                   fclose(f);
                   fclose(f);
-                  return string(out[1]);
+                  // unescape the \0XXX chars in the path
+                  string mount_point = out[1];
+                  return DeEscapeString(mount_point);
                }
                }
             }
             }
          }
          }

+ 1 - 1
apt-pkg/contrib/configuration.cc

@@ -345,7 +345,7 @@ void Configuration::Set(const char *Name,const string &Value)
 // Configuration::Set - Set an integer value				/*{{{*/
 // Configuration::Set - Set an integer value				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-void Configuration::Set(const char *Name,int const Value)
+void Configuration::Set(const char *Name,int const &Value)
 {
 {
    Item *Itm = Lookup(Name,true);
    Item *Itm = Lookup(Name,true);
    if (Itm == 0)
    if (Itm == 0)

+ 1 - 1
apt-pkg/contrib/configuration.h

@@ -84,7 +84,7 @@ class Configuration
    void CndSet(const char *Name,const string &Value);
    void CndSet(const char *Name,const string &Value);
    void CndSet(const char *Name,const int Value);
    void CndSet(const char *Name,const int Value);
    void Set(const char *Name,const string &Value);
    void Set(const char *Name,const string &Value);
-   void Set(const char *Name,const int Value);
+   void Set(const char *Name,const int &Value);
    
    
    inline bool Exists(const string &Name) const {return Exists(Name.c_str());};
    inline bool Exists(const string &Name) const {return Exists(Name.c_str());};
    bool Exists(const char *Name) const;
    bool Exists(const char *Name) const;

+ 2 - 3
apt-pkg/contrib/sha1.cc

@@ -74,10 +74,9 @@ static void SHA1Transform(uint32_t state[5],uint8_t const buffer[64])
       uint32_t l[16];
       uint32_t l[16];
    }
    }
    CHAR64LONG16;
    CHAR64LONG16;
-   CHAR64LONG16 *block;
+   CHAR64LONG16 workspace, *block;
 
 
-   uint8_t workspace[64];
-   block = (CHAR64LONG16 *)workspace;
+   block = &workspace;
    memcpy(block,buffer,sizeof(workspace));
    memcpy(block,buffer,sizeof(workspace));
 
 
    /* Copy context->state[] to working vars */
    /* Copy context->state[] to working vars */

+ 61 - 0
apt-pkg/contrib/strutl.cc

@@ -1240,7 +1240,68 @@ bool CheckDomainList(const string &Host,const string &List)
    return false;
    return false;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// DeEscapeString - unescape (\0XX and \xXX) from a string      	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string DeEscapeString(const string &input)
+{
+   char tmp[3];
+   string::const_iterator it, escape_start;
+   string output, octal, hex;
+   for (it = input.begin(); it != input.end(); it++) 
+   {
+      // just copy non-escape chars
+      if (*it != '\\')
+      {
+         output += *it;
+         continue;
+      }
 
 
+      // deal with double escape
+      if (*it == '\\' && 
+          (it + 1 < input.end()) &&  it[1] == '\\')
+      {
+         // copy
+         output += *it;
+         // advance iterator one step further
+         it += 1;
+         continue;
+      }
+        
+      // ensure we have a char to read
+      if (it + 1 == input.end())
+         continue;
+
+      // read it
+      it++;
+      switch (*it)
+      {
+         case '0':
+            if (it + 2 <= input.end()) {
+               tmp[0] = it[1];
+               tmp[1] = it[2];
+               tmp[2] = 0;
+               output += (char)strtol(tmp, 0, 8);
+               it += 2;
+            }
+            break;
+         case 'x':
+            if (it + 2 <= input.end()) {
+               tmp[0] = it[1];
+               tmp[1] = it[2];
+               tmp[2] = 0;
+               output += (char)strtol(tmp, 0, 16);
+               it += 2;
+            }
+            break;
+         default:
+            // FIXME: raise exception here?
+            break;
+      }
+   }
+   return output;
+}
+									/*}}}*/
 // URI::CopyFrom - Copy from an object					/*{{{*/
 // URI::CopyFrom - Copy from an object					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This parses the URI into all of its components */
 /* This parses the URI into all of its components */

+ 4 - 0
apt-pkg/contrib/strutl.h

@@ -39,6 +39,10 @@ bool ParseCWord(const char *&String,string &Res);
 string QuoteString(const string &Str,const char *Bad);
 string QuoteString(const string &Str,const char *Bad);
 string DeQuoteString(const string &Str);
 string DeQuoteString(const string &Str);
 string DeQuoteString(string::const_iterator const &begin, string::const_iterator const &end);
 string DeQuoteString(string::const_iterator const &begin, string::const_iterator const &end);
+
+// unescape (\0XX and \xXX) from a string
+string DeEscapeString(const string &input);
+
 string SizeToStr(double Bytes);
 string SizeToStr(double Bytes);
 string TimeToStr(unsigned long Sec);
 string TimeToStr(unsigned long Sec);
 string Base64Encode(const string &Str);
 string Base64Encode(const string &Str);

+ 6 - 3
apt-pkg/deb/deblistparser.cc

@@ -456,7 +456,7 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op)
  *
  *
  * The complete architecture, consisting of <kernel>-<cpu>.
  * The complete architecture, consisting of <kernel>-<cpu>.
  */
  */
-static string CompleteArch(std::string& arch) {
+static string CompleteArch(std::string const &arch) {
     if (arch == "armel")              return "linux-arm";
     if (arch == "armel")              return "linux-arm";
     if (arch == "armhf")              return "linux-arm";
     if (arch == "armhf")              return "linux-arm";
     if (arch == "lpia")               return "linux-i386";
     if (arch == "lpia")               return "linux-i386";
@@ -495,9 +495,13 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
    Package.assign(Start,I - Start);
    Package.assign(Start,I - Start);
 
 
    // We don't want to confuse library users which can't handle MultiArch
    // We don't want to confuse library users which can't handle MultiArch
+   string const arch = _config->Find("APT::Architecture");
    if (StripMultiArch == true) {
    if (StripMultiArch == true) {
       size_t const found = Package.rfind(':');
       size_t const found = Package.rfind(':');
-      if (found != string::npos)
+      if (found != string::npos &&
+	  (strcmp(Package.c_str() + found, ":any") == 0 ||
+	   strcmp(Package.c_str() + found, ":native") == 0 ||
+	   strcmp(Package.c_str() + found + 1, arch.c_str()) == 0))
 	 Package = Package.substr(0,found);
 	 Package = Package.substr(0,found);
    }
    }
 
 
@@ -538,7 +542,6 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
 
 
    if (ParseArchFlags == true)
    if (ParseArchFlags == true)
    {
    {
-      string arch = _config->Find("APT::Architecture");
       string completeArch = CompleteArch(arch);
       string completeArch = CompleteArch(arch);
 
 
       // Parse an architecture
       // Parse an architecture

+ 16 - 2
apt-pkg/policy.cc

@@ -56,8 +56,22 @@ pkgPolicy::pkgPolicy(pkgCache *Owner) : Pins(0), PFPriority(0), Cache(Owner)
    // The config file has a master override.
    // The config file has a master override.
    string DefRel = _config->Find("APT::Default-Release");
    string DefRel = _config->Find("APT::Default-Release");
    if (DefRel.empty() == false)
    if (DefRel.empty() == false)
-      CreatePin(pkgVersionMatch::Release,"",DefRel,990);
-      
+   {
+      bool found = false;
+      // FIXME: make ExpressionMatches static to use it here easily
+      pkgVersionMatch vm("", pkgVersionMatch::None);
+      for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
+      {
+	 if ((F->Archive != 0 && vm.ExpressionMatches(DefRel, F.Archive()) == true) ||
+	     (F->Codename != 0 && vm.ExpressionMatches(DefRel, F.Codename()) == true) ||
+	     (F->Version != 0 && vm.ExpressionMatches(DefRel, F.Version()) == true))
+	    found = true;
+      }
+      if (found == false)
+	 _error->Error(_("The value '%s' is invalid for APT::Default-Release as such a release is not available in the sources"), DefRel.c_str());
+      else
+	 CreatePin(pkgVersionMatch::Release,"",DefRel,990);
+   }
    InitDefaults();
    InitDefaults();
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 203 - 104
cmdline/apt-get.cc

@@ -1393,6 +1393,14 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache,
 	 return AllowFail;
 	 return AllowFail;
    }
    }
 
 
+   if (_config->FindB("Debug::BuildDeps",false) == true)
+   {
+      if (Remove == true)
+	 cout << "  Trying to remove " << Pkg << endl;
+      else
+	 cout << "  Trying to install " << Pkg << endl;
+   }
+
    if (Remove == true)
    if (Remove == true)
    {
    {
       TryToRemove RemoveAction(Cache, &Fix);
       TryToRemove RemoveAction(Cache, &Fix);
@@ -2280,7 +2288,7 @@ bool DoDownload(CommandLine &CmdL)
 
 
    pkgAcquire Fetcher;
    pkgAcquire Fetcher;
    AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0));
    AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0));
-   if (_config->FindB("APT::Get::Print-URIs") == true)
+   if (_config->FindB("APT::Get::Print-URIs") == false)
       Fetcher.Setup(&Stat);
       Fetcher.Setup(&Stat);
 
 
    pkgRecords Recs(Cache);
    pkgRecords Recs(Cache);
@@ -2375,8 +2383,7 @@ bool DoSource(CommandLine &CmdL)
    // Create the download object
    // Create the download object
    AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));   
    AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));   
    pkgAcquire Fetcher;
    pkgAcquire Fetcher;
-   if (Fetcher.Setup(&Stat) == false)
-      return false;
+   Fetcher.SetLog(&Stat);
 
 
    DscFile *Dsc = new DscFile[CmdL.FileSize()];
    DscFile *Dsc = new DscFile[CmdL.FileSize()];
    
    
@@ -2622,12 +2629,17 @@ bool DoSource(CommandLine &CmdL)
 	 // Try to compile it with dpkg-buildpackage
 	 // Try to compile it with dpkg-buildpackage
 	 if (_config->FindB("APT::Get::Compile",false) == true)
 	 if (_config->FindB("APT::Get::Compile",false) == true)
 	 {
 	 {
+	    string buildopts = _config->Find("APT::Get::Host-Architecture");
+	    if (buildopts.empty() == false)
+	       buildopts = "-a " + buildopts + " ";
+	    buildopts.append(_config->Find("DPkg::Build-Options","-b -uc"));
+
 	    // Call dpkg-buildpackage
 	    // Call dpkg-buildpackage
 	    char S[500];
 	    char S[500];
 	    snprintf(S,sizeof(S),"cd %s && %s %s",
 	    snprintf(S,sizeof(S),"cd %s && %s %s",
 		     Dir.c_str(),
 		     Dir.c_str(),
 		     _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
 		     _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
-		     _config->Find("DPkg::Build-Options","-b -uc").c_str());
+		     buildopts.c_str());
 	    
 	    
 	    if (system(S) != 0)
 	    if (system(S) != 0)
 	    {
 	    {
@@ -2689,8 +2701,19 @@ bool DoBuildDep(CommandLine &CmdL)
    if (Fetcher.Setup(&Stat) == false)
    if (Fetcher.Setup(&Stat) == false)
       return false;
       return false;
 
 
+   bool StripMultiArch;
+   string hostArch = _config->Find("APT::Get::Host-Architecture");
+   if (hostArch.empty() == false)
+   {
+      std::vector<std::string> archs = APT::Configuration::getArchitectures();
+      if (std::find(archs.begin(), archs.end(), hostArch) == archs.end())
+	 return _error->Error(_("No architecture information available for %s. See apt.conf(5) APT::Architectures for setup"), hostArch.c_str());
+      StripMultiArch = false;
+   }
+   else
+      StripMultiArch = true;
+
    unsigned J = 0;
    unsigned J = 0;
-   bool const StripMultiArch = APT::Configuration::getArchitectures().size() <= 1;
    for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
    for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
    {
    {
       string Src;
       string Src;
@@ -2724,7 +2747,7 @@ bool DoBuildDep(CommandLine &CmdL)
 	 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
 	 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
 	 continue;
 	 continue;
       }
       }
-      
+
       // Install the requested packages
       // Install the requested packages
       vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
       vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
       pkgProblemResolver Fix(Cache);
       pkgProblemResolver Fix(Cache);
@@ -2735,6 +2758,16 @@ bool DoBuildDep(CommandLine &CmdL)
 
 
          if (skipAlternatives == true)
          if (skipAlternatives == true)
          {
          {
+            /*
+             * if there are alternatives, we've already picked one, so skip
+             * the rest
+             *
+             * TODO: this means that if there's a build-dep on A|B and B is
+             * installed, we'll still try to install A; more importantly,
+             * if A is currently broken, we cannot go back and try B. To fix 
+             * this would require we do a Resolve cycle for each package we 
+             * add to the install list. Ugh
+             */
             if (!hasAlternatives)
             if (!hasAlternatives)
                skipAlternatives = false; // end of or group
                skipAlternatives = false; // end of or group
             continue;
             continue;
@@ -2743,27 +2776,117 @@ bool DoBuildDep(CommandLine &CmdL)
          if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
          if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
 	     (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
 	     (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
          {
          {
-            pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
+            pkgCache::GrpIterator Grp = Cache->FindGrp((*D).Package);
             // Build-conflicts on unknown packages are silently ignored
             // Build-conflicts on unknown packages are silently ignored
-            if (Pkg.end() == true)
+            if (Grp.end() == true)
                continue;
                continue;
 
 
-            pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
-
-            /* 
-             * Remove if we have an installed version that satisfies the 
-             * version criteria
-             */
-            if (IV.end() == false && 
-                Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
-               TryToInstallBuildDep(Pkg,Cache,Fix,true,false);
+	    for (pkgCache::PkgIterator Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg))
+	    {
+	       pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
+	       /*
+		* Remove if we have an installed version that satisfies the
+		* version criteria
+		*/
+	       if (IV.end() == false &&
+		   Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
+		  TryToInstallBuildDep(Pkg,Cache,Fix,true,false);
+	    }
          }
          }
 	 else // BuildDep || BuildDepIndep
 	 else // BuildDep || BuildDepIndep
          {
          {
-	    pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
             if (_config->FindB("Debug::BuildDeps",false) == true)
             if (_config->FindB("Debug::BuildDeps",false) == true)
                  cout << "Looking for " << (*D).Package << "...\n";
                  cout << "Looking for " << (*D).Package << "...\n";
 
 
+	    pkgCache::PkgIterator Pkg;
+
+	    // Cross-Building?
+	    if (StripMultiArch == false)
+	    {
+	       size_t const colon = D->Package.find(":");
+	       if (colon != string::npos &&
+		   (strcmp(D->Package.c_str() + colon, ":any") == 0 || strcmp(D->Package.c_str() + colon, ":native") == 0))
+		  Pkg = Cache->FindPkg(D->Package.substr(0,colon));
+	       else
+		  Pkg = Cache->FindPkg(D->Package);
+
+	       // We need to decide if host or build arch, so find a version we can look at
+	       pkgCache::VerIterator Ver;
+
+	       // a bad version either is invalid or doesn't satify dependency
+	       #define BADVER(Ver) Ver.end() == true || \
+				   (Ver.end() == false && D->Version.empty() == false && \
+				    Cache->VS().CheckDep(Ver.VerStr(),D->Op,D->Version.c_str()) == false)
+
+	       if (Pkg.end() == false)
+	       {
+		  Ver = (*Cache)[Pkg].InstVerIter(*Cache);
+		  if (BADVER(Ver))
+		     Ver = (*Cache)[Pkg].CandidateVerIter(*Cache);
+	       }
+	       if (BADVER(Ver))
+	       {
+		  pkgCache::PkgIterator HostPkg = Cache->FindPkg(D->Package, hostArch);
+		  if (HostPkg.end() == false)
+		  {
+		     Ver = (*Cache)[HostPkg].InstVerIter(*Cache);
+		     if (BADVER(Ver))
+		        Ver = (*Cache)[HostPkg].CandidateVerIter(*Cache);
+		  }
+	       }
+	       if ((BADVER(Ver)) == false)
+	       {
+		  string forbidden;
+		  if (Ver->MultiArch == pkgCache::Version::None || Ver->MultiArch == pkgCache::Version::All);
+		  else if (Ver->MultiArch == pkgCache::Version::Same)
+		  {
+		     if (colon != string::npos)
+			Pkg = Ver.ParentPkg().Group().FindPkg(hostArch);
+		     else if (strcmp(D->Package.c_str() + colon, ":any") == 0)
+			forbidden = "Multi-Arch: same";
+		     // :native gets the buildArch
+		  }
+		  else if (Ver->MultiArch == pkgCache::Version::Foreign || Ver->MultiArch == pkgCache::Version::AllForeign)
+		  {
+		     if (colon != string::npos)
+			forbidden = "Multi-Arch: foreign";
+		  }
+		  else if (Ver->MultiArch == pkgCache::Version::Allowed || Ver->MultiArch == pkgCache::Version::AllAllowed)
+		  {
+		     if (colon == string::npos)
+			Pkg = Ver.ParentPkg().Group().FindPkg(hostArch);
+		     else if (strcmp(D->Package.c_str() + colon, ":any") == 0)
+		     {
+			// prefer any installed over preferred non-installed architectures
+			pkgCache::GrpIterator Grp = Ver.ParentPkg().Group();
+			// we don't check for version here as we are better of with upgrading than remove and install
+			for (Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg))
+			   if (Pkg.CurrentVer().end() == false)
+			      break;
+			if (Pkg.end() == true)
+			   Pkg = Grp.FindPreferredPkg(true);
+		     }
+		     // native gets buildArch
+		  }
+		  if (forbidden.empty() == false)
+		  {
+		     if (_config->FindB("Debug::BuildDeps",false) == true)
+			cout << " :any is not allowed from M-A: same package " << (*D).Package << endl;
+		     if (hasAlternatives)
+			continue;
+		     return _error->Error(_("%s dependency for %s can't be satisfied "
+					    "because %s is not allowed on '%s' packages"),
+					  Last->BuildDepType(D->Type), Src.c_str(),
+					  D->Package.c_str(), "Multi-Arch: same");
+		  }
+	       }
+	       else if (_config->FindB("Debug::BuildDeps",false) == true)
+		  cout << " No multiarch info as we have no satisfying installed nor candidate for " << D->Package << " on build or host arch" << endl;
+	       #undef BADVER
+	    }
+	    else
+	       Pkg = Cache->FindPkg(D->Package);
+
 	    if (Pkg.end() == true)
 	    if (Pkg.end() == true)
             {
             {
                if (_config->FindB("Debug::BuildDeps",false) == true)
                if (_config->FindB("Debug::BuildDeps",false) == true)
@@ -2778,99 +2901,74 @@ bool DoBuildDep(CommandLine &CmdL)
                                     (*D).Package.c_str());
                                     (*D).Package.c_str());
             }
             }
 
 
-            /*
-             * if there are alternatives, we've already picked one, so skip
-             * the rest
-             *
-             * TODO: this means that if there's a build-dep on A|B and B is
-             * installed, we'll still try to install A; more importantly,
-             * if A is currently broken, we cannot go back and try B. To fix 
-             * this would require we do a Resolve cycle for each package we 
-             * add to the install list. Ugh
-             */
-                       
-	    /* 
-	     * If this is a virtual package, we need to check the list of
-	     * packages that provide it and see if any of those are
-	     * installed
-	     */
-            pkgCache::PrvIterator Prv = Pkg.ProvidesList();
-            for (; Prv.end() != true; Prv++)
-	    {
-               if (_config->FindB("Debug::BuildDeps",false) == true)
-                    cout << "  Checking provider " << Prv.OwnerPkg().FullName() << endl;
-
-	       if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
-	          break;
-            }
-            
-            // Get installed version and version we are going to install
 	    pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
 	    pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
+	    if (IV.end() == false)
+	    {
+	       if (_config->FindB("Debug::BuildDeps",false) == true)
+		  cout << "  Is installed\n";
 
 
-            if ((*D).Version[0] != '\0') {
-                 // Versioned dependency
-
-                 pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
-
-                 for (; CV.end() != true; CV++)
-                 {
-                      if (Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
-                           break;
-                 }
-                 if (CV.end() == true)
-		 {
-		   if (hasAlternatives)
-		   {
-		      continue;
-		   }
-		   else
-		   {
-                      return _error->Error(_("%s dependency for %s cannot be satisfied "
-                                             "because no available versions of package %s "
-                                             "can satisfy version requirements"),
-                                           Last->BuildDepType((*D).Type),Src.c_str(),
-                                           (*D).Package.c_str());
-		   }
-		 }
-            }
-            else
-            {
-               // Only consider virtual packages if there is no versioned dependency
-               if (Prv.end() == false)
-               {
-                  if (_config->FindB("Debug::BuildDeps",false) == true)
-                     cout << "  Is provided by installed package " << Prv.OwnerPkg().FullName() << endl;
-                  skipAlternatives = hasAlternatives;
-                  continue;
-               }
-            }
+	       if (D->Version.empty() == true ||
+		   Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
+	       {
+		  skipAlternatives = hasAlternatives;
+		  continue;
+	       }
 
 
-            if (IV.end() == false)
-            {
-               if (_config->FindB("Debug::BuildDeps",false) == true)
-                  cout << "  Is installed\n";
+	       if (_config->FindB("Debug::BuildDeps",false) == true)
+		  cout << "    ...but the installed version doesn't meet the version requirement\n";
 
 
-               if (Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
-               {
-                  skipAlternatives = hasAlternatives;
-                  continue;
-               }
+	       if (((*D).Op & pkgCache::Dep::LessEq) == pkgCache::Dep::LessEq)
+		  return _error->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"),
+					Last->BuildDepType((*D).Type), Src.c_str(), Pkg.FullName(true).c_str());
+	    }
 
 
-               if (_config->FindB("Debug::BuildDeps",false) == true)
-                  cout << "    ...but the installed version doesn't meet the version requirement\n";
-
-               if (((*D).Op & pkgCache::Dep::LessEq) == pkgCache::Dep::LessEq)
-               {
-                  return _error->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"),
-                                       Last->BuildDepType((*D).Type),
-                                       Src.c_str(),
-                                       Pkg.FullName(true).c_str());
-               }
-            }
+	    // Only consider virtual packages if there is no versioned dependency
+	    if ((*D).Version.empty() == true)
+	    {
+	       /*
+		* If this is a virtual package, we need to check the list of
+		* packages that provide it and see if any of those are
+		* installed
+		*/
+	       pkgCache::PrvIterator Prv = Pkg.ProvidesList();
+	       for (; Prv.end() != true; Prv++)
+	       {
+		  if (_config->FindB("Debug::BuildDeps",false) == true)
+		     cout << "  Checking provider " << Prv.OwnerPkg().FullName() << endl;
 
 
+		  if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
+		     break;
+	       }
 
 
-            if (_config->FindB("Debug::BuildDeps",false) == true)
-               cout << "  Trying to install " << (*D).Package << endl;
+	       if (Prv.end() == false)
+	       {
+		  if (_config->FindB("Debug::BuildDeps",false) == true)
+		     cout << "  Is provided by installed package " << Prv.OwnerPkg().FullName() << endl;
+		  skipAlternatives = hasAlternatives;
+		  continue;
+	       }
+	    }
+	    else // versioned dependency
+	    {
+	       pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
+	       if (CV.end() == true ||
+		   Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == false)
+	       {
+		  if (hasAlternatives)
+		     continue;
+		  else if (CV.end() == false)
+		     return _error->Error(_("%s dependency for %s cannot be satisfied "
+					    "because candidate version of package %s "
+					    "can't satisfy version requirements"),
+					  Last->BuildDepType(D->Type), Src.c_str(),
+					  D->Package.c_str());
+		  else
+		     return _error->Error(_("%s dependency for %s cannot be satisfied "
+					    "because package %s has no candidate version"),
+					  Last->BuildDepType(D->Type), Src.c_str(),
+					  D->Package.c_str());
+	       }
+	    }
 
 
             if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true)
             if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true)
             {
             {
@@ -3257,6 +3355,7 @@ int main(int argc,const char *argv[])					/*{{{*/
       {'m',"ignore-missing","APT::Get::Fix-Missing",0},
       {'m',"ignore-missing","APT::Get::Fix-Missing",0},
       {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
       {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
       {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
       {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
+      {'a',"host-architecture","APT::Get::Host-Architecture",CommandLine::HasArg},
       {0,"download","APT::Get::Download",0},
       {0,"download","APT::Get::Download",0},
       {0,"fix-missing","APT::Get::Fix-Missing",0},
       {0,"fix-missing","APT::Get::Fix-Missing",0},
       {0,"ignore-hold","APT::Ignore-Hold",0},      
       {0,"ignore-hold","APT::Ignore-Hold",0},      

+ 4 - 1
cmdline/apt-key

@@ -5,9 +5,12 @@ unset GREP_OPTIONS
 
 
 # We don't use a secret keyring, of course, but gpg panics and
 # We don't use a secret keyring, of course, but gpg panics and
 # implodes if there isn't one available
 # implodes if there isn't one available
-GPG_CMD='gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring /etc/apt/secring.gpg'
+SECRETKEYRING="$(mktemp)"
+trap "rm -f '${SECRETKEYRING}'" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
+GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring ${SECRETKEYRING}"
 
 
 if [ "$(id -u)" -eq 0 ]; then
 if [ "$(id -u)" -eq 0 ]; then
+	# we could use a tmpfile here too, but creation of this tends to be time-consuming
 	GPG_CMD="$GPG_CMD --trustdb-name /etc/apt/trustdb.gpg"
 	GPG_CMD="$GPG_CMD --trustdb-name /etc/apt/trustdb.gpg"
 fi
 fi
 
 

+ 5 - 0
debian/apt.postinst

@@ -15,6 +15,11 @@ set -e
 
 
 case "$1" in
 case "$1" in
     configure)
     configure)
+	SECRING='/etc/apt/secring.gpg'
+	# test if secring is an empty normal file
+	if test -f $SECRING -a ! -s $SECRING; then
+		rm -f $SECRING
+	fi
 	apt-key update
 	apt-key update
     ;;
     ;;
 
 

+ 44 - 2
debian/changelog

@@ -1,11 +1,15 @@
 apt (0.8.16~exp4) UNRELEASED; urgency=low
 apt (0.8.16~exp4) UNRELEASED; urgency=low
 
 
+  [ Julian Andres Klode ]
   * apt-pkg/pkgcache.h:
   * apt-pkg/pkgcache.h:
     - [ABI break] Add pkgCache::Header::CacheFileSize, storing the cache size
     - [ABI break] Add pkgCache::Header::CacheFileSize, storing the cache size
   * apt-pkg/pkgcachegen.cc:
   * apt-pkg/pkgcachegen.cc:
     - Write the file size to the cache
     - Write the file size to the cache
   * apt-pkg/pkgcache.cc:
   * apt-pkg/pkgcache.cc:
     - Check that cache is at least CacheFileSize bytes large (LP: #16467)
     - Check that cache is at least CacheFileSize bytes large (LP: #16467)
+  
+  [ Michael Vogt ]
+  * merged latest fixes from debian-sid
 
 
  -- Julian Andres Klode <jak@debian.org>  Wed, 20 Jul 2011 16:23:55 +0200
  -- Julian Andres Klode <jak@debian.org>  Wed, 20 Jul 2011 16:23:55 +0200
 
 
@@ -73,7 +77,25 @@ apt (0.8.16~exp1) experimental; urgency=low
 
 
  -- Michael Vogt <mvo@debian.org>  Wed, 29 Jun 2011 12:40:31 +0200
  -- Michael Vogt <mvo@debian.org>  Wed, 29 Jun 2011 12:40:31 +0200
 
 
-apt (0.8.15.3) UNRELEASED; urgency=low
+apt (0.8.15.4) unstable; urgency=low
+
+  [ David Miller ]
+  * apt-pkg/contrib/sha1.cc:
+    - fix illegally casts of on-stack buffer to a type requiring more
+      alignment than it has resulting in segfaults on sparc (Closes: #634696)
+
+  [ Michael Vogt ]
+  * apt-pkg/contrib/cdromutl.cc:
+    - fix escape problem when looking for the mounted devices
+  * apt-pkg/contrib/strutl.{h,cc}, test/libapt/strutil_test.cc:
+    - add new DeEscapeString() similar to DeQuoteString but
+      unescape character escapes like \0XX and \xXX (plus added
+      test)
+  * refresh po/*
+  
+ -- Michael Vogt <mvo@debian.org>  Tue, 26 Jul 2011 12:12:27 +0200
+
+apt (0.8.15.3) unstable; urgency=low
 
 
   [ Michael Vogt ]
   [ Michael Vogt ]
   * apt-pkg/acquire-item.cc:
   * apt-pkg/acquire-item.cc:
@@ -81,6 +103,8 @@ apt (0.8.15.3) UNRELEASED; urgency=low
   * apt-pkg/algorithms.cc:
   * apt-pkg/algorithms.cc:
     - Hold back packages that would enter "policy-broken" state on upgrade
     - Hold back packages that would enter "policy-broken" state on upgrade
       when doing a "apt-get upgrade"
       when doing a "apt-get upgrade"
+  * cmdline/apt-get.cc:
+    - fix missing download progress in apt-get download
 
 
   [ David Kalnischkies ]
   [ David Kalnischkies ]
   * apt-pkg/pkgcachegen.cc:
   * apt-pkg/pkgcachegen.cc:
@@ -92,12 +116,30 @@ apt (0.8.15.3) UNRELEASED; urgency=low
     - document APT::Architectures list (Closes: #612102)
     - document APT::Architectures list (Closes: #612102)
   * cmdline/apt-get.cc:
   * cmdline/apt-get.cc:
     - restore all important dependencies for garbage packages (LP: #806274)
     - restore all important dependencies for garbage packages (LP: #806274)
+    - do not require unused partial dirs in 'source' (Closes: #633510)
+    - buildconflicts effect all architectures
+    - implement MultiarchCross for build-dep and source (Closes: #632221)
   * apt-pkg/init.cc:
   * apt-pkg/init.cc:
     - use CndSet in pkgInitConfig (Closes: #629617)
     - use CndSet in pkgInitConfig (Closes: #629617)
   * apt-pkg/depcache.cc:
   * apt-pkg/depcache.cc:
     - change default of APT::AutoRemove::SuggestsImportant to true
     - change default of APT::AutoRemove::SuggestsImportant to true
+  * cmdline/apt-key:
+    - use a tmpfile instead of /etc/apt/secring.gpg (Closes: #632596)
+  * debian/apt.postinst:
+    - remove /etc/apt/secring.gpg if it is an empty file
+  * doc/apt-cache.8.xml:
+    - apply madison typofix from John Feuerstein, thanks! (Closes: #633455)
+  * apt-pkg/policy.cc:
+    - emit an error on unknown APT::Default-Release value (Closes: #407511)
+  * apt-pkg/aptconfiguration.cc:
+    - ensure that native architecture is if not specified otherwise the
+      first architecture in the Architectures vector
+  * apt-pkg/deb/deblistparser.cc:
+    - Strip only :any and :native if MultiArch should be stripped as it is
+      save to ignore them in non-MultiArch contexts but if the dependency
+      is a specific architecture (and not the native) do not strip
 
 
- -- David Kalnischkies <kalnischkies@gmail.com>  Fri, 15 Jul 2011 09:29:37 +0200
+ -- Michael Vogt <mvo@debian.org>  Mon, 25 Jul 2011 15:04:43 +0200
 
 
 apt (0.8.15.2) unstable; urgency=high
 apt (0.8.15.2) unstable; urgency=high
 
 

+ 1 - 1
doc/apt-cache.8.xml

@@ -263,7 +263,7 @@ Reverse Provides:
      about the priority selection of the named package.</para></listitem>
      about the priority selection of the named package.</para></listitem>
      </varlistentry>
      </varlistentry>
 
 
-     <varlistentry><term>madison <replaceable>/[ pkg(s) ]</replaceable></term>
+     <varlistentry><term>madison <replaceable>[ pkg(s) ]</replaceable></term>
      <listitem><para><literal>apt-cache</literal>'s <literal>madison</literal> command attempts to mimic
      <listitem><para><literal>apt-cache</literal>'s <literal>madison</literal> command attempts to mimic
      the output format and a subset of the functionality of the Debian
      the output format and a subset of the functionality of the Debian
      archive management tool, <literal>madison</literal>.  It displays
      archive management tool, <literal>madison</literal>.  It displays

+ 24 - 3
doc/apt-get.8.xml

@@ -54,6 +54,13 @@
 			<replaceable>target_release</replaceable>
 			<replaceable>target_release</replaceable>
 		</arg>
 		</arg>
       </arg>
       </arg>
+      <arg>
+		<option>-a=</option>
+		<arg choice='plain'>
+			<replaceable>default_architecture</replaceable>
+		</arg>
+      </arg>
+
 
 
       <group choice="req">
       <group choice="req">
          <arg choice='plain'>update</arg>
          <arg choice='plain'>update</arg>
@@ -254,8 +261,10 @@
 
 
      <para>If the <option>--compile</option> option is specified
      <para>If the <option>--compile</option> option is specified
      then the package will be compiled to a binary .deb using
      then the package will be compiled to a binary .deb using
-     <command>dpkg-buildpackage</command>, if <option>--download-only</option>
-     is specified then the source package will not be unpacked.</para>
+     <command>dpkg-buildpackage</command> for the architecture as
+     defined by the <command>--host-architecture</command> option.
+     If <option>--download-only</option> is specified then the source package
+     will not be unpacked.</para>
 
 
      <para>A specific source version can be retrieved by postfixing the source name
      <para>A specific source version can be retrieved by postfixing the source name
      with an equals and then the version to fetch, similar to the mechanism
      with an equals and then the version to fetch, similar to the mechanism
@@ -270,7 +279,9 @@
 
 
      <varlistentry><term>build-dep</term>
      <varlistentry><term>build-dep</term>
      <listitem><para><literal>build-dep</literal> causes apt-get to install/remove packages in an 
      <listitem><para><literal>build-dep</literal> causes apt-get to install/remove packages in an 
-     attempt to satisfy the build dependencies for a source package.</para></listitem>
+     attempt to satisfy the build dependencies for a source package. By default the dependencies are
+     satisfied to build the package nativly. If desired a host-architecture can be specified
+     with the <option>--host-architecture</option> option instead.</para></listitem>
      </varlistentry>
      </varlistentry>
 
 
      <varlistentry><term>check</term>
      <varlistentry><term>check</term>
@@ -438,6 +449,16 @@
      Configuration Item: <literal>APT::Get::Show-Versions</literal>.</para></listitem>
      Configuration Item: <literal>APT::Get::Show-Versions</literal>.</para></listitem>
      </varlistentry>
      </varlistentry>
 
 
+     <varlistentry><term><option>-a</option></term>
+                   <term><option>--host-architecture</option></term>
+     <listitem><para>This option controls the architecture packages are built for
+     by <command>apt-get source --compile</command> and how cross-builddependencies
+     are satisfied. By default is not set which means that the host architecture
+     is the same as the build architecture (which is defined by <literal>APT::Architecture</literal>)
+     Configuration Item: <literal>APT::Get::Host-Architecture</literal>
+     </para></listitem>
+     </varlistentry>
+
      <varlistentry><term><option>-b</option></term><term><option>--compile</option></term>
      <varlistentry><term><option>-b</option></term><term><option>--compile</option></term>
                    <term><option>--build</option></term>
                    <term><option>--build</option></term>
      <listitem><para>Compile source packages after downloading them.
      <listitem><para>Compile source packages after downloading them.

+ 1 - 0
doc/examples/configure-index

@@ -32,6 +32,7 @@ APT
   // Options for apt-get
   // Options for apt-get
   Get 
   Get 
   {
   {
+     Host-Architecture "armel";
      Arch-Only "false";
      Arch-Only "false";
      AllowUnauthenticated "false";
      AllowUnauthenticated "false";
      AutomaticRemove "false";       
      AutomaticRemove "false";       

+ 1 - 1
doc/po/apt-doc.pot

@@ -928,7 +928,7 @@ msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #: apt-cache.8.xml:266
 #: apt-cache.8.xml:266
-msgid "madison <replaceable>/[ pkg(s) ]</replaceable>"
+msgid "madison <replaceable>[ pkg(s) ]</replaceable>"
 msgstr ""
 msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>

+ 2 - 2
doc/po/de.po

@@ -1230,8 +1230,8 @@ msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #: apt-cache.8.xml:266
 #: apt-cache.8.xml:266
-msgid "madison <replaceable>/[ pkg(s) ]</replaceable>"
-msgstr "madison <replaceable>/[ Paket(e) ]</replaceable>"
+msgid "madison <replaceable>[ pkg(s) ]</replaceable>"
+msgstr "madison <replaceable>[ Paket(e) ]</replaceable>"
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #: apt-cache.8.xml:267
 #: apt-cache.8.xml:267

+ 1 - 1
doc/po/es.po

@@ -1303,7 +1303,7 @@ msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #: apt-cache.8.xml:266
 #: apt-cache.8.xml:266
-msgid "madison <replaceable>/[ pkg(s) ]</replaceable>"
+msgid "madison <replaceable>[ pkg(s) ]</replaceable>"
 msgstr "madison <replaceable>[ paquete(s) ]</replaceable>"
 msgstr "madison <replaceable>[ paquete(s) ]</replaceable>"
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>

+ 1 - 1
doc/po/fr.po

@@ -1225,7 +1225,7 @@ msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #: apt-cache.8.xml:266
 #: apt-cache.8.xml:266
-msgid "madison <replaceable>/[ pkg(s) ]</replaceable>"
+msgid "madison <replaceable>[ pkg(s) ]</replaceable>"
 msgstr "madison <replaceable>[ paquet(s) ]</replaceable>"
 msgstr "madison <replaceable>[ paquet(s) ]</replaceable>"
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>

+ 1 - 1
doc/po/it.po

@@ -893,7 +893,7 @@ msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #: apt-cache.8.xml:266
 #: apt-cache.8.xml:266
-msgid "madison <replaceable>/[ pkg(s) ]</replaceable>"
+msgid "madison <replaceable>[ pkg(s) ]</replaceable>"
 msgstr ""
 msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>

+ 2 - 2
doc/po/ja.po

@@ -1304,8 +1304,8 @@ msgstr ""
 # type: Content of: <refentry><refsect1><refsect2><para><programlisting>
 # type: Content of: <refentry><refsect1><refsect2><para><programlisting>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #: apt-cache.8.xml:266
 #: apt-cache.8.xml:266
-msgid "madison <replaceable>/[ pkg(s) ]</replaceable>"
-msgstr "madison <replaceable>/[ pkg(s) ]</replaceable>"
+msgid "madison <replaceable>[ pkg(s) ]</replaceable>"
+msgstr "madison <replaceable>[ pkg(s) ]</replaceable>"
 
 
 # type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 # type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>

+ 2 - 2
doc/po/pl.po

@@ -1311,8 +1311,8 @@ msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #: apt-cache.8.xml:266
 #: apt-cache.8.xml:266
-msgid "madison <replaceable>/[ pkg(s) ]</replaceable>"
-msgstr "madison <replaceable>/[ pakiet(y) ]</replaceable>"
+msgid "madison <replaceable>[ pkg(s) ]</replaceable>"
+msgstr "madison <replaceable>[ pakiet(y) ]</replaceable>"
 
 
 #
 #
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>

+ 2 - 2
doc/po/pt.po

@@ -1255,8 +1255,8 @@ msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #: apt-cache.8.xml:266
 #: apt-cache.8.xml:266
-msgid "madison <replaceable>/[ pkg(s) ]</replaceable>"
-msgstr "madison <replaceable>/[ pacote(s) ]</replaceable>"
+msgid "madison <replaceable>[ pkg(s) ]</replaceable>"
+msgstr "madison <replaceable>[ pacote(s) ]</replaceable>"
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #: apt-cache.8.xml:267
 #: apt-cache.8.xml:267

+ 4 - 1
doc/po/pt_BR.po

@@ -943,8 +943,11 @@ msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><term>
 #: apt-cache.8.xml:266
 #: apt-cache.8.xml:266
-msgid "madison <replaceable>/[ pkg(s) ]</replaceable>"
+#, fuzzy
+msgid "madison <replaceable>[ pkg(s) ]</replaceable>"
 msgstr ""
 msgstr ""
+"<programlisting>\n"
+"apt-get install <replaceable>pacote</replaceable>/testing\n"
 
 
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #. type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
 #: apt-cache.8.xml:267
 #: apt-cache.8.xml:267

Разница между файлами не показана из-за своего большого размера
+ 519 - 416
po/ar.po


Разница между файлами не показана из-за своего большого размера
+ 533 - 420
po/ast.po


Разница между файлами не показана из-за своего большого размера
+ 535 - 421
po/bg.po


Разница между файлами не показана из-за своего большого размера
+ 515 - 415
po/bs.po


Разница между файлами не показана из-за своего большого размера
+ 620 - 631
po/ca.po


Разница между файлами не показана из-за своего большого размера
+ 529 - 420
po/cs.po


Разница между файлами не показана из-за своего большого размера
+ 527 - 420
po/cy.po


Разница между файлами не показана из-за своего большого размера
+ 531 - 420
po/da.po


Разница между файлами не показана из-за своего большого размера
+ 533 - 420
po/de.po


Разница между файлами не показана из-за своего большого размера
+ 523 - 420
po/dz.po


Разница между файлами не показана из-за своего большого размера
+ 524 - 419
po/el.po


Разница между файлами не показана из-за своего большого размера
+ 534 - 420
po/es.po


Разница между файлами не показана из-за своего большого размера
+ 524 - 419
po/eu.po


Разница между файлами не показана из-за своего большого размера
+ 524 - 419
po/fi.po


Разница между файлами не показана из-за своего большого размера
+ 536 - 420
po/fr.po


Разница между файлами не показана из-за своего большого размера
+ 596 - 559
po/gl.po


Разница между файлами не показана из-за своего большого размера
+ 526 - 419
po/hu.po


Разница между файлами не показана из-за своего большого размера
+ 597 - 562
po/it.po


Разница между файлами не показана из-за своего большого размера
+ 534 - 421
po/ja.po


Разница между файлами не показана из-за своего большого размера
+ 521 - 418
po/km.po


Разница между файлами не показана из-за своего большого размера
+ 533 - 420
po/ko.po


Разница между файлами не показана из-за своего большого размера
+ 515 - 415
po/ku.po


Разница между файлами не показана из-за своего большого размера
+ 521 - 419
po/lt.po


Разница между файлами не показана из-за своего большого размера
+ 521 - 418
po/mr.po


Разница между файлами не показана из-за своего большого размера
+ 530 - 421
po/nb.po


Разница между файлами не показана из-за своего большого размера
+ 521 - 418
po/ne.po


Разница между файлами не показана из-за своего большого размера
+ 526 - 419
po/nl.po


Разница между файлами не показана из-за своего большого размера
+ 522 - 419
po/nn.po


Разница между файлами не показана из-за своего большого размера
+ 526 - 419
po/pl.po


Разница между файлами не показана из-за своего большого размера
+ 533 - 420
po/pt.po


Разница между файлами не показана из-за своего большого размера
+ 526 - 419
po/pt_BR.po


Разница между файлами не показана из-за своего большого размера
+ 526 - 419
po/ro.po


Разница между файлами не показана из-за своего большого размера
+ 534 - 420
po/ru.po


Разница между файлами не показана из-за своего большого размера
+ 529 - 420
po/sk.po


Разница между файлами не показана из-за своего большого размера
+ 545 - 454
po/sl.po


Разница между файлами не показана из-за своего большого размера
+ 533 - 420
po/sv.po


Разница между файлами не показана из-за своего большого размера
+ 521 - 418
po/th.po


Разница между файлами не показана из-за своего большого размера
+ 526 - 419
po/tl.po


Разница между файлами не показана из-за своего большого размера
+ 524 - 419
po/uk.po


Разница между файлами не показана из-за своего большого размера
+ 529 - 420
po/vi.po


Разница между файлами не показана из-за своего большого размера
+ 528 - 422
po/zh_CN.po


Разница между файлами не показана из-за своего большого размера
+ 527 - 420
po/zh_TW.po


+ 42 - 3
test/integration/framework

@@ -151,6 +151,7 @@ setupenvironment() {
 
 
 configarchitecture() {
 configarchitecture() {
 	local CONFFILE=rootdir/etc/apt/apt.conf.d/01multiarch.conf
 	local CONFFILE=rootdir/etc/apt/apt.conf.d/01multiarch.conf
+	rm -f $CONFFILE
 	echo "APT::Architecture \"$1\";" > $CONFFILE
 	echo "APT::Architecture \"$1\";" > $CONFFILE
 	shift
 	shift
 	while [ -n "$1" ]; do
 	while [ -n "$1" ]; do
@@ -429,6 +430,27 @@ Filename: pool/main/${NAME}/${NAME}_${VERSION}_${arch}.deb" >> $FILE
 	done
 	done
 }
 }
 
 
+insertsource() {
+	local RELEASE="$1"
+	local NAME="$2"
+	local ARCH="$3"
+	local VERSION="$4"
+	local DEPENDENCIES="$5"
+	local ARCHS=""
+	local SPATH="aptarchive/dists/${RELEASE}/main/source"
+	mkdir -p $SPATH
+	local FILE="${SPATH}/Sources"
+	echo "Package: $NAME
+Binary: $NAME
+Version: $VERSION
+Maintainer: Joe Sixpack <joe@example.org>
+Architecture: $ARCH" >> $FILE
+	test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE
+	echo "Files:
+ d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.dsc
+ d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.tar.gz" >> $FILE
+}
+
 insertinstalledpackage() {
 insertinstalledpackage() {
 	local NAME="$1"
 	local NAME="$1"
 	local ARCH="$2"
 	local ARCH="$2"
@@ -481,6 +503,10 @@ buildaptarchivefromfiles() {
 	generatereleasefiles
 	generatereleasefiles
 }
 }
 
 
+# can be overridden by testcases for their pleasure
+getcodenamefromsuite() { echo -n "$1"; }
+getreleaseversionfromsuite() { true; }
+
 generatereleasefiles() {
 generatereleasefiles() {
 	msgninfo "\tGenerate Release files… "
 	msgninfo "\tGenerate Release files… "
 	local DATE="${1:-now}"
 	local DATE="${1:-now}"
@@ -489,9 +515,22 @@ generatereleasefiles() {
 			aptftparchive -qq release $dir -o APT::FTPArchive::Release::Patterns::='Translation-*' > $dir/Index
 			aptftparchive -qq release $dir -o APT::FTPArchive::Release::Patterns::='Translation-*' > $dir/Index
 		done
 		done
 		for dir in $(find ./aptarchive/dists -mindepth 1 -maxdepth 1 -type d); do
 		for dir in $(find ./aptarchive/dists -mindepth 1 -maxdepth 1 -type d); do
-			local CODENAME="$(echo "$dir" | cut -d'/' -f 4)"
-			aptftparchive -qq release $dir -o APT::FTPArchive::Release::Suite="${CODENAME}" -o APT::FTPArchive::Release::Codename="${CODENAME}" | sed -e '/0 Release$/ d' > $dir/Release # remove the self reference
-			if [ "$CODENAME" = "experimental" -o "$CODENAME" = "experimental2" ]; then
+			local SUITE="$(echo "$dir" | cut -d'/' -f 4)"
+			local CODENAME="$(getcodenamefromsuite $SUITE)"
+			local VERSION="$(getreleaseversionfromsuite $SUITE)"
+			if [ -z "$VERSION" ]; then
+				aptftparchive -qq release $dir \
+					-o APT::FTPArchive::Release::Suite="${SUITE}" \
+					-o APT::FTPArchive::Release::Codename="${CODENAME}" \
+						| sed -e '/0 Release$/ d' > $dir/Release # remove the self reference
+			else
+				aptftparchive -qq release $dir \
+					-o APT::FTPArchive::Release::Suite="${SUITE}" \
+					-o APT::FTPArchive::Release::Codename="${CODENAME}" \
+					-o APT::FTPArchive::Release::Version="${VERSION}" \
+						| sed -e '/0 Release$/ d' > $dir/Release # remove the self reference
+			fi
+			if [ "$SUITE" = "experimental" -o "$SUITE" = "experimental2" ]; then
 				sed -i '/^Date: / a\
 				sed -i '/^Date: / a\
 NotAutomatic: yes' $dir/Release
 NotAutomatic: yes' $dir/Release
 			fi
 			fi

+ 47 - 0
test/integration/test-bug-407511-fail-invalid-default-release

@@ -0,0 +1,47 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386'
+
+insertpackage 'unstable' 'cool' 'all' '1.0-1'
+
+getcodenamefromsuite() {
+	if [ "$SUITE" = 'unstable' ]; then
+		echo -n 'sid'
+	else
+		echo -n "$SUITE"
+	fi
+}
+getreleaseversionfromsuite() {
+	if [ "$SUITE" = 'unstable' ]; then
+		echo -n '42.0'
+	else
+		echo -n '0.8.15'
+	fi
+}
+
+setupaptarchive
+
+passdist() {
+	msgtest "Test that target-release is accepted" $1
+	aptget dist-upgrade -t $1 -qq && msgpass || msgfail
+}
+
+faildist() {
+	msgtest "Test that target-release is refused" $1
+	aptget dist-upgrade -t $1 -qq 2> /dev/null && msgfail || msgpass
+}
+
+passdist unstable
+passdist sid
+faildist sidd
+faildist stable
+passdist 42.0
+passdist 42.*
+passdist 42*
+passdist 4*.0
+faildist 21.0
+faildist 21*

+ 183 - 0
test/integration/test-bug-632221-cross-dependency-satisfaction

@@ -0,0 +1,183 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'amd64' 'armel'
+
+insertinstalledpackage 'build-essential' 'all' '11.5'
+
+insertpackage 'unstable' 'doxygen' 'amd64,armel' '1.0'
+insertpackage 'unstable' 'libc6' 'amd64,armel' '1.0' 'Multi-Arch: same'
+insertpackage 'unstable' 'libc6-dev' 'amd64,armel' '1.0' 'Depends: libc6
+Multi-Arch: same'
+insertpackage 'unstable' 'cool' 'amd64,armel' '1.0' 'Multi-Arch: allowed'
+insertpackage 'unstable' 'amdboot' 'amd64' '1.0'
+insertpackage 'unstable' 'foreigner' 'amd64,armel' '1.0' 'Multi-Arch: foreign'
+
+insertsource 'unstable' 'apt' 'any' '0.8.15' 'Build-Depends: doxygen, libc6-dev, libc6-dev:native, cool:any, amdboot:amd64, foreigner'
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot cool doxygen foreigner libc6 libc6-dev
+0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
+Inst amdboot (1.0 unstable [amd64])
+Inst cool (1.0 unstable [amd64])
+Inst doxygen (1.0 unstable [amd64])
+Inst foreigner (1.0 unstable [amd64])
+Inst libc6 (1.0 unstable [amd64])
+Inst libc6-dev (1.0 unstable [amd64])
+Conf amdboot (1.0 unstable [amd64])
+Conf cool (1.0 unstable [amd64])
+Conf doxygen (1.0 unstable [amd64])
+Conf foreigner (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [amd64])
+Conf libc6-dev (1.0 unstable [amd64])' aptget build-dep apt -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot cool doxygen foreigner libc6 libc6:armel libc6-dev libc6-dev:armel
+0 upgraded, 8 newly installed, 0 to remove and 0 not upgraded.
+Inst amdboot (1.0 unstable [amd64])
+Inst cool (1.0 unstable [amd64])
+Inst doxygen (1.0 unstable [amd64])
+Inst foreigner (1.0 unstable [amd64])
+Inst libc6:armel (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [amd64])
+Inst libc6-dev:armel (1.0 unstable [armel])
+Inst libc6-dev (1.0 unstable [amd64])
+Conf amdboot (1.0 unstable [amd64])
+Conf cool (1.0 unstable [amd64])
+Conf doxygen (1.0 unstable [amd64])
+Conf foreigner (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [amd64])
+Conf libc6:armel (1.0 unstable [armel])
+Conf libc6-dev (1.0 unstable [amd64])
+Conf libc6-dev:armel (1.0 unstable [armel])' aptget build-dep apt -s -a armel
+
+configarchitecture 'armel' 'amd64'
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot:amd64 cool doxygen foreigner libc6 libc6-dev
+0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
+Inst amdboot:amd64 (1.0 unstable [amd64])
+Inst cool (1.0 unstable [armel])
+Inst doxygen (1.0 unstable [armel])
+Inst foreigner (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [armel])
+Inst libc6-dev (1.0 unstable [armel])
+Conf amdboot:amd64 (1.0 unstable [amd64])
+Conf cool (1.0 unstable [armel])
+Conf doxygen (1.0 unstable [armel])
+Conf foreigner (1.0 unstable [armel])
+Conf libc6 (1.0 unstable [armel])
+Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot:amd64 cool doxygen foreigner libc6:amd64 libc6 libc6-dev:amd64
+  libc6-dev
+0 upgraded, 8 newly installed, 0 to remove and 0 not upgraded.
+Inst amdboot:amd64 (1.0 unstable [amd64])
+Inst cool (1.0 unstable [armel])
+Inst doxygen (1.0 unstable [armel])
+Inst foreigner (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [armel])
+Inst libc6:amd64 (1.0 unstable [amd64])
+Inst libc6-dev (1.0 unstable [armel])
+Inst libc6-dev:amd64 (1.0 unstable [amd64])
+Conf amdboot:amd64 (1.0 unstable [amd64])
+Conf cool (1.0 unstable [armel])
+Conf doxygen (1.0 unstable [armel])
+Conf foreigner (1.0 unstable [armel])
+Conf libc6:amd64 (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [armel])
+Conf libc6-dev:amd64 (1.0 unstable [amd64])
+Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s -a amd64
+
+configarchitecture 'amd64' 'armel'
+
+insertinstalledpackage 'cool' 'amd64' '0.5'
+insertinstalledpackage 'foreigner' 'armel' '0.5'
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot doxygen libc6 libc6-dev
+0 upgraded, 4 newly installed, 0 to remove and 2 not upgraded.
+Inst amdboot (1.0 unstable [amd64])
+Inst doxygen (1.0 unstable [amd64])
+Inst libc6 (1.0 unstable [amd64])
+Inst libc6-dev (1.0 unstable [amd64])
+Conf amdboot (1.0 unstable [amd64])
+Conf doxygen (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [amd64])
+Conf libc6-dev (1.0 unstable [amd64])' aptget build-dep apt -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot doxygen libc6 libc6:armel libc6-dev libc6-dev:armel
+0 upgraded, 6 newly installed, 0 to remove and 2 not upgraded.
+Inst amdboot (1.0 unstable [amd64])
+Inst doxygen (1.0 unstable [amd64])
+Inst libc6:armel (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [amd64])
+Inst libc6-dev:armel (1.0 unstable [armel])
+Inst libc6-dev (1.0 unstable [amd64])
+Conf amdboot (1.0 unstable [amd64])
+Conf doxygen (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [amd64])
+Conf libc6:armel (1.0 unstable [armel])
+Conf libc6-dev (1.0 unstable [amd64])
+Conf libc6-dev:armel (1.0 unstable [armel])' aptget build-dep apt -s -a armel
+
+configarchitecture 'armel' 'amd64'
+
+# cool 0.5 is not M-A: allowed, so amd64 is not acceptable
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages will be REMOVED:
+  cool:amd64
+The following NEW packages will be installed:
+  amdboot:amd64 cool doxygen libc6 libc6-dev
+0 upgraded, 5 newly installed, 1 to remove and 1 not upgraded.
+Remv cool:amd64 [0.5]
+Inst amdboot:amd64 (1.0 unstable [amd64])
+Inst cool (1.0 unstable [armel])
+Inst doxygen (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [armel])
+Inst libc6-dev (1.0 unstable [armel])
+Conf amdboot:amd64 (1.0 unstable [amd64])
+Conf cool (1.0 unstable [armel])
+Conf doxygen (1.0 unstable [armel])
+Conf libc6 (1.0 unstable [armel])
+Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot:amd64 doxygen libc6:amd64 libc6 libc6-dev:amd64 libc6-dev
+0 upgraded, 6 newly installed, 0 to remove and 2 not upgraded.
+Inst amdboot:amd64 (1.0 unstable [amd64])
+Inst doxygen (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [armel])
+Inst libc6:amd64 (1.0 unstable [amd64])
+Inst libc6-dev (1.0 unstable [armel])
+Inst libc6-dev:amd64 (1.0 unstable [amd64])
+Conf amdboot:amd64 (1.0 unstable [amd64])
+Conf doxygen (1.0 unstable [armel])
+Conf libc6:amd64 (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [armel])
+Conf libc6-dev:amd64 (1.0 unstable [amd64])
+Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s -a amd64
+
+

+ 38 - 4
test/libapt/assert.h

@@ -1,9 +1,9 @@
 #include <iostream>
 #include <iostream>
 
 
-#define equals(x,y) assertEquals(x, y, __LINE__)
+#define equals(x,y) assertEquals(y, x, __LINE__)
 
 
 template < typename X, typename Y >
 template < typename X, typename Y >
-void OutputAssert(X expect, char const* compare, Y get, unsigned long const &line) {
+void OutputAssertEqual(X expect, char const* compare, Y get, unsigned long const &line) {
 	std::cerr << "Test FAILED: »" << expect << "« " << compare << " »" << get << "« at line " << line << std::endl;
 	std::cerr << "Test FAILED: »" << expect << "« " << compare << " »" << get << "« at line " << line << std::endl;
 }
 }
 
 
@@ -11,11 +11,45 @@ template < typename X, typename Y >
 void assertEquals(X expect, Y get, unsigned long const &line) {
 void assertEquals(X expect, Y get, unsigned long const &line) {
 	if (expect == get)
 	if (expect == get)
 		return;
 		return;
-	OutputAssert(expect, "==", get, line);
+	OutputAssertEqual(expect, "==", get, line);
 }
 }
 
 
 void assertEquals(unsigned int const &expect, int const &get, unsigned long const &line) {
 void assertEquals(unsigned int const &expect, int const &get, unsigned long const &line) {
 	if (get < 0)
 	if (get < 0)
-		OutputAssert(expect, "==", get, line);
+		OutputAssertEqual(expect, "==", get, line);
 	assertEquals<unsigned int const&, unsigned int const&>(expect, get, line);
 	assertEquals<unsigned int const&, unsigned int const&>(expect, get, line);
 }
 }
+
+void assertEquals(int const &expect, unsigned int const &get, unsigned long const &line) {
+	if (expect < 0)
+		OutputAssertEqual(expect, "==", get, line);
+	assertEquals<unsigned int const&, unsigned int const&>(expect, get, line);
+}
+
+
+#define equalsOr2(x,y,z) assertEqualsOr2(y, z, x, __LINE__)
+
+template < typename X, typename Y >
+void OutputAssertEqualOr2(X expect1, X expect2, char const* compare, Y get, unsigned long const &line) {
+	std::cerr << "Test FAILED: »" << expect1 << "« or »" << expect2 << "« " << compare << " »" << get << "« at line " << line << std::endl;
+}
+
+template < typename X, typename Y >
+void assertEqualsOr2(X expect1, X expect2, Y get, unsigned long const &line) {
+	if (expect1 == get || expect2 == get)
+		return;
+	OutputAssertEqualOr2(expect1, expect2, "==", get, line);
+}
+
+void assertEqualsOr2(unsigned int const &expect1, unsigned int const &expect2, int const &get, unsigned long const &line) {
+	if (get < 0)
+		OutputAssertEqualOr2(expect1, expect2, "==", get, line);
+	assertEqualsOr2<unsigned int const&, unsigned int const&>(expect1, expect2, get, line);
+}
+
+void assertEqualsOr2(int const &expect1, int const &expect2, unsigned int const &get, unsigned long const &line) {
+	if (expect1 < 0 && expect2 < 0)
+		OutputAssertEqualOr2(expect1, expect2, "==", get, line);
+	assertEqualsOr2<unsigned int const&, unsigned int const&>(expect1, expect2, get, line);
+}
+

+ 6 - 0
test/libapt/getarchitectures_test.cc

@@ -39,6 +39,12 @@ int main(int argc,char *argv[])
 	_config->Set("APT::Architecture", "armel");
 	_config->Set("APT::Architecture", "armel");
 	vec = APT::Configuration::getArchitectures(false);
 	vec = APT::Configuration::getArchitectures(false);
 	equals(vec.size(), 2);
 	equals(vec.size(), 2);
+	equals(vec[0], "armel");
+	equals(vec[1], "i386");
+
+	_config->Set("APT::Architectures::2", "armel");
+	vec = APT::Configuration::getArchitectures(false);
+	equals(vec.size(), 2);
 	equals(vec[0], "i386");
 	equals(vec[0], "i386");
 	equals(vec[1], "armel");
 	equals(vec[1], "armel");
 
 

+ 2 - 2
test/libapt/getlanguages_test.cc

@@ -138,8 +138,8 @@ int main(int argc,char *argv[])
 	equals(vec[1], "de");
 	equals(vec[1], "de");
 	equals(vec[2], "en");
 	equals(vec[2], "en");
 	equals(vec[3], "none");
 	equals(vec[3], "none");
-	equals(vec[4], "pt");
-	equals(vec[5], "tr");
+	equalsOr2(vec[4], "pt", "tr");
+	equalsOr2(vec[5], "tr", "pt");
 
 
 	_config->Set("Dir::State::lists", "/non-existing-dir");
 	_config->Set("Dir::State::lists", "/non-existing-dir");
 	_config->Set("Acquire::Languages::1", "none");
 	_config->Set("Acquire::Languages::1", "none");

+ 6 - 0
test/libapt/makefile

@@ -52,3 +52,9 @@ PROGRAM = HashSums${BASENAME}
 SLIBS = -lapt-pkg
 SLIBS = -lapt-pkg
 SOURCE = hashsums_test.cc
 SOURCE = hashsums_test.cc
 include $(PROGRAM_H)
 include $(PROGRAM_H)
+
+# test the strutils stuff
+PROGRAM = StrUtil${BASENAME}
+SLIBS = -lapt-pkg
+SOURCE = strutil_test.cc
+include $(PROGRAM_H)

+ 46 - 0
test/libapt/strutil_test.cc

@@ -0,0 +1,46 @@
+#include <apt-pkg/strutl.h>
+
+#include "assert.h"
+
+int main(int argc,char *argv[])
+{
+   string input, output, expected;
+
+   // no input
+   input = "foobar";
+   expected = "foobar";
+   output = DeEscapeString(input);
+   equals(output, expected);
+
+   // hex and octal
+   input = "foo\\040bar\\x0abaz";
+   expected = "foo bar\nbaz";
+   output = DeEscapeString(input);
+   equals(output, expected);
+
+   // at the end
+   input = "foo\\040";
+   expected = "foo ";
+   output = DeEscapeString(input);
+   equals(output, expected);
+
+   // double escape
+   input = "foo\\\\ x";
+   expected = "foo\\ x";
+   output = DeEscapeString(input);
+   equals(output, expected);
+
+   // double escape at the end
+   input = "\\\\foo\\\\";
+   expected = "\\foo\\";
+   output = DeEscapeString(input);
+   equals(output, expected);
+
+   // the string that we actually need it for
+   input = "/media/Ubuntu\\04011.04\\040amd64";
+   expected = "/media/Ubuntu 11.04 amd64";
+   output = DeEscapeString(input);
+   equals(output, expected);
+
+   return 0;
+}