[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#265009: marked as done ([ABI change] apt translated package description patch)



Your message dated Sat, 08 Dec 2007 08:20:44 -0200
with message-id <874peto5c3.fsf@lab.ossystems.com.br>
and subject line Included in a previous release
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--- Begin Message ---
Package: apt
Version: 0.5.27
Severity: wishlist
Tags: patch

Hi,

attached is a patch that implements the apt part for translated
package descriptions. All credit go to Otavio Salvador
<otavio@debian.org> for doing the patch and Michael Bramer
<grisu@debian.org>. The patch is against 0.5.27.  Additional
information can be found in the mail from Michael Bramer at:
http://lwn.net/Articles/14676/

It works by adding a additonal index file that contains the
description. The language to download is determined by the current
locale or by "APT::Acquire::Translation". The code that checks the
current locales has problem if the locale is set like this:

LANG=POSIX
LC_CTYPE=de_DE
LC_NUMERIC="POSIX"
...

That is, if a LC_* is set different than LANG or LC_ALL it spits out a
lot of warnings. I'll have a look at it and see how to improve this.

I'm not sure if the source of the other frontends (like aptitude, synaptic)
needs to be changed to support it. Synaptic for examples uses:

     pkgRecords::Parser & parser = _records->Lookup(ver.FileList());
     do_something_with(parser.LongDesc());

and LongDesc() should give the "right" translated Description. I'm not
sure about aptitude. 

The big picture for the server that support this is:
 - download http://ddtp.debian.org/pdesc/translatefiles/Translations.tar.gz
   and unpack it under dists (this download location is stable)	
 - use a apt with the attached patch :)
 - set /etc/apt/apt.conf to 'APT::Acquire::Translation "de";' 
   (or whatever language, more than one language is possible)
 - apt-cache now shows information according to LANG (search, show work)
   
Thanks to Michael Bramer for this information. 

thanks, 
 Michael


-- Package-specific info:

-- (no /etc/apt/preferences present) --


-- (/etc/apt/sources.list present, but not submitted) --


-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing')
Architecture: i386 (i686)
Kernel: Linux 2.6.7
Locale: LANG=C, LC_CTYPE=de_DE

Versions of packages apt depends on:
ii  libc6                       2.3.2.ds1-13 GNU C Library: Shared libraries an
ii  libgcc1                     1:3.4.1-4    GCC support library
ii  libstdc++5                  1:3.3.4-5    The GNU Standard C++ Library v3

-- no debconf information
Index: apt-pkg/acquire-item.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/acquire-item.cc,v
retrieving revision 1.46
diff -u -r1.46 acquire-item.cc
--- apt-pkg/acquire-item.cc	2 Feb 2003 22:19:17 -0000	1.46
+++ apt-pkg/acquire-item.cc	11 Aug 2004 11:10:44 -0000
@@ -242,6 +242,34 @@
 }
 									/*}}}*/
 
+// AcqIndexTrans::pkgAcqIndexTrans - Constructor			/*{{{*/
+// ---------------------------------------------------------------------
+/* The Translation file is added to the queue */
+pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
+			    string URI,string URIDesc,string ShortDesc) :
+                      pkgAcqIndex(Owner, URI, URIDesc, ShortDesc)
+{
+}
+
+									/*}}}*/
+// AcqIndexTrans::Failed - Silence failure messages for missing files	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
+{
+   if (Cnf->LocalOnly == true || 
+       StringToBool(LookupTag(Message,"Transient-Failure"),false) == false)
+   {      
+      // Ignore this
+      Status = StatDone;
+      Complete = false;
+      Dequeue();
+      return;
+   }
+   
+   Item::Failed(Message,Cnf);
+}
+									/*}}}*/
 // AcqIndexRel::pkgAcqIndexRel - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 /* The Release file is added to the queue */
Index: apt-pkg/acquire-item.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/acquire-item.h,v
retrieving revision 1.26
diff -u -r1.26 acquire-item.h
--- apt-pkg/acquire-item.h	2 Feb 2003 03:13:13 -0000	1.26
+++ apt-pkg/acquire-item.h	11 Aug 2004 11:10:44 -0000
@@ -9,8 +9,8 @@
    the Owner Acquire class. Derived classes will then call QueueURI to 
    register all the URI's they wish to fetch at the initial moment.   
    
-   Two item classes are provided to provide functionality for downloading
-   of Index files and downloading of Packages.
+   Tree item classes are provided to provide functionality for
+   downloading of Index, Translation and Packages files.
    
    A Archive class is provided for downloading .deb files. It does Md5
    checking and source location as well as a retry algorithm.
@@ -97,6 +97,16 @@
 
    pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc,
 	       string ShortDesct);
+};
+
+// Item class for index files
+class pkgAcqIndexTrans : public pkgAcqIndex
+{
+public:
+  
+  virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
+  pkgAcqIndexTrans(pkgAcquire *Owner,string URI,string URIDesc,
+		   string ShortDesct);
 };
 
 // Item class for index files
Index: apt-pkg/cacheiterators.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/cacheiterators.h,v
retrieving revision 1.18
diff -u -r1.18 cacheiterators.h
--- apt-pkg/cacheiterators.h	9 Oct 2003 23:15:25 -0000	1.18
+++ apt-pkg/cacheiterators.h	11 Aug 2004 11:10:45 -0000
@@ -129,6 +129,7 @@
    inline const char *Section() const {return Ver->Section == 0?0:Owner->StrP + Ver->Section;};
    inline const char *Arch() const {return Ver->Arch == 0?0:Owner->StrP + Ver->Arch;};
    inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Ver->ParentPkg);};
+   inline DescIterator DescriptionList() const;
    inline DepIterator DependsList() const;
    inline PrvIterator ProvidesList() const;
    inline VerFileIterator FileList() const;
@@ -149,6 +150,50 @@
    };
 };
 
+// Description Iterator
+class pkgCache::DescIterator
+{
+   Description *Desc;
+   pkgCache *Owner;
+   
+   void _dummy();
+   
+   public:
+
+   // Iteration
+   void operator ++(int) {if (Desc != Owner->DescP) Desc = Owner->DescP + Desc->NextDesc;};
+   inline void operator ++() {operator ++(0);};
+   inline bool end() const {return Desc == Owner->DescP?true:false;};
+   inline void operator =(const DescIterator &B) {Desc = B.Desc; Owner = B.Owner;};
+   
+   // Comparison
+   inline bool operator ==(const DescIterator &B) const {return Desc == B.Desc;};
+   inline bool operator !=(const DescIterator &B) const {return Desc != B.Desc;};
+   int CompareDesc(const DescIterator &B) const;
+   
+   // Accessors
+   inline Description *operator ->() {return Desc;};
+   inline Description const *operator ->() const {return Desc;};
+   inline Description &operator *() {return *Desc;};
+   inline Description const &operator *() const {return *Desc;};
+   inline operator Description *() {return Desc == Owner->DescP?0:Desc;};
+   inline operator Description const *() const {return Desc == Owner->DescP?0:Desc;};
+   inline pkgCache *Cache() {return Owner;};
+      
+   inline const char *LanguageCode() const {return Owner->StrP + Desc->language_code;};
+   inline const char *md5() const {return Owner->StrP + Desc->md5sum;};
+   inline DescFileIterator FileList() const;
+   inline unsigned long Index() const {return Desc - Owner->DescP;};
+
+   inline DescIterator() : Desc(0), Owner(0) {};   
+   inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Desc(Trg), 
+              Owner(&Owner) 
+   { 
+      if (Desc == 0)
+	 Desc = Owner.DescP;
+   };
+};
+
 // Dependency iterator
 class pkgCache::DepIterator
 {
@@ -337,6 +382,38 @@
    inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Owner(&Owner), FileP(Trg) {};
 };
 
