diff options
author | David Kalnischkies <kalnischkies@gmail.com> | 2009-11-26 22:23:08 +0100 |
---|---|---|
committer | David Kalnischkies <kalnischkies@gmail.com> | 2009-11-26 22:23:08 +0100 |
commit | 45df0ad2aab7d019cec855ba2cfe7ecdd0f8c7c8 (patch) | |
tree | f18787e135dcd7ea9444f93abc51c2a6516e2f7e | |
parent | 32e994d9c891ba379af7b292eeb81b4402d3f2af (diff) | |
download | apt-45df0ad2aab7d019cec855ba2cfe7ecdd0f8c7c8.tar.gz |
[BREAK] add possibility to download and use multiply
Translation files, configurable with Acquire::Languages
accessable with APT::Configuration::getLanguages() and
as always with documentation in apt.conf.
The commit also includes a very very simple testapp.
-rw-r--r-- | apt-pkg/aptconfiguration.cc | 136 | ||||
-rw-r--r-- | apt-pkg/aptconfiguration.h | 27 | ||||
-rw-r--r-- | apt-pkg/deb/debindexfile.cc | 29 | ||||
-rw-r--r-- | apt-pkg/deb/debindexfile.h | 5 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 17 | ||||
-rw-r--r-- | apt-pkg/deb/debmetaindex.cc | 17 | ||||
-rw-r--r-- | apt-pkg/deb/debrecords.cc | 12 | ||||
-rw-r--r-- | apt-pkg/indexfile.cc | 61 | ||||
-rw-r--r-- | apt-pkg/pkgcache.cc | 26 | ||||
-rw-r--r-- | debian/changelog | 2 | ||||
-rw-r--r-- | doc/apt.conf.5.xml | 24 | ||||
-rw-r--r-- | doc/examples/configure-index | 9 | ||||
-rw-r--r-- | test/libapt/getlanguages_test.cc | 91 | ||||
-rw-r--r-- | test/libapt/makefile | 13 |
14 files changed, 391 insertions, 78 deletions
diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 45ae9bed5..899004d9f 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -87,4 +87,140 @@ const Configuration::getCompressionTypes(bool const &Cached) { return types; } /*}}}*/ +// GetLanguages - Return Vector of Language Codes /*{{{*/ +// --------------------------------------------------------------------- +/* return a vector of language codes in the prefered order. + the special word "environment" will be replaced with the long and the short + code of the local settings and it will be insured that this will not add + duplicates. So in an german local the setting "environment, de_DE, en, de" + will result in "de_DE, de, en". + The special word "none" is the stopcode for the not-All code vector */ +std::vector<std::string> const Configuration::getLanguages(bool const &All, + bool const &Cached, char const * const Locale) { + using std::string; + + // The detection is boring and has a lot of cornercases, + // so we cache the results to calculated it only once. + std::vector<string> static allCodes; + std::vector<string> static codes; + + // we have something in the cache + if (codes.empty() == false || allCodes.empty() == false) { + if (Cached == true) { + if(All == true && allCodes.empty() == false) + return allCodes; + else + return codes; + } else { + allCodes.clear(); + codes.clear(); + } + } + + // get the environment language code + // we extract both, a long and a short code and then we will + // check if we actually need both (rare) or if the short is enough + string const envMsg = string(Locale == 0 ? std::setlocale(LC_MESSAGES, NULL) : Locale); + size_t const lenShort = (envMsg.find('_') != string::npos) ? envMsg.find('_') : 2; + size_t const lenLong = (envMsg.find('.') != string::npos) ? envMsg.find('.') : (lenShort + 3); + + string envLong = envMsg.substr(0,lenLong); + string const envShort = envLong.substr(0,lenShort); + bool envLongIncluded = true, envShortIncluded = false; + + // first cornercase: LANG=C, so we use only "en" Translation + if (envLong == "C") { + codes.push_back("en"); + return codes; + } + + if (envLong != envShort) { + // to save the servers from unneeded queries, we only try also long codes + // for languages it is realistic to have a long code translation file... + char const *needLong[] = { "cs", "en", "pt", "sv", "zh", NULL }; + for (char const **l = needLong; *l != NULL; l++) + if (envShort.compare(*l) == 0) { + envLongIncluded = false; + break; + } + } + + // we don't add the long code, but we allow the user to do so + if (envLongIncluded == true) + envLong.clear(); + + // FIXME: Remove support for the old APT::Acquire::Translation + // it was undocumented and so it should be not very widthly used + string const oldAcquire = _config->Find("APT::Acquire::Translation",""); + if (oldAcquire.empty() == false && oldAcquire != "environment") { + if (oldAcquire != "none") + codes.push_back(oldAcquire); + return codes; + } + + // Support settings like Acquire::Translation=none on the command line to + // override the configuration settings vector of languages. + string const forceLang = _config->Find("Acquire::Languages",""); + if (forceLang.empty() == false) { + if (forceLang == "environment") { + if (envLongIncluded == false) + codes.push_back(envLong); + if (envShortIncluded == false) + codes.push_back(envShort); + return codes; + } else if (forceLang != "none") + codes.push_back(forceLang); + return codes; + } + + std::vector<string> const lang = _config->FindVector("Acquire::Languages"); + // the default setting -> "environment, en" + if (lang.empty() == true) { + if (envLongIncluded == false) + codes.push_back(envLong); + if (envShortIncluded == false) + codes.push_back(envShort); + if (envShort != "en") + codes.push_back("en"); + return codes; + } + + // the configs define the order, so add the environment + // then needed and ensure the codes are not listed twice. + bool noneSeen = false; + for (std::vector<string>::const_iterator l = lang.begin(); + l != lang.end(); l++) { + if (*l == "environment") { + if (envLongIncluded == true && envShortIncluded == true) + continue; + if (envLongIncluded == false) { + envLongIncluded = true; + if (noneSeen == false) + codes.push_back(envLong); + allCodes.push_back(envLong); + } + if (envShortIncluded == false) { + envShortIncluded = true; + if (noneSeen == false) + codes.push_back(envShort); + allCodes.push_back(envShort); + } + continue; + } else if (*l == "none") { + noneSeen = true; + continue; + } else if ((envLongIncluded == true && *l == envLong) || + (envShortIncluded == true && *l == envShort)) + continue; + + if (noneSeen == false) + codes.push_back(*l); + allCodes.push_back(*l); + } + if (All == true) + return allCodes; + else + return codes; +} + /*}}}*/ } diff --git a/apt-pkg/aptconfiguration.h b/apt-pkg/aptconfiguration.h index 6a123adce..f2f04a39b 100644 --- a/apt-pkg/aptconfiguration.h +++ b/apt-pkg/aptconfiguration.h @@ -39,6 +39,33 @@ public: /*{{{*/ * \return a vector of (all) Language Codes in the prefered usage order */ std::vector<std::string> static const getCompressionTypes(bool const &Cached = true); + + /** \brief Returns a vector of Language Codes + * + * Languages can be defined with their two or five chars long code. + * This methods handles the various ways to set the prefered codes, + * honors the environment and ensures that the codes are not listed twice. + * + * The special word "environment" will be replaced with the long and the short + * code of the local settings and it will be insured that this will not add + * duplicates. So in an german local the setting "environment, de_DE, en, de" + * will result in "de_DE, de, en". + * + * Another special word is "none" which separates the prefered from all codes + * in this setting. So setting and method can be used to get codes the user want + * to see or to get all language codes APT (should) have Translations available. + * + * \param All return all codes or only codes for languages we want to use + * \param Cached saves the result so we need to calculated it only once + * this parameter should ony be used for testing purposes. + * \param Locale don't get the locale from the system but use this one instead + * this parameter should ony be used for testing purposes. + * + * \return a vector of (all) Language Codes in the prefered usage order + */ + std::vector<std::string> static const getLanguages(bool const &All = false, + bool const &Cached = true, char const * const Locale = 0); + /*}}}*/ }; /*}}}*/ diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index ed7633803..5beb83665 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -319,10 +319,11 @@ pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const // TranslationsIndex::debTranslationsIndex - Contructor /*{{{*/ // --------------------------------------------------------------------- /* */ -debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section) : - pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section) -{ -} +debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section, + char const * const Translation) : + pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section), + Language(Translation) +{} /*}}}*/ // TranslationIndex::Trans* - Return the URI to the translation files /*{{{*/ // --------------------------------------------------------------------- @@ -355,8 +356,8 @@ string debTranslationsIndex::IndexURI(const char *Type) const bool debTranslationsIndex::GetIndexes(pkgAcquire *Owner) const { if (TranslationsAvailable()) { - string TranslationFile = "Translation-" + LanguageCode(); - new pkgAcqIndexTrans(Owner, IndexURI(LanguageCode().c_str()), + string const TranslationFile = string("Translation-").append(Language); + new pkgAcqIndexTrans(Owner, IndexURI(Language), Info(TranslationFile.c_str()), TranslationFile); } @@ -375,7 +376,7 @@ string debTranslationsIndex::Describe(bool Short) const 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()); + IndexFile(Language).c_str()); return S; } /*}}}*/ @@ -397,20 +398,20 @@ string debTranslationsIndex::Info(const char *Type) const return Info; } /*}}}*/ -bool debTranslationsIndex::HasPackages() const +bool debTranslationsIndex::HasPackages() const /*{{{*/ { if(!TranslationsAvailable()) return false; - return FileExists(IndexFile(LanguageCode().c_str())); + return FileExists(IndexFile(Language)); } - + /*}}}*/ // TranslationsIndex::Exists - Check if the index is available /*{{{*/ // --------------------------------------------------------------------- /* */ bool debTranslationsIndex::Exists() const { - return FileExists(IndexFile(LanguageCode().c_str())); + return FileExists(IndexFile(Language)); } /*}}}*/ // TranslationsIndex::Size - Return the size of the index /*{{{*/ @@ -419,7 +420,7 @@ bool debTranslationsIndex::Exists() const unsigned long debTranslationsIndex::Size() const { struct stat S; - if (stat(IndexFile(LanguageCode().c_str()).c_str(),&S) != 0) + if (stat(IndexFile(Language).c_str(),&S) != 0) return 0; return S.st_size; } @@ -430,7 +431,7 @@ unsigned long debTranslationsIndex::Size() const bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const { // Check the translation file, if in use - string TranslationFile = IndexFile(LanguageCode().c_str()); + string TranslationFile = IndexFile(Language); if (TranslationsAvailable() && FileExists(TranslationFile)) { FileFd Trans(TranslationFile,FileFd::ReadOnly); @@ -462,7 +463,7 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const /* */ pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const { - string FileName = IndexFile(LanguageCode().c_str()); + string FileName = IndexFile(Language); pkgCache::PkgFileIterator File = Cache.FileBegin(); for (; File.end() == false; File++) diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index b0012c96b..c0e8d7d8e 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -77,12 +77,13 @@ class debTranslationsIndex : public pkgIndexFile string URI; string Dist; string Section; + const char * const Language; 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();}; + inline string TranslationFile() const {return string("Translation-").append(Language);}; public: @@ -99,7 +100,7 @@ class debTranslationsIndex : public pkgIndexFile virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; - debTranslationsIndex(string URI,string Dist,string Section); + debTranslationsIndex(string URI,string Dist,string Section, char const * const Language); }; class debSourcesIndex : public pkgIndexFile diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 517b771a5..16e6ee332 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -13,6 +13,7 @@ #include <apt-pkg/deblistparser.h> #include <apt-pkg/error.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/aptconfiguration.h> #include <apt-pkg/strutl.h> #include <apt-pkg/crc-16.h> #include <apt-pkg/md5.h> @@ -129,10 +130,11 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver) only describe package properties */ string debListParser::Description() { - if (DescriptionLanguage().empty()) + string const lang = DescriptionLanguage(); + if (lang.empty()) return Section.FindS("Description"); else - return Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str()); + return Section.FindS(string("Description-").append(lang).c_str()); } /*}}}*/ // ListParser::DescriptionLanguage - Return the description lang string /*{{{*/ @@ -142,7 +144,16 @@ string debListParser::Description() assumed to describe original description. */ string debListParser::DescriptionLanguage() { - return Section.FindS("Description").empty() ? pkgIndexFile::LanguageCode() : ""; + if (Section.FindS("Description").empty() == false) + return ""; + + std::vector<string> const lang = APT::Configuration::getLanguages(); + for (std::vector<string>::const_iterator l = lang.begin(); + l != lang.end(); l++) + if (Section.FindS(string("Description-").append(*l).c_str()).empty() == false) + return *l; + + return ""; } /*}}}*/ // ListParser::Description - Return the description_md5 MD5SumValue /*{{{*/ diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index f3ab6960c..8f28f053b 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -5,6 +5,7 @@ #include <apt-pkg/strutl.h> #include <apt-pkg/acquire-item.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/aptconfiguration.h> #include <apt-pkg/error.h> using namespace std; @@ -170,13 +171,19 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const new indexRecords (Dist)); // Queue the translations + std::vector<std::string> const lang = APT::Configuration::getLanguages(true); for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin(); I != SectionEntries.end(); I++) { if((*I)->IsSrc) continue; - debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section); - i.GetIndexes(Owner); + + for (vector<string>::const_iterator l = lang.begin(); + l != lang.end(); l++) + { + debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str()); + i.GetIndexes(Owner); + } } return true; @@ -202,6 +209,7 @@ vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() return Indexes; Indexes = new vector <pkgIndexFile*>; + std::vector<std::string> const lang = APT::Configuration::getLanguages(true); for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin(); I != SectionEntries.end(); I++) { if ((*I)->IsSrc) @@ -209,7 +217,10 @@ vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() else { Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted())); - Indexes->push_back(new debTranslationsIndex(URI, Dist, (*I)->Section)); + + for (vector<string>::const_iterator l = lang.begin(); + l != lang.end(); l++) + Indexes->push_back(new debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str())); } } diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index 8ed0bb7eb..5b8538a46 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -11,6 +11,7 @@ #include <apt-pkg/debrecords.h> #include <apt-pkg/strutl.h> #include <apt-pkg/error.h> +#include <apt-pkg/aptconfiguration.h> #include <langinfo.h> /*}}}*/ @@ -109,13 +110,18 @@ string debRecordParser::ShortDesc() string debRecordParser::LongDesc() { 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(); + else + { + vector<string> const lang = APT::Configuration::getLanguages(); + for (vector<string>::const_iterator l = lang.begin(); + orig.empty() && l != lang.end(); l++) + orig = Section.FindS(string("Description-").append(*l).c_str()); + } + char const * const codeset = nl_langinfo(CODESET); if (strcmp(codeset,"UTF-8") != 0) { UTF8ToCodeset(codeset, orig, &dest); orig = dest; diff --git a/apt-pkg/indexfile.cc b/apt-pkg/indexfile.cc index 08f71feb0..37be87055 100644 --- a/apt-pkg/indexfile.cc +++ b/apt-pkg/indexfile.cc @@ -8,9 +8,9 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#include <apt-pkg/configuration.h> #include <apt-pkg/indexfile.h> #include <apt-pkg/error.h> +#include <apt-pkg/aptconfiguration.h> #include <clocale> #include <cstring> @@ -66,28 +66,20 @@ string pkgIndexFile::SourceInfo(pkgSrcRecords::Parser const &Record, return string(); } /*}}}*/ -// IndexFile::TranslationsAvailable - Check if will use Translation /*{{{*/ +// IndexFile::TranslationsAvailable - Check if will use Translation /*{{{*/ // --------------------------------------------------------------------- /* */ -bool pkgIndexFile::TranslationsAvailable() -{ - const string Translation = _config->Find("APT::Acquire::Translation"); - - if (Translation.compare("none") != 0) - return CheckLanguageCode(LanguageCode().c_str()); - else - return false; +bool pkgIndexFile::TranslationsAvailable() { + return (APT::Configuration::getLanguages().empty() != true); } /*}}}*/ -// IndexFile::CheckLanguageCode - Check the Language Code /*{{{*/ +// IndexFile::CheckLanguageCode - Check the Language Code /*{{{*/ // --------------------------------------------------------------------- -/* */ -/* common cases: de_DE, de_DE@euro, de_DE.UTF-8, de_DE.UTF-8@euro, - de_DE.ISO8859-1, tig_ER - more in /etc/gdm/locale.conf -*/ - -bool pkgIndexFile::CheckLanguageCode(const char *Lang) +/* No intern need for this method anymore as the check for correctness + is already done in getLanguages(). Note also that this check is + rather bad (doesn't take three character like ast into account). + TODO: Remove method with next API break */ +__attribute__ ((deprecated)) bool pkgIndexFile::CheckLanguageCode(const char *Lang) { if (strlen(Lang) == 2 || (strlen(Lang) == 5 && Lang[2] == '_')) return true; @@ -98,31 +90,14 @@ bool pkgIndexFile::CheckLanguageCode(const char *Lang) return false; } /*}}}*/ -// IndexFile::LanguageCode - Return the Language Code /*{{{*/ +// IndexFile::LanguageCode - Return the Language Code /*{{{*/ // --------------------------------------------------------------------- -/* return the language code */ -string pkgIndexFile::LanguageCode() -{ - const string Translation = _config->Find("APT::Acquire::Translation"); - - if (Translation.compare("environment") == 0) - { - string lang = std::setlocale(LC_MESSAGES,NULL); - - // we have a mapping of the language codes that contains all the language - // codes that need the country code as well - // (like pt_BR, pt_PT, sv_SE, zh_*, en_*) - const char *need_full_langcode[] = { "pt","sv","zh","en", NULL }; - for(const char **s = need_full_langcode;*s != NULL; s++) - if(lang.find(*s) == 0) - return lang.substr(0,5); - - if(lang.size() > 2) - return lang.substr(0,2); - else - return lang; - } - else - return Translation; +/* As we have now possibly more than one LanguageCode this method is + supersided by a) private classmembers or b) getLanguages(). + TODO: Remove method with next API break */ +__attribute__ ((deprecated)) string pkgIndexFile::LanguageCode() { + if (TranslationsAvailable() == false) + return ""; + return APT::Configuration::getLanguages()[0]; } /*}}}*/ diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index b0ce6e598..997ff51fe 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -22,11 +22,11 @@ // Include Files /*{{{*/ #include <apt-pkg/pkgcache.h> #include <apt-pkg/policy.h> -#include <apt-pkg/indexfile.h> #include <apt-pkg/version.h> #include <apt-pkg/error.h> #include <apt-pkg/strutl.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/aptconfiguration.h> #include <apti18n.h> @@ -674,14 +674,22 @@ string pkgCache::PkgFileIterator::RelStr() */ pkgCache::DescIterator pkgCache::VerIterator::TranslatedDescription() const { - pkgCache::DescIterator DescDefault = DescriptionList(); - pkgCache::DescIterator Desc = DescDefault; - for (; Desc.end() == false; Desc++) - if (pkgIndexFile::LanguageCode() == Desc.LanguageCode()) - break; - if (Desc.end() == true) - Desc = DescDefault; - return Desc; + std::vector<string> const lang = APT::Configuration::getLanguages(); + for (std::vector<string>::const_iterator l = lang.begin(); + l != lang.end(); l++) + { + pkgCache::DescIterator DescDefault = DescriptionList(); + pkgCache::DescIterator Desc = DescDefault; + + for (; Desc.end() == false; Desc++) + if (*l == Desc.LanguageCode()) + break; + if (Desc.end() == true) + Desc = DescDefault; + return Desc; + } + + return DescriptionList(); }; /*}}}*/ diff --git a/debian/changelog b/debian/changelog index 0cfb5ff30..07d9c0303 100644 --- a/debian/changelog +++ b/debian/changelog @@ -17,6 +17,8 @@ apt (0.7.25) UNRELEASED; urgency=low Closes: #552606 [ David Kalnischkies ] + * [BREAK] add possibility to download and use multiply + Translation files, configurable with Acquire::Translation * apt-pkg/packagemanager.cc: - better debug output for ImmediateAdd with depth and why - improve the message shown for failing immediate configuration diff --git a/doc/apt.conf.5.xml b/doc/apt.conf.5.xml index d7ad51cfb..777630e14 100644 --- a/doc/apt.conf.5.xml +++ b/doc/apt.conf.5.xml @@ -142,7 +142,7 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";}; <listitem><para>Default release to install packages from if more than one version available. Contains release name, codename or release version. Examples: 'stable', 'testing', 'unstable', 'lenny', 'squeeze', '4.0', '5.0*'. See also &apt-preferences;.</para></listitem> </varlistentry> - + <varlistentry><term>Ignore-Hold</term> <listitem><para>Ignore Held packages; This global option causes the problem resolver to ignore held packages in its decision making.</para></listitem> @@ -392,6 +392,27 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";}; these warnings are most of the time false negatives. Future versions will maybe include a way to really prefer uncompressed files to support the usage of local mirrors.</para></listitem> </varlistentry> + + <varlistentry><term>Languages</term> + <listitem><para>The Languages subsection controls which <filename>Translation</filename> files are downloaded + and in which order APT tries to display the Description-Translations. APT will try to display the first + available Description for the Language which is listed at first. Languages can be defined with their + short or long Languagecodes. Note that not all archives provide <filename>Translation</filename> + files for every Language - especially the long Languagecodes are rare, so please + inform you which ones are available before you set here impossible values.</para> + <para>The default list includes "environment" and "en". "<literal>environment</literal>" has a special meaning here: + It will be replaced at runtime with the languagecodes extracted from the <literal>LC_MESSAGES</literal> enviroment variable. + It will also ensure that these codes are not included twice in the list. If <literal>LC_MESSAGES</literal> + is set to "C" only the <filename>Translation-en</filename> file (if available) will be used. + To force apt to use no Translation file use the setting <literal>Acquire::Languages=none</literal>. "<literal>none</literal>" + is another special meaning code which will stop the search for a fitting <filename>Translation</filename> file. + This can be used by the system administrator to let APT know that it should download also this files without + actually use them if not the environment specifies this languages. So the following example configuration will + result in the order "en, de" in an english and in "de, en" in a german localization. Note that "fr" is downloaded, + but not used if APT is not used in a french localization, in such an environment the order would be "fr, de, en". + <programlisting>Acquire::Languages { "environment"; "de"; "en"; "none"; "fr"; };</programlisting></para></listitem> + </varlistentry> + </variablelist> </para> </refsect1> @@ -983,6 +1004,7 @@ is commented. </listitem> </varlistentry> --> + </variablelist> </refsect1> diff --git a/doc/examples/configure-index b/doc/examples/configure-index index 7e86b3d4a..05826feaa 100644 --- a/doc/examples/configure-index +++ b/doc/examples/configure-index @@ -273,6 +273,15 @@ Acquire Order { "gz"; "lzma"; "bz2"; }; }; + + Languages + { + "environment"; + "de"; + "en"; + "none"; + "fr"; + }; }; // Directory layout diff --git a/test/libapt/getlanguages_test.cc b/test/libapt/getlanguages_test.cc new file mode 100644 index 000000000..f3629df68 --- /dev/null +++ b/test/libapt/getlanguages_test.cc @@ -0,0 +1,91 @@ +#include <apt-pkg/aptconfiguration.h> +#include <apt-pkg/configuration.h> + +#include <assert.h> +#include <string> +#include <vector> + +#include <iostream> + +// simple helper to quickly output a vector of strings +void dumpVector(std::vector<std::string> vec) { + for (std::vector<std::string>::const_iterator v = vec.begin(); + v != vec.end(); v++) + std::cout << *v << std::endl; +} + +int main(int argc,char *argv[]) +{ + std::vector<std::string> vec = APT::Configuration::getLanguages(false, false, "de_DE.UTF-8"); + assert(vec.size() == 2); + assert(vec[0] == "de"); + assert(vec[1] == "en"); + + // Special: Check if the cache is actually in use + vec = APT::Configuration::getLanguages(false, true, "en_GB.UTF-8"); + assert(vec.size() == 2); + assert(vec[0] == "de"); + assert(vec[1] == "en"); + + vec = APT::Configuration::getLanguages(false, false, "en_GB.UTF-8"); + assert(vec.size() == 2); + assert(vec[0] == "en_GB"); + assert(vec[1] == "en"); + + vec = APT::Configuration::getLanguages(false, false, "pt_PR.UTF-8"); + assert(vec.size() == 3); + assert(vec[0] == "pt_PR"); + assert(vec[1] == "pt"); + assert(vec[2] == "en"); + + vec = APT::Configuration::getLanguages(false, false, "ast_DE.UTF-8"); // bogus, but syntactical correct + assert(vec.size() == 2); + assert(vec[0] == "ast"); + assert(vec[1] == "en"); + + vec = APT::Configuration::getLanguages(false, false, "C"); + assert(vec.size() == 1); + assert(vec[0] == "en"); + + _config->Set("Acquire::Languages::1", "environment"); + _config->Set("Acquire::Languages::2", "en"); + vec = APT::Configuration::getLanguages(false, false, "de_DE.UTF-8"); + assert(vec.size() == 2); + assert(vec[0] == "de"); + assert(vec[1] == "en"); + + _config->Set("Acquire::Languages::3", "de"); + vec = APT::Configuration::getLanguages(false, false, "de_DE.UTF-8"); + assert(vec.size() == 2); + assert(vec[0] == "de"); + assert(vec[1] == "en"); + + _config->Set("Acquire::Languages::1", "none"); + vec = APT::Configuration::getLanguages(false, false, "de_DE.UTF-8"); + assert(vec.size() == 0); + vec = APT::Configuration::getLanguages(true, false, "de_DE.UTF-8"); + assert(vec[0] == "en"); + assert(vec[1] == "de"); + + _config->Set("Acquire::Languages::1", "fr"); + _config->Set("Acquire::Languages", "de_DE"); + vec = APT::Configuration::getLanguages(false, false, "de_DE.UTF-8"); + assert(vec.size() == 1); + assert(vec[0] == "de_DE"); + + _config->Set("Acquire::Languages", "none"); + vec = APT::Configuration::getLanguages(true, false, "de_DE.UTF-8"); + assert(vec.size() == 0); + + _config->Set("Acquire::Languages", ""); + //FIXME: Remove support for this deprecated setting + _config->Set("APT::Acquire::Translation", "ast_DE"); + vec = APT::Configuration::getLanguages(true, false, "de_DE.UTF-8"); + assert(vec.size() == 1); + assert(vec[0] == "ast_DE"); + _config->Set("APT::Acquire::Translation", "none"); + vec = APT::Configuration::getLanguages(true, false, "de_DE.UTF-8"); + assert(vec.size() == 0); + + return 0; +} diff --git a/test/libapt/makefile b/test/libapt/makefile new file mode 100644 index 000000000..f61a95f3d --- /dev/null +++ b/test/libapt/makefile @@ -0,0 +1,13 @@ +# -*- make -*- +BASE=../.. +SUBDIR=test/libapt +BASENAME=_libapt_test + +# Bring in the default rules +include ../../buildlib/defaults.mak + +# Program for testing getLanguageCode +PROGRAM = getLanguages${BASENAME} +SLIBS = -lapt-pkg +SOURCE = getlanguages_test.cc +include $(PROGRAM_H) |