X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/d39d7f885d61bfe296c131c83bdc042a2ab6b0d7..98cc7fd2c1d397623960baf69ae3cec04a87a23e:/apt-private/private-output.cc diff --git a/apt-private/private-output.cc b/apt-private/private-output.cc index 158bd5c71..b8e6dec02 100644 --- a/apt-private/private-output.cc +++ b/apt-private/private-output.cc @@ -25,6 +25,8 @@ #include <signal.h> #include <sys/ioctl.h> +#include <sstream> + #include <apti18n.h> /*}}}*/ @@ -52,14 +54,14 @@ static void SigWinch(int) #endif } /*}}}*/ -bool InitOutput() /*{{{*/ +bool InitOutput(std::basic_streambuf<char> * const out) /*{{{*/ { if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1) _config->Set("quiet","1"); - c0out.rdbuf(cout.rdbuf()); - c1out.rdbuf(cout.rdbuf()); - c2out.rdbuf(cout.rdbuf()); + c0out.rdbuf(out); + c1out.rdbuf(out); + c2out.rdbuf(out); if (_config->FindI("quiet",0) > 0) c0out.rdbuf(devnull.rdbuf()); if (_config->FindI("quiet",0) > 1) @@ -118,7 +120,7 @@ static std::string GetFlagsStr(pkgCacheFile &CacheFile, pkgCache::PkgIterator P) std::string flags_str; if (state.NowBroken()) flags_str = "B"; - if (P.CurrentVer() && state.Upgradable()) + if (P.CurrentVer() && state.Upgradable() && state.CandidateVer != NULL) flags_str = "g"; else if (P.CurrentVer() != NULL) flags_str = "i"; @@ -164,15 +166,26 @@ static std::string GetVersion(pkgCacheFile &/*CacheFile*/, pkgCache::VerIterator /*}}}*/ static std::string GetArchitecture(pkgCacheFile &CacheFile, pkgCache::PkgIterator P)/*{{{*/ { - pkgPolicy *policy = CacheFile.GetPolicy(); - pkgCache::VerIterator inst = P.CurrentVer(); - pkgCache::VerIterator cand = policy->GetCandidateVer(P); - - // this may happen for packages in dpkg "deinstall ok config-file" state - if (inst.IsGood() == false && cand.IsGood() == false) - return P.VersionList().Arch(); - - return inst ? inst.Arch() : cand.Arch(); + if (P->CurrentVer == 0) + { + pkgDepCache * const DepCache = CacheFile.GetDepCache(); + pkgDepCache::StateCache const &state = (*DepCache)[P]; + if (state.CandidateVer != NULL) + { + pkgCache::VerIterator const CandV(CacheFile, state.CandidateVer); + return CandV.Arch(); + } + else + { + pkgCache::VerIterator const V = P.VersionList(); + if (V.end() == false) + return V.Arch(); + else + return P.Arch(); + } + } + else + return P.CurrentVer().Arch(); } /*}}}*/ static std::string GetShortDescription(pkgCacheFile &CacheFile, pkgRecords &records, pkgCache::PkgIterator P)/*{{{*/ @@ -188,148 +201,103 @@ static std::string GetShortDescription(pkgCacheFile &CacheFile, pkgRecords &reco std::string ShortDescription = "(none)"; if(ver) { - pkgCache::DescIterator Desc = ver.TranslatedDescription(); - pkgRecords::Parser & parser = records.Lookup(Desc.FileList()); - - ShortDescription = parser.ShortDesc(); + pkgCache::DescIterator const Desc = ver.TranslatedDescription(); + if (Desc.end() == false) + { + pkgRecords::Parser & parser = records.Lookup(Desc.FileList()); + ShortDescription = parser.ShortDesc(); + } } return ShortDescription; } /*}}}*/ -void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records, /*{{{*/ - pkgCache::VerIterator V, std::ostream &out, - bool include_summary) +static std::string GetLongDescription(pkgCacheFile &CacheFile, pkgRecords &records, pkgCache::PkgIterator P)/*{{{*/ { - pkgCache::PkgIterator P = V.ParentPkg(); + pkgPolicy *policy = CacheFile.GetPolicy(); - pkgDepCache *DepCache = CacheFile.GetDepCache(); - pkgDepCache::StateCache &state = (*DepCache)[P]; + pkgCache::VerIterator ver; + if (P->CurrentVer != 0) + ver = P.CurrentVer(); + else + ver = policy->GetCandidateVer(P); - std::string suite = GetArchiveSuite(CacheFile, V); - std::string name_str = P.Name(); + std::string const EmptyDescription = "(none)"; + if(ver.end() == true) + return EmptyDescription; - if (_config->FindB("APT::Cmd::use-format", false)) + pkgCache::DescIterator const Desc = ver.TranslatedDescription(); + if (Desc.end() == false) { - std::string format = _config->Find("APT::Cmd::format", "${db::Status-Abbrev} ${Package} ${Version} ${Origin} ${Description}"); - std::string output = format; - - output = SubstVar(output, "${db::Status-Abbrev}", GetFlagsStr(CacheFile, P)); - output = SubstVar(output, "${Package}", name_str); - output = SubstVar(output, "${installed:Version}", GetInstalledVersion(CacheFile, P)); - output = SubstVar(output, "${candidate:Version}", GetCandidateVersion(CacheFile, P)); - output = SubstVar(output, "${Version}", GetVersion(CacheFile, V)); - output = SubstVar(output, "${Description}", GetShortDescription(CacheFile, records, P)); - output = SubstVar(output, "${Origin}", GetArchiveSuite(CacheFile, V)); - out << output << std::endl; - } else { - // raring/linux-kernel version [upradable: new-version] - // description - pkgPolicy *policy = CacheFile.GetPolicy(); - std::string VersionStr = GetVersion(CacheFile, V); - std::string CandidateVerStr = GetCandidateVersion(CacheFile, P); - std::string InstalledVerStr = GetInstalledVersion(CacheFile, P); - std::string StatusStr; - if(P.CurrentVer() == V && state.Upgradable()) { - strprintf(StatusStr, _("[installed,upgradable to: %s]"), - CandidateVerStr.c_str()); - } else if (P.CurrentVer() == V) { - if(!V.Downloadable()) - StatusStr = _("[installed,local]"); - else - if(V.Automatic() && state.Garbage) - StatusStr = _("[installed,auto-removable]"); - else if (state.Flags & pkgCache::Flag::Auto) - StatusStr = _("[installed,automatic]"); - else - StatusStr = _("[installed]"); - } else if (P.CurrentVer() && - policy->GetCandidateVer(P) == V && - state.Upgradable()) { - strprintf(StatusStr, _("[upgradable from: %s]"), - InstalledVerStr.c_str()); - } else { - if (V.ParentPkg()->CurrentState == pkgCache::State::ConfigFiles) - StatusStr = _("[residual-config]"); - else - StatusStr = ""; - } - out << std::setiosflags(std::ios::left) - << _config->Find("APT::Color::Highlight", "") - << name_str - << _config->Find("APT::Color::Neutral", "") - << "/" << suite - << " " - << VersionStr << " " - << GetArchitecture(CacheFile, P); - if (StatusStr != "") - out << " " << StatusStr; - if (include_summary) - { - out << std::endl - << " " << GetShortDescription(CacheFile, records, P) - << std::endl; - } + pkgRecords::Parser & parser = records.Lookup(Desc.FileList()); + std::string const longdesc = parser.LongDesc(); + if (longdesc.empty() == false) + return SubstVar(longdesc, "\n ", "\n "); } + return EmptyDescription; } /*}}}*/ -// ShowList - Show a list /*{{{*/ -// --------------------------------------------------------------------- -/* This prints out a string of space separated words with a title and - a two space indent line wraped to the current screen width. */ -bool ShowList(ostream &out,string Title,string List,string VersionsList) +void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records, /*{{{*/ + pkgCache::VerIterator const &V, std::ostream &out, + std::string const &format) { - if (List.empty() == true) - return true; - // trim trailing space - int NonSpace = List.find_last_not_of(' '); - if (NonSpace != -1) - { - List = List.erase(NonSpace + 1); - if (List.empty() == true) - return true; - } + pkgCache::PkgIterator const P = V.ParentPkg(); + pkgDepCache * const DepCache = CacheFile.GetDepCache(); + pkgDepCache::StateCache const &state = (*DepCache)[P]; - // Acount for the leading space - int ScreenWidth = ::ScreenWidth - 3; - - out << Title << endl; - string::size_type Start = 0; - string::size_type VersionsStart = 0; - while (Start < List.size()) + std::string output; + if (_config->FindB("APT::Cmd::use-format", false)) + output = _config->Find("APT::Cmd::format", "${db::Status-Abbrev} ${Package} ${Version} ${Origin} ${Description}"); + else + output = format; + + // FIXME: some of these names are really icky â and all is nowhere documented + output = SubstVar(output, "${db::Status-Abbrev}", GetFlagsStr(CacheFile, P)); + output = SubstVar(output, "${Package}", P.Name()); + std::string const ArchStr = GetArchitecture(CacheFile, P); + output = SubstVar(output, "${Architecture}", ArchStr); + std::string const InstalledVerStr = GetInstalledVersion(CacheFile, P); + output = SubstVar(output, "${installed:Version}", InstalledVerStr); + std::string const CandidateVerStr = GetCandidateVersion(CacheFile, P); + output = SubstVar(output, "${candidate:Version}", CandidateVerStr); + std::string const VersionStr = GetVersion(CacheFile, V); + output = SubstVar(output, "${Version}", VersionStr); + output = SubstVar(output, "${Origin}", GetArchiveSuite(CacheFile, V)); + + std::string StatusStr = ""; + if (P->CurrentVer != 0) { - if(_config->FindB("APT::Get::Show-Versions",false) == true && - VersionsList.size() > 0) { - string::size_type End; - string::size_type VersionsEnd; - - End = List.find(' ',Start); - VersionsEnd = VersionsList.find('\n', VersionsStart); - - out << " " << string(List,Start,End - Start) << " (" << - string(VersionsList,VersionsStart,VersionsEnd - VersionsStart) << - ")" << endl; - - if (End == string::npos || End < Start) - End = Start + ScreenWidth; - - Start = End + 1; - VersionsStart = VersionsEnd + 1; - } else { - string::size_type End; - - if (Start + ScreenWidth >= List.size()) - End = List.size(); - else - End = List.rfind(' ',Start+ScreenWidth); - - if (End == string::npos || End < Start) - End = Start + ScreenWidth; - out << " " << string(List,Start,End - Start) << endl; - Start = End + 1; + if (P.CurrentVer() == V) + { + if (state.Upgradable() && state.CandidateVer != NULL) + strprintf(StatusStr, _("[installed,upgradable to: %s]"), + CandidateVerStr.c_str()); + else if (V.Downloadable() == false) + StatusStr = _("[installed,local]"); + else if(V.Automatic() == true && state.Garbage == true) + StatusStr = _("[installed,auto-removable]"); + else if ((state.Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) + StatusStr = _("[installed,automatic]"); + else + StatusStr = _("[installed]"); } - } - - return false; + else if (state.CandidateVer == V && state.Upgradable()) + strprintf(StatusStr, _("[upgradable from: %s]"), + InstalledVerStr.c_str()); + } + else if (V.ParentPkg()->CurrentState == pkgCache::State::ConfigFiles) + StatusStr = _("[residual-config]"); + output = SubstVar(output, "${apt:Status}", StatusStr); + output = SubstVar(output, "${color:highlight}", _config->Find("APT::Color::Highlight", "")); + output = SubstVar(output, "${color:neutral}", _config->Find("APT::Color::Neutral", "")); + output = SubstVar(output, "${Description}", GetShortDescription(CacheFile, records, P)); + output = SubstVar(output, "${LongDescription}", GetLongDescription(CacheFile, records, P)); + output = SubstVar(output, "${ }${ }", "${ }"); + output = SubstVar(output, "${ }\n", "\n"); + output = SubstVar(output, "${ }", " "); + if (APT::String::Endswith(output, " ") == true) + output.erase(output.length() - 1); + + out << output; } /*}}}*/ // ShowBroken - Debugging aide /*{{{*/ @@ -465,11 +433,9 @@ void ShowBroken(ostream &out, CacheFile &Cache, bool const Now) return; out << _("The following packages have unmet dependencies:") << endl; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator const I(Cache,Cache.List[J]); - ShowBrokenPackage(out, &Cache, I, Now); - } + SortedPackageUniverse Universe(Cache); + for (auto const &Pkg: Universe) + ShowBrokenPackage(out, &Cache, Pkg, Now); } void ShowBroken(ostream &out, pkgCacheFile &Cache, bool const Now) { @@ -477,98 +443,64 @@ void ShowBroken(ostream &out, pkgCacheFile &Cache, bool const Now) return; out << _("The following packages have unmet dependencies:") << endl; - for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg) + APT::PackageUniverse Universe(Cache); + for (auto const &Pkg: Universe) ShowBrokenPackage(out, &Cache, Pkg, Now); } /*}}}*/ // ShowNew - Show packages to newly install /*{{{*/ -// --------------------------------------------------------------------- -/* */ void ShowNew(ostream &out,CacheFile &Cache) { - /* Print out a list of packages that are going to be installed extra - to what the user asked */ - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - if (Cache[I].NewInstall() == true) { - List += I.FullName(true) + " "; - VersionsList += string(Cache[I].CandVersion) + "\n"; - } - } - - ShowList(out,_("The following NEW packages will be installed:"),List,VersionsList); + SortedPackageUniverse Universe(Cache); + ShowList(out,_("The following NEW packages will be installed:"), Universe, + [&Cache](pkgCache::PkgIterator const &Pkg) { return Cache[Pkg].NewInstall(); }, + &PrettyFullName, + CandidateVersion(&Cache)); } /*}}}*/ // ShowDel - Show packages to delete /*{{{*/ -// --------------------------------------------------------------------- -/* */ void ShowDel(ostream &out,CacheFile &Cache) { - /* Print out a list of packages that are going to be removed extra - to what the user asked */ - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - if (Cache[I].Delete() == true) - { - if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge) - List += I.FullName(true) + "* "; - else - List += I.FullName(true) + " "; - - VersionsList += string(Cache[I].CandVersion)+ "\n"; - } - } - - ShowList(out,_("The following packages will be REMOVED:"),List,VersionsList); + SortedPackageUniverse Universe(Cache); + ShowList(out,_("The following packages will be REMOVED:"), Universe, + [&Cache](pkgCache::PkgIterator const &Pkg) { return Cache[Pkg].Delete(); }, + [&Cache](pkgCache::PkgIterator const &Pkg) + { + std::string str = PrettyFullName(Pkg); + if (((*Cache)[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge) + str.append("*"); + return str; + }, + CandidateVersion(&Cache)); } /*}}}*/ // ShowKept - Show kept packages /*{{{*/ -// --------------------------------------------------------------------- -/* */ void ShowKept(ostream &out,CacheFile &Cache) { - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - - // Not interesting - if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false || - I->CurrentVer == 0 || Cache[I].Delete() == true) - continue; - - List += I.FullName(true) + " "; - VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; - } - ShowList(out,_("The following packages have been kept back:"),List,VersionsList); + SortedPackageUniverse Universe(Cache); + ShowList(out,_("The following packages have been kept back:"), Universe, + [&Cache](pkgCache::PkgIterator const &Pkg) + { + return Cache[Pkg].Upgrade() == false && + Cache[Pkg].Upgradable() == true && + Pkg->CurrentVer != 0 && + Cache[Pkg].Delete() == false; + }, + &PrettyFullName, + CurrentToCandidateVersion(&Cache)); } /*}}}*/ // ShowUpgraded - Show upgraded packages /*{{{*/ -// --------------------------------------------------------------------- -/* */ void ShowUpgraded(ostream &out,CacheFile &Cache) { - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - - // Not interesting - if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true) - continue; - - List += I.FullName(true) + " "; - VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; - } - ShowList(out,_("The following packages will be upgraded:"),List,VersionsList); + SortedPackageUniverse Universe(Cache); + ShowList(out,_("The following packages will be upgraded:"), Universe, + [&Cache](pkgCache::PkgIterator const &Pkg) + { + return Cache[Pkg].Upgrade() == true && Cache[Pkg].NewInstall() == false; + }, + &PrettyFullName, + CurrentToCandidateVersion(&Cache)); } /*}}}*/ // ShowDowngraded - Show downgraded packages /*{{{*/ @@ -576,74 +508,73 @@ void ShowUpgraded(ostream &out,CacheFile &Cache) /* */ bool ShowDowngraded(ostream &out,CacheFile &Cache) { - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - - // Not interesting - if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true) - continue; - - List += I.FullName(true) + " "; - VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; - } - return ShowList(out,_("The following packages will be DOWNGRADED:"),List,VersionsList); + SortedPackageUniverse Universe(Cache); + return ShowList(out,_("The following packages will be DOWNGRADED:"), Universe, + [&Cache](pkgCache::PkgIterator const &Pkg) + { + return Cache[Pkg].Downgrade() == true && Cache[Pkg].NewInstall() == false; + }, + &PrettyFullName, + CurrentToCandidateVersion(&Cache)); } /*}}}*/ // ShowHold - Show held but changed packages /*{{{*/ -// --------------------------------------------------------------------- -/* */ bool ShowHold(ostream &out,CacheFile &Cache) { - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() && - I->SelectedState == pkgCache::State::Hold) { - List += I.FullName(true) + " "; - VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; - } - } - - return ShowList(out,_("The following held packages will be changed:"),List,VersionsList); + SortedPackageUniverse Universe(Cache); + return ShowList(out,_("The following held packages will be changed:"), Universe, + [&Cache](pkgCache::PkgIterator const &Pkg) + { + return Pkg->SelectedState == pkgCache::State::Hold && + Cache[Pkg].InstallVer != (pkgCache::Version *)Pkg.CurrentVer(); + }, + &PrettyFullName, + CurrentToCandidateVersion(&Cache)); } /*}}}*/ // ShowEssential - Show an essential package warning /*{{{*/ // --------------------------------------------------------------------- /* This prints out a warning message that is not to be ignored. It shows - all essential packages and their dependents that are to be removed. + all essential packages and their dependents that are to be removed. It is insanely risky to remove the dependents of an essential package! */ +struct APT_HIDDEN PrettyFullNameWithDue { + std::map<unsigned long long, pkgCache::PkgIterator> due; + PrettyFullNameWithDue() {} + std::string operator() (pkgCache::PkgIterator const &Pkg) + { + std::string const A = PrettyFullName(Pkg); + std::map<unsigned long long, pkgCache::PkgIterator>::const_iterator d = due.find(Pkg->ID); + if (d == due.end()) + return A; + + std::string const B = PrettyFullName(d->second); + std::ostringstream outstr; + ioprintf(outstr, _("%s (due to %s)"), A.c_str(), B.c_str()); + return outstr.str(); + } +}; bool ShowEssential(ostream &out,CacheFile &Cache) { - string List; - string VersionsList; - bool *Added = new bool[Cache->Head().PackageCount]; - for (unsigned int I = 0; I != Cache->Head().PackageCount; I++) - Added[I] = false; - - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + std::vector<bool> Added(Cache->Head().PackageCount, false); + APT::PackageDeque pkglist; + PrettyFullNameWithDue withdue; + + SortedPackageUniverse Universe(Cache); + for (pkgCache::PkgIterator const &I: Universe) { - pkgCache::PkgIterator I(Cache,Cache.List[J]); if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential && (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important) continue; - + // The essential package is being removed - if (Cache[I].Delete() == true) + if (Cache[I].Delete() == false) + continue; + + if (Added[I->ID] == false) { - if (Added[I->ID] == false) - { - Added[I->ID] = true; - List += I.FullName(true) + " "; - //VersionsList += string(Cache[I].CurVersion) + "\n"; ??? - } + Added[I->ID] = true; + pkglist.insert(I); } - else - continue; if (I->CurrentVer == 0) continue; @@ -655,27 +586,23 @@ bool ShowEssential(ostream &out,CacheFile &Cache) if (D->Type != pkgCache::Dep::PreDepends && D->Type != pkgCache::Dep::Depends) continue; - + pkgCache::PkgIterator P = D.SmartTargetPkg(); if (Cache[P].Delete() == true) { if (Added[P->ID] == true) continue; Added[P->ID] = true; - - char S[300]; - snprintf(S,sizeof(S),_("%s (due to %s) "),P.FullName(true).c_str(),I.FullName(true).c_str()); - List += S; - //VersionsList += "\n"; ??? - } - } + + pkglist.insert(P); + withdue.due[P->ID] = I; + } + } } - - delete [] Added; return ShowList(out,_("WARNING: The following essential packages will be removed.\n" - "This should NOT be done unless you know exactly what you are doing!"),List,VersionsList); + "This should NOT be done unless you know exactly what you are doing!"), + pkglist, &AlwaysTrue, withdue, &EmptyString); } - /*}}}*/ // Stats - Show some statistics /*{{{*/ // --------------------------------------------------------------------- @@ -803,3 +730,33 @@ bool AnalPrompt(const char *Text) return false; } /*}}}*/ + +std::string PrettyFullName(pkgCache::PkgIterator const &Pkg) +{ + return Pkg.FullName(true); +} +std::string CandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg) +{ + return (*Cache)[Pkg].CandVersion; +} +std::function<std::string(pkgCache::PkgIterator const &)> CandidateVersion(pkgCacheFile * const Cache) +{ + return std::bind(static_cast<std::string(*)(pkgCacheFile * const, pkgCache::PkgIterator const&)>(&CandidateVersion), Cache, std::placeholders::_1); +} +std::string CurrentToCandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg) +{ + return std::string((*Cache)[Pkg].CurVersion) + " => " + (*Cache)[Pkg].CandVersion; +} +std::function<std::string(pkgCache::PkgIterator const &)> CurrentToCandidateVersion(pkgCacheFile * const Cache) +{ + return std::bind(static_cast<std::string(*)(pkgCacheFile * const, pkgCache::PkgIterator const&)>(&CurrentToCandidateVersion), Cache, std::placeholders::_1); +} +bool AlwaysTrue(pkgCache::PkgIterator const &) +{ + return true; +} +std::string EmptyString(pkgCache::PkgIterator const &) +{ + return std::string(); +} +