+// Description File 
+class pkgCache::DescFileIterator
+{
+   pkgCache *Owner;
+   DescFile *FileP;
+
+   public:
+
+   // Iteration
+   void operator ++(int) {if (FileP != Owner->DescFileP) FileP = Owner->DescFileP + FileP->NextFile;};
+   inline void operator ++() {operator ++(0);};
+   inline bool end() const {return FileP == Owner->DescFileP?true:false;};
+
+   // Comparison
+   inline bool operator ==(const DescFileIterator &B) const {return FileP == B.FileP;};
+   inline bool operator !=(const DescFileIterator &B) const {return FileP != B.FileP;};
+			   
+   // Accessors
+   inline DescFile *operator ->() {return FileP;};
+   inline DescFile const *operator ->() const {return FileP;};
+   inline DescFile const &operator *() const {return *FileP;};
+   inline operator DescFile *() {return FileP == Owner->DescFileP?0:FileP;};
+   inline operator DescFile const *() const {return FileP == Owner->DescFileP?0:FileP;};
+   inline pkgCache *Cache() {return Owner;};
+  
+   inline PkgFileIterator File() const {return PkgFileIterator(*Owner,FileP->File + Owner->PkgFileP);};
+   inline unsigned long Index() const {return FileP - Owner->DescFileP;};
+      
+   inline DescFileIterator() : Owner(0), FileP(0) {};
+   inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Owner(&Owner), FileP(Trg) {};
+};
+
 // Inlined Begin functions cant be in the class because of order problems
 inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
        {return VerIterator(*Owner,Owner->VerP + Pkg->VersionList);};
@@ -346,11 +423,15 @@
        {return DepIterator(*Owner,Owner->DepP + Pkg->RevDepends,Pkg);};
 inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const
        {return PrvIterator(*Owner,Owner->ProvideP + Pkg->ProvidesList,Pkg);};
+inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const
+       {return DescIterator(*Owner,Owner->DescP + Ver->DescriptionList);};
 inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const
        {return PrvIterator(*Owner,Owner->ProvideP + Ver->ProvidesList,Ver);};
 inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const
        {return DepIterator(*Owner,Owner->DepP + Ver->DependsList,Ver);};
 inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
        {return VerFileIterator(*Owner,Owner->VerFileP + Ver->FileList);};
+inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
+       {return DescFileIterator(*Owner,Owner->DescFileP + Desc->FileList);};
 
 #endif
Index: apt-pkg/indexfile.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/indexfile.cc,v
retrieving revision 1.2
diff -u -r1.2 indexfile.cc
--- apt-pkg/indexfile.cc	20 Feb 2001 07:03:17 -0000	1.2
+++ apt-pkg/indexfile.cc	11 Aug 2004 11:10:45 -0000
@@ -12,8 +12,11 @@
 #pragma implementation "apt-pkg/indexfile.h"
 #endif
 
+#include <apt-pkg/configuration.h>
 #include <apt-pkg/indexfile.h>
 #include <apt-pkg/error.h>
+
+#include <clocale>
 									/*}}}*/
 
 // Global list of Item supported
@@ -73,5 +76,45 @@
 				pkgSrcRecords::File const &File) const
 {
    return string();
+}
+									/*}}}*/
+// IndexFile::UseTranslation - Check if will use Translation	        /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgIndexFile::UseTranslation()
+{
+  const string Translation = _config->Find("APT::Acquire::Translation");
+  
+  if (Translation.compare("none") != 0)
+    return CheckLanguageCode(LanguageCode().c_str());
+  else
+    return false;
+}
+									/*}}}*/
+// IndexFile::CheckLanguageCode - Check the Language Code   	        /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgIndexFile::CheckLanguageCode(const char *Lang)
+{
+  if (strlen(Lang) == 2 || (strlen(Lang) == 5 && Lang[2] == '_'))
+    return true;
+
+  if (strcmp(Lang,"C") != 0)
+    _error->Warning("Wrong language code %s", Lang);
+
+  return false;
+}
+									/*}}}*/
+// IndexFile::LanguageCode - Return the Language Code            	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string pkgIndexFile::LanguageCode()
+{
+  const string Translation = _config->Find("APT::Acquire::Translation");
+
+  if (Translation.compare("environment") == 0)
+     return std::setlocale(LC_ALL,NULL);
+  else 
+     return Translation;
 }
 									/*}}}*/
Index: apt-pkg/indexfile.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/indexfile.h,v
retrieving revision 1.6
diff -u -r1.6 indexfile.h
--- apt-pkg/indexfile.h	8 Jul 2002 03:13:30 -0000	1.6
+++ apt-pkg/indexfile.h	11 Aug 2004 11:10:46 -0000
@@ -5,10 +5,11 @@
 
    Index File - Abstraction for an index of archive/source file.
    
-   There are 3 primary sorts of index files, all represented by this 
+   There are 4 primary sorts of index files, all represented by this 
    class:
    
    Binary index files 
+   Binary translation files 
    Bianry index files decribing the local system
    Source index files
    
@@ -76,6 +77,10 @@
    virtual bool Merge(pkgCacheGenerator &/*Gen*/,OpProgress &/*Prog*/) const {return false;};
    virtual bool MergeFileProvides(pkgCacheGenerator &/*Gen*/,OpProgress &/*Prog*/) const {return true;};
    virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
+
+   static bool UseTranslation();
+   static bool CheckLanguageCode(const char *Lang);
+   static string LanguageCode();
    
    virtual ~pkgIndexFile() {};
 };
Index: apt-pkg/init.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/init.cc,v
retrieving revision 1.21
diff -u -r1.21 init.cc
--- apt-pkg/init.cc	27 Feb 2004 00:46:44 -0000	1.21
+++ apt-pkg/init.cc	11 Aug 2004 11:10:47 -0000
@@ -33,6 +33,9 @@
    is prepended, this allows a fair degree of flexability. */
 bool pkgInitConfig(Configuration &Cnf)
 {
+   // Translation
+   Cnf.Set("APT::Acquire::Translation", "environment");
+
    // General APT things
    if (strcmp(COMMON_OS,"linux") == 0 ||
        strcmp(COMMON_OS,"unknown") == 0)
Index: apt-pkg/pkgcache.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/pkgcache.cc,v
retrieving revision 1.37
diff -u -r1.37 pkgcache.cc
--- apt-pkg/pkgcache.cc	10 Feb 2003 01:40:58 -0000	1.37
+++ apt-pkg/pkgcache.cc	11 Aug 2004 11:10:47 -0000
@@ -52,7 +52,7 @@
    
    /* Whenever the structures change the major version should be bumped,
       whenever the generator changes the minor version should be bumped. */
-   MajorVersion = 4;
+   MajorVersion = 5;
    MinorVersion = 0;
    Dirty = false;
    
@@ -60,17 +60,22 @@
    PackageSz = sizeof(pkgCache::Package);
    PackageFileSz = sizeof(pkgCache::PackageFile);
    VersionSz = sizeof(pkgCache::Version);
+   DescriptionSz = sizeof(pkgCache::Description);
    DependencySz = sizeof(pkgCache::Dependency);
    ProvidesSz = sizeof(pkgCache::Provides);
    VerFileSz = sizeof(pkgCache::VerFile);
+   DescFileSz = sizeof(pkgCache::DescFile);
    
    PackageCount = 0;
    VersionCount = 0;
+   DescriptionCount = 0;
    DependsCount = 0;
    PackageFileCount = 0;
    VerFileCount = 0;
+   DescFileCount = 0;
    ProvidesCount = 0;
    MaxVerFileSize = 0;
+   MaxDescFileSize = 0;
    
    FileList = 0;
    StringList = 0;
@@ -89,8 +94,10 @@
        PackageSz == Against.PackageSz &&
        PackageFileSz == Against.PackageFileSz &&
        VersionSz == Against.VersionSz &&
+       DescriptionSz == Against.DescriptionSz &&
        DependencySz == Against.DependencySz &&
        VerFileSz == Against.VerFileSz &&
+       DescFileSz == Against.DescFileSz &&
        ProvidesSz == Against.ProvidesSz)
       return true;
    return false;
