Hi, With the attached patch, APT searches in all available translations of package descriptions, which fixes the issue:
$ apt-cache search служба протокола системы | grep rsyslog rsyslog - гибкая служба ведения протокола работы системы и ядра $ apt-cache search system logging daemon | grep rsyslog rsyslog - гибкая служба ведения протокола работы системы и ядра $
From b827d6845f547ac123e3cbef58b86f57a5037373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B9=20=D0=A8=D0=B8?= =?UTF-8?q?=D0=BB=D0=B8=D0=BD?= <rootl...@mail.ru> Date: Tue, 17 Sep 2019 22:11:30 +0300 Subject: [PATCH] Search in all available description translations When multiple translations of package descriptions are available, perform search in all of them. It allows using search patterns in any of the configured languages. Previously, only the first available translation was searched. As the result, patterns in e.g. English never matched packages which had their descriptions translated into local language. Closes: #490000 --- apt-private/private-search.cc | 73 ++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 27 deletions(-) diff --git a/apt-private/private-search.cc b/apt-private/private-search.cc index de1b19758..7f7d2b343 100644 --- a/apt-private/private-search.cc +++ b/apt-private/private-search.cc @@ -94,27 +94,39 @@ static bool FullTextSearch(CommandLine &CmdL) /*{{{*/ if (PkgsDone[P->ID] == true) continue; - char const * const PkgName = P.Name(); - pkgCache::DescIterator Desc = V.TranslatedDescription(); - std::string LongDesc = ""; - if (Desc.end() == false) + std::vector<std::string> PkgDescriptions; + if (NamesOnly == false) { - pkgRecords::Parser &parser = records.Lookup(Desc.FileList()); - LongDesc = parser.LongDesc(); + for (auto Desc = V.TranslatedDescription(); Desc.end() == false; ++Desc) + { + pkgRecords::Parser &parser = records.Lookup(Desc.FileList()); + PkgDescriptions.push_back(parser.LongDesc()); + } } - bool all_found = true; - for (std::vector<regex_t>::const_iterator pattern = Patterns.begin(); - pattern != Patterns.end(); ++pattern) + bool all_found = false; + + char const * const PkgName = P.Name(); + for (std::string const &PkgDesc: PkgDescriptions) { - if (regexec(&(*pattern), PkgName, 0, 0, 0) == 0) - continue; - else if (NamesOnly == false && regexec(&(*pattern), LongDesc.c_str(), 0, 0, 0) == 0) - continue; - // search patterns are AND, so one failing fails all - all_found = false; - break; + all_found = true; + + for (std::vector<regex_t>::const_iterator pattern = Patterns.begin(); + pattern != Patterns.end(); ++pattern) + { + if (regexec(&(*pattern), PkgName, 0, 0, 0) == 0) + continue; + else if (NamesOnly == false && regexec(&(*pattern), PkgDesc.c_str(), 0, 0, 0) == 0) + continue; + // search patterns are AND, so one failing fails all + all_found = false; + break; + } + + if (all_found == true) + break; } + if (all_found == true) { PkgsDone[P->ID] = true; @@ -172,6 +184,7 @@ static void LocalitySort(pkgCache::DescFile ** const begin, unsigned long long c struct ExDescFile { pkgCache::DescFile *Df; + pkgCache::DescIterator D; pkgCache::VerIterator V; map_id_t ID; ExDescFile() : Df(nullptr), ID(0) {} @@ -254,6 +267,7 @@ static bool Search(CommandLine &CmdL) if (D.end() == true) continue; DFList[G->ID].Df = D.FileList(); + DFList[G->ID].D = D; DFList[G->ID].V = V; DFList[G->ID].ID = G->ID; } @@ -274,6 +288,7 @@ static bool Search(CommandLine &CmdL) if (D.end() == true) continue; DFList[id].Df = D.FileList(); + DFList[id].D = D; DFList[id].V = V; DFList[id].ID = id; @@ -290,19 +305,20 @@ static bool Search(CommandLine &CmdL) // Iterate over all the version records and check them for (ExDescFile *J = DFList; J->Df != 0; ++J) { - pkgRecords::Parser &P = Recs.Lookup(pkgCache::DescFileIterator(*Cache,J->Df)); size_t const PatternOffset = J->ID * NumPatterns; - if (NamesOnly == false) { - std::string const LongDesc = P.LongDesc(); - for (unsigned I = 0; I < NumPatterns; ++I) - { - if (PatternMatch[PatternOffset + I] == true) - continue; - else if (regexec(&Patterns[I],LongDesc.c_str(),0,0,0) == 0) - PatternMatch[PatternOffset + I] = true; - } + for (auto Desc = J->D; Desc.end() == false; ++Desc) + { + std::string const LongDesc = Recs.Lookup(Desc.FileList()).LongDesc(); + for (unsigned I = 0; I < NumPatterns; ++I) + { + if (PatternMatch[PatternOffset + I] == true) + continue; + else if (regexec(&Patterns[I], LongDesc.c_str(), 0, 0, 0) == 0) + PatternMatch[PatternOffset + I] = true; + } + } } bool matchedAll = true; @@ -325,7 +341,10 @@ static bool Search(CommandLine &CmdL) DisplayRecordV1(CacheFile, Recs, J->V, Vf, Start, Length, std::cout); } else - printf("%s - %s\n",P.Name().c_str(),P.ShortDesc().c_str()); + { + pkgRecords::Parser &P = Recs.Lookup(pkgCache::DescFileIterator(*Cache, J->Df)); + printf("%s - %s\n", P.Name().c_str(), P.ShortDesc().c_str()); + } } } -- 2.20.1