@@ -115,8 +122,10 @@
    HeaderP = (Header *)Map.Data();
    PkgP = (Package *)Map.Data();
    VerFileP = (VerFile *)Map.Data();
+   DescFileP = (DescFile *)Map.Data();
    PkgFileP = (PackageFile *)Map.Data();
    VerP = (Version *)Map.Data();
+   DescP = (Description *)Map.Data();
    ProvideP = (Provides *)Map.Data();
    DepP = (Dependency *)Map.Data();
    StringItemP = (StringItem *)Map.Data();
Index: apt-pkg/pkgcache.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/pkgcache.h,v
retrieving revision 1.25
diff -u -r1.25 pkgcache.h
--- apt-pkg/pkgcache.h	1 Jul 2001 22:28:24 -0000	1.25
+++ apt-pkg/pkgcache.h	11 Aug 2004 11:10:47 -0000
@@ -38,24 +38,30 @@
    struct Package;
    struct PackageFile;
    struct Version;
+   struct Description;
    struct Provides;
    struct Dependency;
    struct StringItem;
    struct VerFile;
+   struct DescFile;
    
    // Iterators
    class PkgIterator;
    class VerIterator;
+   class DescIterator;
    class DepIterator;
    class PrvIterator;
    class PkgFileIterator;
    class VerFileIterator;
+   class DescFileIterator;
    friend class PkgIterator;
    friend class VerIterator;
+   friend class DescInterator;
    friend class DepIterator;
    friend class PrvIterator;
    friend class PkgFileIterator;
    friend class VerFileIterator;
+   friend class DescFileIterator;
    
    class Namespace;
    
@@ -98,8 +104,10 @@
    Header *HeaderP;
    Package *PkgP;
    VerFile *VerFileP;
+   DescFile *DescFileP;
    PackageFile *PkgFileP;
    Version *VerP;
+   Description *DescP;
    Provides *ProvideP;
    Dependency *DepP;
    StringItem *StringItemP;
@@ -151,16 +159,20 @@
    unsigned short PackageSz;
    unsigned short PackageFileSz;
    unsigned short VersionSz;
+   unsigned short DescriptionSz;
    unsigned short DependencySz;
    unsigned short ProvidesSz;
    unsigned short VerFileSz;
+   unsigned short DescFileSz;
    
    // Structure counts
    unsigned long PackageCount;
    unsigned long VersionCount;
+   unsigned long DescriptionCount;
    unsigned long DependsCount;
    unsigned long PackageFileCount;
    unsigned long VerFileCount;
+   unsigned long DescFileCount;
    unsigned long ProvidesCount;
    
    // Offsets
@@ -169,10 +181,11 @@
    map_ptrloc VerSysName;            // StringTable
    map_ptrloc Architecture;          // StringTable
    unsigned long MaxVerFileSize;
+   unsigned long MaxDescFileSize;
 
    /* Allocation pools, there should be one of these for each structure
       excluding the header */
-   DynamicMMap::Pool Pools[7];
+   DynamicMMap::Pool Pools[8];
    
    // Rapid package name lookup
    map_ptrloc HashTable[2*1048];
@@ -193,7 +206,7 @@
    map_ptrloc NextPackage;       // Package
    map_ptrloc RevDepends;        // Dependency
    map_ptrloc ProvidesList;      // Provides
-   
+
    // Install/Remove/Purge etc
    unsigned char SelectedState;     // What
    unsigned char InstState;         // Flags
@@ -232,6 +245,14 @@
    unsigned short Size;
 };
 
+struct pkgCache::DescFile
+{
+   map_ptrloc File;           // PackageFile
+   map_ptrloc NextFile;       // PkgVerFile
+   map_ptrloc Offset;         // File offset
+   unsigned short Size;
+};
+
 struct pkgCache::Version
 {
    map_ptrloc VerStr;            // Stringtable
@@ -241,6 +262,7 @@
    // Lists
    map_ptrloc FileList;          // VerFile
    map_ptrloc NextVer;           // Version
+   map_ptrloc DescriptionList;   // Description
    map_ptrloc DependsList;       // Dependency
    map_ptrloc ParentPkg;         // Package
    map_ptrloc ProvidesList;      // Provides
@@ -252,6 +274,22 @@
    unsigned char Priority;
 };
 
+struct pkgCache::Description
+{
+   // Language Code store the description translation language code. If
+   // the value has a 0 lenght then this is readed using the Package
+   // file else the Translation-CODE are used.
+   map_ptrloc language_code;     // StringTable
+   map_ptrloc md5sum;            // StringTable
+
+   // Linked list 
+   map_ptrloc FileList;          // DescFile
+   map_ptrloc NextDesc;          // Description
+   map_ptrloc ParentPkg;         // Package
+
+   unsigned short ID;
+};
+
 struct pkgCache::Dependency
 {
    map_ptrloc Version;         // Stringtable
@@ -299,11 +337,13 @@
 
    typedef pkgCache::PkgIterator PkgIterator;
    typedef pkgCache::VerIterator VerIterator;
+   typedef pkgCache::DescIterator DescIterator;
    typedef pkgCache::DepIterator DepIterator;
    typedef pkgCache::PrvIterator PrvIterator;
    typedef pkgCache::PkgFileIterator PkgFileIterator;
    typedef pkgCache::VerFileIterator VerFileIterator;   
    typedef pkgCache::Version Version;
+   typedef pkgCache::Description Description;
    typedef pkgCache::Package Package;
    typedef pkgCache::Header Header;
    typedef pkgCache::Dep Dep;
Index: apt-pkg/pkgcachegen.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/pkgcachegen.cc,v
retrieving revision 1.53
diff -u -r1.53 pkgcachegen.cc
--- apt-pkg/pkgcachegen.cc	2 Feb 2003 02:44:20 -0000	1.53
+++ apt-pkg/pkgcachegen.cc	11 Aug 2004 11:10:47 -0000
@@ -125,6 +125,28 @@
       string Version = List.Version();
       if (Version.empty() == true)
       {
+ 	 // Find the right version to write the description
+ 	 MD5SumValue CurMd5 = List.Description_md5();
+ 	 pkgCache::VerIterator Ver = Pkg.VersionList();
+ 	 map_ptrloc *LastVer = &Pkg->VersionList;
+ 	 
+  	 for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++) 
+ 	 {
+ 	    pkgCache::DescIterator Desc = Ver.DescriptionList();
+ 	    map_ptrloc *LastDesc = &Ver->DescriptionList;
+       
+ 	    for (; Desc.end() == false; LastDesc = &Desc->NextDesc, Desc++)
+ 	       if (MD5SumValue(Desc.md5()) == CurMd5) {
+ 		  // Add new description
+ 		  *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), CurMd5, *LastDesc);
+ 		  Desc->ParentPkg = Pkg.Index();
+ 
+ 		  if (NewFileDesc(Desc,List) == false)
+ 		     return _error->Error(_("Error occured while processing %s (NewFileDesc1)"),PackageName.c_str());
+ 		  break;
+ 	       }
+ 	 }
+ 
 	 if (List.UsePackage(Pkg,pkgCache::VerIterator(Cache)) == false)
 	    return _error->Error(_("Error occured while processing %s (UsePackage1)"),
 				 PackageName.c_str());
@@ -132,9 +154,9 @@
       }
 
       pkgCache::VerIterator Ver = Pkg.VersionList();
-      map_ptrloc *Last = &Pkg->VersionList;
+      map_ptrloc *LastVer = &Pkg->VersionList;
       int Res = 1;
-      for (; Ver.end() == false; Last = &Ver->NextVer, Ver++)
+      for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
       {
 	 Res = Cache.VS->CmpVersion(Version,Ver.VerStr());
 	 if (Res >= 0)
@@ -168,7 +190,7 @@
       // Skip to the end of the same version set.
       if (Res == 0)
       {
-	 for (; Ver.end() == false; Last = &Ver->NextVer, Ver++)
+	 for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
 	 {
 	    Res = Cache.VS->CmpVersion(Version,Ver.VerStr());
 	    if (Res != 0)
@@ -177,9 +199,10 @@
       }
 
       // Add a new version
-      *Last = NewVersion(Ver,Version,*Last);
+      *LastVer = NewVersion(Ver,Version,*LastVer);
       Ver->ParentPkg = Pkg.Index();
       Ver->Hash = Hash;
+
       if (List.NewVersion(Ver) == false)
 	 return _error->Error(_("Error occured while processing %s (NewVersion1)"),
 			      PackageName.c_str());
@@ -199,6 +222,21 @@
 	 FoundFileDeps |= List.HasFileDeps();
 	 return true;
       }      
+
+      /* Record the Description data. Description data always exist in
+	 Packages and Translation-* files. */
+      pkgCache::DescIterator Desc = Ver.DescriptionList();
+      map_ptrloc *LastDesc = &Ver->DescriptionList;
+      
+      // Skip to the end of description set
+      for (; Desc.end() == false; LastDesc = &Desc->NextDesc, Desc++);
+
+      // Add new description
+      *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), List.Description_md5(), *LastDesc);
+      Desc->ParentPkg = Pkg.Index();
+
+      if (NewFileDesc(Desc,List) == false)
+	 return _error->Error(_("Error occured while processing %s (NewFileDesc2)"),PackageName.c_str());
    }
 
    FoundFileDeps |= List.HasFileDeps();
@@ -209,6 +247,9 @@
    if (Cache.HeaderP->VersionCount >= (1ULL<<(sizeof(Cache.VerP->ID)*8))-1)
       return _error->Error(_("Wow, you exceeded the number of versions "
 			     "this APT is capable of."));
+   if (Cache.HeaderP->DescriptionCount >= (1ULL<<(sizeof(Cache.DescP->ID)*8))-1)
+      return _error->Error(_("Wow, you exceeded the number of descriptions "
+			     "this APT is capable of."));
    if (Cache.HeaderP->DependsCount >= (1ULL<<(sizeof(Cache.DepP->ID)*8))-1ULL)
       return _error->Error(_("Wow, you exceeded the number of dependencies "
 			     "this APT is capable of."));
@@ -271,7 +312,7 @@
    Pkg = Cache.FindPkg(Name);
    if (Pkg.end() == false)
       return true;
-       
+
    // Get a structure
    unsigned long Package = Map.Allocate(sizeof(pkgCache::Package));
    if (Package == 0)
@@ -349,6 +390,61 @@
    return Version;
 }
 									/*}}}*/
+// CacheGenerator::NewFileDesc - Create a new File<->Desc association	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgCacheGenerator::NewFileDesc(pkgCache::DescIterator &Desc,
+				   ListParser &List)
+{
+   if (CurrentFile == 0)
+      return true;
+   
+   // Get a structure
+   unsigned long DescFile = Map.Allocate(sizeof(pkgCache::DescFile));
+   if (DescFile == 0)
+      return 0;
+   
+   pkgCache::DescFileIterator DF(Cache,Cache.DescFileP + DescFile);
+   DF->File = CurrentFile - Cache.PkgFileP;
+   
+   // Link it to the end of the list
+   map_ptrloc *Last = &Desc->FileList;
+   for (pkgCache::DescFileIterator D = Desc.FileList(); D.end() == false; D++)
+      Last = &D->NextFile;
+   DF->NextFile = *Last;
+   *Last = DF.Index();
+   
+   DF->Offset = List.Offset();
+   DF->Size = List.Size();
+   if (Cache.HeaderP->MaxDescFileSize < DF->Size)
+      Cache.HeaderP->MaxDescFileSize = DF->Size;
+   Cache.HeaderP->DescFileCount++;
+   
+   return true;
+}
+									/*}}}*/
+// CacheGenerator::NewDescription - Create a new Description		/*{{{*/
+// ---------------------------------------------------------------------
+/* This puts a description structure in the linked list */
+map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
+					    const string &Lang, const MD5SumValue &md5sum,
+					    map_ptrloc Next)
+{
+   // Get a structure
+   map_ptrloc Description = Map.Allocate(sizeof(pkgCache::Description));
+   if (Description == 0)
+      return 0;
+
+   // Fill it in
+   Desc = pkgCache::DescIterator(Cache,Cache.DescP + Description);
+   Desc->NextDesc = Next;
+   Desc->ID = Cache.HeaderP->DescriptionCount++;
+   Desc->language_code = Map.WriteString(Lang);
+   Desc->md5sum = Map.WriteString(md5sum.Value());
+
+   return Description;
+}
+									/*}}}*/
 // ListParser::NewDepends - Create a dependency element			/*{{{*/
 // ---------------------------------------------------------------------
 /* This creates a dependency element in the tree. It is linked to the
@@ -580,7 +676,7 @@
       pkgCache::PkgFileIterator File = (*Start)->FindInCache(Cache);
       if (File.end() == true)
 	 return false;
-      
+
       Visited[File->ID] = true;
    }
    
Index: apt-pkg/pkgcachegen.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/pkgcachegen.h,v
retrieving revision 1.19
diff -u -r1.19 pkgcachegen.h
--- apt-pkg/pkgcachegen.h	8 Jul 2002 03:13:30 -0000	1.19
+++ apt-pkg/pkgcachegen.h	11 Aug 2004 11:10:47 -0000
@@ -24,6 +24,7 @@
 #endif 
 
 #include <apt-pkg/pkgcache.h>
+#include <apt-pkg/md5.h>
 
 class pkgSourceList;
 class OpProgress;
@@ -55,7 +56,9 @@
    
    bool NewPackage(pkgCache::PkgIterator &Pkg,string Pkg);
    bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List);
+   bool NewFileDesc(pkgCache::DescIterator &Desc,ListParser &List);
    unsigned long NewVersion(pkgCache::VerIterator &Ver,string VerStr,unsigned long Next);
+   map_ptrloc NewDescription(pkgCache::DescIterator &Desc,const string &Lang,const MD5SumValue &md5sum,map_ptrloc Next);
 
    public:
 
@@ -107,6 +110,9 @@
    virtual string Package() = 0;
    virtual string Version() = 0;
    virtual bool NewVersion(pkgCache::VerIterator Ver) = 0;
+   virtual string Description() = 0;
+   virtual string DescriptionLanguage() = 0;
+   virtual MD5SumValue Description_md5() = 0;
    virtual unsigned short VersionHash() = 0;
    virtual bool UsePackage(pkgCache::PkgIterator Pkg,
 			   pkgCache::VerIterator Ver) = 0;
Index: apt-pkg/pkgrecords.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/pkgrecords.cc,v
retrieving revision 1.8
diff -u -r1.8 pkgrecords.cc
--- apt-pkg/pkgrecords.cc	2 Sep 2003 04:52:16 -0000	1.8
+++ apt-pkg/pkgrecords.cc	11 Aug 2004 11:10:47 -0000
@@ -63,3 +63,12 @@
    return *Files[Ver.File()->ID];
 }
 									/*}}}*/
+// Records::Lookup - Get a parser for the package description file	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgRecords::Parser &pkgRecords::Lookup(pkgCache::DescFileIterator const &Desc)
+{
+   Files[Desc.File()->ID]->Jump(Desc);
+   return *Files[Desc.File()->ID];
+}
+									/*}}}*/
Index: apt-pkg/pkgrecords.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/pkgrecords.h,v
retrieving revision 1.6
diff -u -r1.6 pkgrecords.h
--- apt-pkg/pkgrecords.h	13 Mar 2001 06:51:46 -0000	1.6
+++ apt-pkg/pkgrecords.h	11 Aug 2004 11:10:47 -0000
@@ -38,6 +38,7 @@
 
    // Lookup function
    Parser &Lookup(pkgCache::VerFileIterator const &Ver);
+   Parser &Lookup(pkgCache::DescFileIterator const &Desc);
 
    // Construct destruct
    pkgRecords(pkgCache &Cache);
@@ -49,6 +50,7 @@
    protected:
    
    virtual bool Jump(pkgCache::VerFileIterator const &Ver) = 0;
+   virtual bool Jump(pkgCache::DescFileIterator const &Desc) = 0;
    
    public:
    friend class pkgRecords;
Index: apt-pkg/contrib/strutl.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/contrib/strutl.cc,v
retrieving revision 1.48
diff -u -r1.48 strutl.cc
--- apt-pkg/contrib/strutl.cc	18 Jul 2003 14:15:11 -0000	1.48
+++ apt-pkg/contrib/strutl.cc	11 Aug 2004 11:10:49 -0000
@@ -32,12 +32,55 @@
 #include <regex.h>
 #include <errno.h>
 #include <stdarg.h>
+#include <iconv.h>
 
 #include "config.h"
 
 using namespace std;
 									/*}}}*/
 
+// UTF8ToCodeset - Convert some UTF-8 string for some codeset   	/*{{{*/
+// ---------------------------------------------------------------------
+/* This is handy to use before display some information for enduser  */
+bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest)
+{
+  iconv_t cd;
+  const char *inbuf;
+  char *inptr, *outbuf, *outptr;
+  size_t insize, outsize, nconv;
+  
+  cd = iconv_open(codeset, "UTF-8");
+  if (cd == (iconv_t)(-1)) {
+     // Something went wrong
+     if (errno == EINVAL)
+	_error->Error("conversion from 'UTF-8' to '%s' not available",
+               codeset);
+     else
+	perror("iconv_open");
+     
+     // Clean the destination string
+     *dest = "";
+     
+     return false;
+  }
+
+  insize = outsize = orig.size();
+  inbuf = orig.data();
+  inptr = (char *)inbuf;
+  outbuf = new char[insize+1];
+  outptr = outbuf;
+
+  iconv(cd, &inptr, &insize, &outptr, &outsize);
+  *outptr = '\0';
+
+  *dest = outbuf;
+  delete[] outbuf;
+  
+  iconv_close(cd);
+
+  return true;
+}
+									/*}}}*/
 // strstrip - Remove white space from the front and back of a string	/*{{{*/
 // ---------------------------------------------------------------------
 /* This is handy to use when parsing a file. It also removes \n's left 
@@ -357,7 +400,7 @@
    U.Access = "";
    
    // "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF";
-   URI = QuoteString(U,"\\|{}[]<>\"^~_=!@#$%^&*");
+   URI = QuoteString(U,"\\|{}[]<>\"^~=!@#$%^&*");
    string::iterator J = URI.begin();
    for (; J != URI.end(); J++)
       if (*J == '/') 
Index: apt-pkg/contrib/strutl.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/contrib/strutl.h,v
retrieving revision 1.22
diff -u -r1.22 strutl.h
--- apt-pkg/contrib/strutl.h	2 Feb 2003 22:20:27 -0000	1.22
+++ apt-pkg/contrib/strutl.h	11 Aug 2004 11:10:49 -0000
@@ -38,7 +38,8 @@
 #define APT_FORMAT2
 #define APT_FORMAT3
 #endif    
-    
+
+bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest);
 char *_strstrip(char *String);
 char *_strtabexpand(char *String,size_t Len);
 bool ParseQuoteWord(const char *&String,string &Res);
Index: apt-pkg/deb/debindexfile.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/debindexfile.cc,v
retrieving revision 1.6
diff -u -r1.6 debindexfile.cc
--- apt-pkg/deb/debindexfile.cc	4 Jan 2004 07:41:30 -0000	1.6
+++ apt-pkg/deb/debindexfile.cc	11 Aug 2004 11:10:49 -0000
@@ -339,6 +339,140 @@
 }
 									/*}}}*/
 
+// TranslationsIndex::debTranslationsIndex - Contructor			/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section) : 
+                  URI(URI), Dist(Dist), Section(Section)
+{
+}
+									/*}}}*/
+// TranslationIndex::Trans* - Return the URI to the translation files	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+inline string debTranslationsIndex::IndexFile(const char *Type) const
+{
+   return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
+}
+string debTranslationsIndex::IndexURI(const char *Type) const
+{
+   string Res;
+   if (Dist[Dist.size() - 1] == '/')
+   {
+      if (Dist != "/")
+	 Res = URI + Dist;
+      else 
+	 Res = URI;
+   }
+   else
+      Res = URI + "dists/" + Dist + '/' + Section +
+      "/i18n/Translation-";
+   
+   Res += Type;
+   return Res;
+}
+									/*}}}*/
+// TranslationsIndex::GetIndexes - Fetch the index files		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool debTranslationsIndex::GetIndexes(pkgAcquire *Owner) const
+{
+   if (UseTranslation()) {
+     string TranslationFile = "Translation-" + LanguageCode();
+     new pkgAcqIndexTrans(Owner, IndexURI(LanguageCode().c_str()),
+			  Info(TranslationFile.c_str()),
+			  TranslationFile);
+   }
+
+   return true;
+}
+									/*}}}*/
+// TranslationsIndex::Describe - Give a descriptive path to the index	/*{{{*/
+// ---------------------------------------------------------------------
+/* This should help the user find the index in the sources.list and
+   in the filesystem for problem solving */
+string debTranslationsIndex::Describe(bool Short) const
+{   
+   char S[300];
+   if (Short == true)
+      snprintf(S,sizeof(S),"%s",Info(TranslationFile().c_str()).c_str());
+   else
+      snprintf(S,sizeof(S),"%s (%s)",Info(TranslationFile().c_str()).c_str(),
+	       IndexFile(LanguageCode().c_str()).c_str());
+   return S;
+}
+									/*}}}*/
+// TranslationsIndex::Info - One liner describing the index URI		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string debTranslationsIndex::Info(const char *Type) const 
+{
+   string Info = ::URI::SiteOnly(URI) + ' ';
+   if (Dist[Dist.size() - 1] == '/')
+   {
+      if (Dist != "/")
+	 Info += Dist;
+   }
+   else
+      Info += Dist + '/' + Section;   
+   Info += " ";
+   Info += Type;
+   return Info;
+}
+									/*}}}*/
+// TranslationsIndex::Exists - Check if the index is available		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool debTranslationsIndex::Exists() const
+{
+   return true;
+}
+									/*}}}*/
+// TranslationsIndex::Size - Return the size of the index		/*{{{*/
+// ---------------------------------------------------------------------
+/* This is really only used for progress reporting. */
+unsigned long debTranslationsIndex::Size() const
+{
+   struct stat S;
+   if (stat(IndexFile(LanguageCode().c_str()).c_str(),&S) != 0)
+      return 0;
+   return S.st_size;
+}
+									/*}}}*/
+// TranslationsIndex::Merge - Load the index file into a cache		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const
+{
+   // Check the translation file, if in use
+   string TranslationFile = IndexFile(LanguageCode().c_str());
+   if (UseTranslation() && FileExists(TranslationFile))
+   {
+     FileFd Trans(TranslationFile,FileFd::ReadOnly);
+     debListParser TransParser(&Trans);
+     if (_error->PendingError() == true)
+       return false;
+     
+     Prog.SubProgress(0, Info(TranslationFile.c_str()));
+     if (Gen.SelectFile(TranslationFile,string(),*this) == false)
+       return _error->Error("Problem with SelectFile %s",TranslationFile.c_str());
+
+     // Store the IMS information
+     pkgCache::PkgFileIterator TransFile = Gen.GetCurFile();
+     struct stat TransSt;
+     if (fstat(Trans.Fd(),&TransSt) != 0)
+       return _error->Errno("fstat","Failed to stat");
+     TransFile->Size = TransSt.st_size;
+     TransFile->mtime = TransSt.st_mtime;
+   
+     if (Gen.MergeList(TransParser) == false)
+       return _error->Error("Problem with MergeList %s",TranslationFile.c_str());
+   }
+
+   return true;
+}
+									/*}}}*/
+
 // StatusIndex::debStatusIndex - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -428,6 +562,7 @@
 		   pkgSourceList::Vendor const *Vendor) const
    {
       List.push_back(new debPackagesIndex(URI,Dist,Section));
+      List.push_back(new debTranslationsIndex(URI,Dist,Section));
       return true;
    };
 
@@ -496,6 +631,10 @@
    return &_apt_Src;
 }
 const pkgIndexFile::Type *debPackagesIndex::GetType() const
+{
+   return &_apt_Pkg;
+}
+const pkgIndexFile::Type *debTranslationsIndex::GetType() const
 {
    return &_apt_Pkg;
 }
Index: apt-pkg/deb/debindexfile.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/debindexfile.h,v
retrieving revision 1.3
diff -u -r1.3 debindexfile.h
--- apt-pkg/deb/debindexfile.h	29 Apr 2001 05:13:51 -0000	1.3
+++ apt-pkg/deb/debindexfile.h	11 Aug 2004 11:10:50 -0000
@@ -52,7 +52,7 @@
    string Info(const char *Type) const;
    string IndexFile(const char *Type) const;
    string IndexURI(const char *Type) const;   
-   
+
    public:
    
    virtual const Type *GetType() const;
@@ -73,6 +73,35 @@
    virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
    
    debPackagesIndex(string URI,string Dist,string Section);
+};
+
+class debTranslationsIndex : public pkgIndexFile
+{
+   string URI;
+   string Dist;
+   string Section;
+   
+   string Info(const char *Type) const;
+   string IndexFile(const char *Type) const;
+   string IndexURI(const char *Type) const;
+
+   inline string TranslationFile() const {return "Translation-" + LanguageCode();};
+
+   public:
+   
+   virtual const Type *GetType() const;
+
+   // Interface for acquire
+   virtual string Describe(bool Short) const;   
+   virtual bool GetIndexes(pkgAcquire *Owner) const;
+   
+   // Interface for the Cache Generator
+   virtual bool Exists() const;
+   virtual bool HasPackages() const {return true;};
+   virtual unsigned long Size() const;
+   virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const;
+
+   debTranslationsIndex(string URI,string Dist,string Section);
 };
 
 class debSourcesIndex : public pkgIndexFile
Index: apt-pkg/deb/deblistparser.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/deblistparser.cc,v
retrieving revision 1.29
diff -u -r1.29 deblistparser.cc
--- apt-pkg/deb/deblistparser.cc	22 Sep 2003 04:16:26 -0000	1.29
+++ apt-pkg/deb/deblistparser.cc	11 Aug 2004 11:10:51 -0000
@@ -15,6 +15,7 @@
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/crc-16.h>
+#include <apt-pkg/md5.h>
 
 #include <ctype.h>
 
@@ -117,6 +118,46 @@
    return true;
 }
 									/*}}}*/
+// ListParser::Description - Return the description string		/*{{{*/
+// ---------------------------------------------------------------------
+/* This is to return the string describing the package in debian
+   form. If this returns the blank string then the entry is assumed to
+   only describe package properties */
+string debListParser::Description()
+{
+   if (DescriptionLanguage().empty())
+      return Section.FindS("Description");
+   else
+      return Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str());
+}
+                                                                        /*}}}*/
+// ListParser::DescriptionLanguage - Return the description lang string	/*{{{*/
+// ---------------------------------------------------------------------
+/* This is to return the string describing the language of
+   description. If this returns the blank string then the entry is
+   assumed to describe original description. */
+string debListParser::DescriptionLanguage()
+{
+   return Section.FindS("Description").empty() ? pkgIndexFile::LanguageCode() : "";
+}
+                                                                        /*}}}*/
+// ListParser::Description - Return the description_md5 MD5SumValue	/*{{{*/
+// ---------------------------------------------------------------------
+/* This is to return the md5 string to allow the check if is the right
+   description. If thisreturns a blank string then calculate the md5
+   value. */
+MD5SumValue debListParser::Description_md5()
+{
+   string value = Section.FindS("Description-md5");
+
+   if (value.empty()) {
+      MD5Summation md5;
+      md5.Add((Description() + "\n").c_str());
+      return md5.Result();
+   } else
+      return MD5SumValue(value);
+}
+                                                                        /*}}}*/
 // ListParser::UsePackage - Update a package structure			/*{{{*/
 // ---------------------------------------------------------------------
 /* This is called to update the package with any new information 
@@ -546,7 +587,7 @@
          inside the Status file, so that is a positive return */
       const char *Start;
       const char *Stop;
-      if (Section.Find("Architecture",Start,Stop) == false)
+      if (Section.Find("Architecture",Start,Stop) == false) 
 	 return true;
 
       if (stringcmp(Arch,Start,Stop) == 0)
Index: apt-pkg/deb/deblistparser.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/deblistparser.h,v
retrieving revision 1.9
diff -u -r1.9 deblistparser.h
--- apt-pkg/deb/deblistparser.h	20 Feb 2001 07:03:17 -0000	1.9
+++ apt-pkg/deb/deblistparser.h	11 Aug 2004 11:10:51 -0000
@@ -12,6 +12,7 @@
 #define PKGLIB_DEBLISTPARSER_H
 
 #include <apt-pkg/pkgcachegen.h>
+#include <apt-pkg/indexfile.h>
 #include <apt-pkg/tagfile.h>
 
 class debListParser : public pkgCacheGenerator::ListParser
@@ -47,6 +48,9 @@
    virtual string Package();
    virtual string Version();
    virtual bool NewVersion(pkgCache::VerIterator Ver);
+   virtual string Description();
+   virtual string DescriptionLanguage();
+   virtual MD5SumValue Description_md5();
    virtual unsigned short VersionHash();
    virtual bool UsePackage(pkgCache::PkgIterator Pkg,
 			   pkgCache::VerIterator Ver);
Index: apt-pkg/deb/debrecords.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/debrecords.cc,v
retrieving revision 1.10
diff -u -r1.10 debrecords.cc
--- apt-pkg/deb/debrecords.cc	13 Mar 2001 06:51:46 -0000	1.10
+++ apt-pkg/deb/debrecords.cc	11 Aug 2004 11:10:51 -0000
@@ -12,7 +12,9 @@
 #pragma implementation "apt-pkg/debrecords.h"
 #endif
 #include <apt-pkg/debrecords.h>
+#include <apt-pkg/strutl.h>
 #include <apt-pkg/error.h>
+#include <langinfo.h>
 									/*}}}*/
 
 // RecordParser::debRecordParser - Constructor				/*{{{*/
@@ -31,6 +33,10 @@
 {
    return Tags.Jump(Section,Ver->Offset);
 }
+bool debRecordParser::Jump(pkgCache::DescFileIterator const &Desc)
+{
+   return Tags.Jump(Section,Desc->Offset);
+}
 									/*}}}*/
 // RecordParser::FileName - Return the archive filename on the site	/*{{{*/
 // ---------------------------------------------------------------------
@@ -77,7 +83,7 @@
 /* */
 string debRecordParser::ShortDesc()
 {
-   string Res = Section.FindS("Description");
+   string Res = LongDesc();
    string::size_type Pos = Res.find('\n');
    if (Pos == string::npos)
       return Res;
@@ -89,7 +95,20 @@
 /* */
 string debRecordParser::LongDesc()
 {
-   return Section.FindS("Description");
+  string orig, dest;
+  char *codeset = nl_langinfo(CODESET);
+
+  if (!Section.FindS("Description").empty())
+     orig = Section.FindS("Description").c_str();
+  else 
+     orig = Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str()).c_str();
+
+  if (strcmp(codeset,"UTF-8") != 0) {
+     UTF8ToCodeset(codeset, orig, &dest);
+     orig = dest;
+   }    
+  
+   return orig;
 }
 									/*}}}*/
 // RecordParser::SourcePkg - Return the source package name if any	/*{{{*/
Index: apt-pkg/deb/debrecords.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/debrecords.h,v
retrieving revision 1.8
diff -u -r1.8 debrecords.h
--- apt-pkg/deb/debrecords.h	13 Mar 2001 06:51:46 -0000	1.8
+++ apt-pkg/deb/debrecords.h	11 Aug 2004 11:10:51 -0000
@@ -19,6 +19,7 @@
 #endif 
 
 #include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/indexfile.h>
 #include <apt-pkg/tagfile.h>
 
 class debRecordParser : public pkgRecords::Parser
@@ -30,6 +31,7 @@
    protected:
    
    virtual bool Jump(pkgCache::VerFileIterator const &Ver);
+   virtual bool Jump(pkgCache::DescFileIterator const &Desc);
    
    public:
 
Index: cmdline/apt-cache.cc
===================================================================
RCS file: /cvs/deity/apt/cmdline/apt-cache.cc,v
retrieving revision 1.72
diff -u -r1.72 apt-cache.cc
--- cmdline/apt-cache.cc	30 Apr 2004 04:34:03 -0000	1.72
+++ cmdline/apt-cache.cc	11 Aug 2004 11:10:53 -0000
@@ -71,6 +71,12 @@
 {   
    qsort(begin,Count,Size,LocalityCompare);
 }
+
+void LocalitySort(pkgCache::DescFile **begin,
+		  unsigned long Count,size_t Size)
+{   
+   qsort(begin,Count,Size,LocalityCompare);
+}
 									/*}}}*/
 // UnMet - Show unmet dependencies					/*{{{*/
 // ---------------------------------------------------------------------
@@ -182,7 +188,14 @@
       {
 	 cout << Cur.VerStr();
 	 for (pkgCache::VerFileIterator Vf = Cur.FileList(); Vf.end() == false; Vf++)
-	    cout << "(" << Vf.File().FileName() << ")";
+	    cout << " (" << Vf.File().FileName() << ")";
+	 cout << endl;
+	 for (pkgCache::DescIterator D = Cur.DescriptionList(); D.end() == false; D++)
+	 {
+	    cout << " Description Language: " << D.LanguageCode() << endl
+		 << "                 File: " << D.FileList().File().FileName() << endl
+		 << "                  MD5: " << D.md5() << endl;
+	 }
 	 cout << endl;
       }
       
@@ -277,11 +290,15 @@
    
    cout << _("Total Distinct Versions: ") << Cache.Head().VersionCount << " (" <<
       SizeToStr(Cache.Head().VersionCount*Cache.Head().VersionSz) << ')' << endl;
+   cout << _("Total Distinct Descriptions: ") << Cache.Head().DescriptionCount << " (" <<
+      SizeToStr(Cache.Head().DescriptionCount*Cache.Head().DescriptionSz) << ')' << endl;
    cout << _("Total Dependencies: ") << Cache.Head().DependsCount << " (" << 
       SizeToStr(Cache.Head().DependsCount*Cache.Head().DependencySz) << ')' << endl;
    
    cout << _("Total Ver/File relations: ") << Cache.Head().VerFileCount << " (" <<
       SizeToStr(Cache.Head().VerFileCount*Cache.Head().VerFileSz) << ')' << endl;
+   cout << _("Total Desc/File relations: ") << Cache.Head().DescFileCount << " (" <<
+      SizeToStr(Cache.Head().DescFileCount*Cache.Head().DescFileSz) << ')' << endl;
    cout << _("Total Provides Mappings: ") << Cache.Head().ProvidesCount << " (" <<
       SizeToStr(Cache.Head().ProvidesCount*Cache.Head().ProvidesSz) << ')' << endl;
    
@@ -344,6 +361,12 @@
 	 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
 	    cout << "  Depends: " << D.TargetPkg().Name() << ' ' << 
 	                     DeNull(D.TargetVer()) << endl;
+	 for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; D++)
+	 {
+	    cout << " Description Language: " << D.LanguageCode() << endl
+		 << "                 File: " << D.FileList().File().FileName() << endl
+		 << "                  MD5: " << D.md5() << endl;
+	 } 
       }      
    }
 
@@ -1192,28 +1215,51 @@
    if (_error->PendingError() == true)
       return false;
    
-   // Read the record and then write it out again.
+   // Read the record
    unsigned char *Buffer = new unsigned char[GCache->HeaderP->MaxVerFileSize+1];
    Buffer[V.FileList()->Size] = '\n';
    if (PkgF.Seek(V.FileList()->Offset) == false ||
-       PkgF.Read(Buffer,V.FileList()->Size) == false ||
-       fwrite(Buffer,1,V.FileList()->Size+1,stdout) < (size_t)(V.FileList()->Size+1))
+       PkgF.Read(Buffer,V.FileList()->Size) == false)
    {
       delete [] Buffer;
       return false;
    }
-   
+   // Strip the Description
+   unsigned char *DescP = (unsigned char*)strstr((char*)Buffer, "Description:");
+   *DescP='\0';
+
+   // Write all the rest
+   if (write(STDOUT_FILENO,Buffer,strlen((char *)Buffer)+1) != strlen((char *)Buffer)+1)
+   {
+      delete [] Buffer;
+      return false;
+   }
+ 
    delete [] Buffer;
 
+   // Show the right description
+   pkgRecords Recs(*GCache);
+   pkgCache::DescIterator DescDefault = V.DescriptionList();
+   pkgCache::DescIterator Desc = DescDefault;
+   for (; Desc.end() == false; Desc++)
+      if (pkgIndexFile::LanguageCode() == Desc.LanguageCode())
+        break;
+   if (Desc.end() == true) Desc = DescDefault;
+
+   pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
+   cout << "Description" << ( (strcmp(Desc.LanguageCode(),"") != 0) ? "-" : "" ) << Desc.LanguageCode() << ": " << P.LongDesc() << endl; 
+
+
+
    return true;
 }
 									/*}}}*/
 // Search - Perform a search						/*{{{*/
 // ---------------------------------------------------------------------
 /* This searches the package names and pacakge descriptions for a pattern */
-struct ExVerFile
+struct ExDescFile
 {
-   pkgCache::VerFile *Vf;
+   pkgCache::DescFile *Df;
    bool NameMatch;
 };
 
@@ -1253,35 +1299,35 @@
       return false;
    }
    
-   ExVerFile *VFList = new ExVerFile[Cache.HeaderP->PackageCount+1];
-   memset(VFList,0,sizeof(*VFList)*Cache.HeaderP->PackageCount+1);
+   ExDescFile *DFList = new ExDescFile[Cache.HeaderP->PackageCount+1];
+   memset(DFList,0,sizeof(*DFList)*Cache.HeaderP->PackageCount+1);
 
    // Map versions that we want to write out onto the VerList array.
    for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
    {
-      VFList[P->ID].NameMatch = NumPatterns != 0;
+      DFList[P->ID].NameMatch = NumPatterns != 0;
       for (unsigned I = 0; I != NumPatterns; I++)
       {
 	 if (regexec(&Patterns[I],P.Name(),0,0,0) == 0)
-	    VFList[P->ID].NameMatch &= true;
+	    DFList[P->ID].NameMatch &= true;
 	 else
-	    VFList[P->ID].NameMatch = false;
+	    DFList[P->ID].NameMatch = false;
       }
         
       // Doing names only, drop any that dont match..
-      if (NamesOnly == true && VFList[P->ID].NameMatch == false)
+      if (NamesOnly == true && DFList[P->ID].NameMatch == false)
 	 continue;
 	 
       // Find the proper version to use. 
       pkgCache::VerIterator V = Plcy.GetCandidateVer(P);
       if (V.end() == false)
-	 VFList[P->ID].Vf = V.FileList();
+	 DFList[P->ID].Df = V.DescriptionList().FileList();
    }
       
    // Include all the packages that provide matching names too
    for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
    {
-      if (VFList[P->ID].NameMatch == false)
+      if (DFList[P->ID].NameMatch == false)
 	 continue;
 
       for (pkgCache::PrvIterator Prv = P.ProvidesList() ; Prv.end() == false; Prv++)
@@ -1289,18 +1335,18 @@
 	 pkgCache::VerIterator V = Plcy.GetCandidateVer(Prv.OwnerPkg());
 	 if (V.end() == false)
 	 {
-	    VFList[Prv.OwnerPkg()->ID].Vf = V.FileList();
-	    VFList[Prv.OwnerPkg()->ID].NameMatch = true;
+	    DFList[Prv.OwnerPkg()->ID].Df = V.DescriptionList().FileList();
+	    DFList[Prv.OwnerPkg()->ID].NameMatch = true;
 	 }
       }
    }
-
-   LocalitySort(&VFList->Vf,Cache.HeaderP->PackageCount,sizeof(*VFList));
+   
+   LocalitySort(&DFList->Df,Cache.HeaderP->PackageCount,sizeof(*DFList));
 
    // Iterate over all the version records and check them
-   for (ExVerFile *J = VFList; J->Vf != 0; J++)
+   for (ExDescFile *J = DFList; J->Df != 0; J++)
    {
-      pkgRecords::Parser &P = Recs.Lookup(pkgCache::VerFileIterator(Cache,J->Vf));
+      pkgRecords::Parser &P = Recs.Lookup(pkgCache::DescFileIterator(Cache,J->Df));
 
       bool Match = true;
       if (J->NameMatch == false)
@@ -1331,7 +1377,7 @@
       }
    }
    
-   delete [] VFList;
+   delete [] DFList;
    for (unsigned I = 0; I != NumPatterns; I++)
       regfree(&Patterns[I]);
    if (ferror(stdout))
Index: debian/changelog
===================================================================
RCS file: /cvs/deity/apt/debian/changelog,v
retrieving revision 1.443
diff -u -r1.443 changelog
--- debian/changelog	4 Aug 2004 14:03:11 -0000	1.443
+++ debian/changelog	11 Aug 2004 11:10:55 -0000
@@ -1,10 +1,3 @@
-apt (0.5.28) unstable; urgency=low
-
-  * Translation updates:
-    - Updated Hungarian from Kelemen Gábor <kelemeng@gnome.hu> (Closes: #263436)
-
- -- 
-
 apt (0.5.27) unstable; urgency=high
 
   * Sneak in a bunch of updated translations before the freeze

--- End Message ---
--- Begin Message ---
Version: 0.7.0

This has been include on a previous version of APT and then I'm
closing this bug report.

Thank you

-- 
        O T A V I O    S A L V A D O R
---------------------------------------------
 E-mail: otavio@debian.org      UIN: 5906116
 GNU/Linux User: 239058     GPG ID: 49A5F855
 Home Page: http://otavio.ossystems.com.br
---------------------------------------------
"Microsoft sells you Windows ... Linux gives
 you the whole house."


--- End Message ---

Reply to: