summaryrefslogtreecommitdiff
path: root/cmdline
diff options
context:
space:
mode:
authorMichael Vogt <mvo@debian.org>2010-07-09 19:10:28 +0200
committerMichael Vogt <mvo@debian.org>2010-07-09 19:10:28 +0200
commit358f10d9d47a88cbf0568f042caccfef8678cbc8 (patch)
tree711c7ddc538476e8b88dfb8b6d76361db5754c1e /cmdline
parentfd3b761e8cba6ed626639b50b1221246098c7b3a (diff)
parenta9fe592842bfa17d91f4904d7fb0e3af3adebb17 (diff)
merged from donkult
Diffstat (limited to 'cmdline')
-rw-r--r--cmdline/apt-cache.cc21
-rw-r--r--cmdline/apt-cdrom.cc14
-rw-r--r--cmdline/apt-get.cc709
-rw-r--r--cmdline/cacheset.cc515
-rw-r--r--cmdline/cacheset.h375
-rw-r--r--cmdline/makefile4
6 files changed, 1231 insertions, 407 deletions
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index 7cb95b3f8..c790559e7 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -29,7 +29,8 @@
#include <apt-pkg/tagfile.h>
#include <apt-pkg/algorithms.h>
#include <apt-pkg/sptr.h>
-#include <apt-pkg/cacheset.h>
+
+#include "cacheset.h"
#include <config.h>
#include <apti18n.h>
@@ -1867,21 +1868,21 @@ int main(int argc,const char *argv[]) /*{{{*/
}
// Deal with stdout not being a tty
- if (isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
+ if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
_config->Set("quiet","1");
-// if (_config->FindB("APT::Cache::Generate",true) == false)
+ if (_config->Exists("APT::Cache::Generate") == true)
+ _config->Set("pkgCacheFile::Generate", _config->FindB("APT::Cache::Generate", true));
+
if (CmdL.DispatchArg(CmdsA,false) == false && _error->PendingError() == false)
CmdL.DispatchArg(CmdsB);
// Print any errors or warnings found during parsing
- if (_error->empty() == false)
- {
- bool Errors = _error->PendingError();
+ bool const Errors = _error->PendingError();
+ if (_config->FindI("quiet",0) > 0)
_error->DumpErrors();
- return Errors == true?100:0;
- }
-
- return 0;
+ else
+ _error->DumpErrors(GlobalError::DEBUG);
+ return Errors == true ? 100 : 0;
}
/*}}}*/
diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc
index 8b9eacae6..d1268edf9 100644
--- a/cmdline/apt-cdrom.cc
+++ b/cmdline/apt-cdrom.cc
@@ -266,20 +266,18 @@ int main(int argc,const char *argv[]) /*{{{*/
return ShowHelp();
// Deal with stdout not being a tty
- if (isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
+ if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
_config->Set("quiet","1");
// Match the operation
CmdL.DispatchArg(Cmds);
// Print any errors or warnings found during parsing
- if (_error->empty() == false)
- {
- bool Errors = _error->PendingError();
+ bool const Errors = _error->PendingError();
+ if (_config->FindI("quiet",0) > 0)
_error->DumpErrors();
- return Errors == true?100:0;
- }
-
- return 0;
+ else
+ _error->DumpErrors(GlobalError::DEBUG);
+ return Errors == true ? 100 : 0;
}
/*}}}*/
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index 0ada46c73..7cf760c27 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -40,12 +40,12 @@
#include <apt-pkg/sptr.h>
#include <apt-pkg/md5.h>
#include <apt-pkg/versionmatch.h>
-#include <apt-pkg/cacheset.h>
#include <config.h>
#include <apti18n.h>
#include "acqprogress.h"
+#include "cacheset.h"
#include <set>
#include <locale.h>
@@ -609,6 +609,253 @@ void Stats(ostream &out,pkgDepCache &Dep)
Dep.BadCount());
}
/*}}}*/
+// CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/
+class CacheSetHelperAPTGet : public APT::CacheSetHelper {
+ /** \brief stream message should be printed to */
+ std::ostream &out;
+ /** \brief were things like Task or RegEx used to select packages? */
+ bool explicitlyNamed;
+
+ APT::PackageSet virtualPkgs;
+
+public:
+ CacheSetHelperAPTGet(std::ostream &out) : APT::CacheSetHelper(true), out(out) {
+ explicitlyNamed = true;
+ }
+
+ virtual void showTaskSelection(APT::PackageSet const &pkgset, string const &pattern) {
+ for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+ ioprintf(out, _("Note, selecting '%s' for task '%s'\n"),
+ Pkg.FullName(true).c_str(), pattern.c_str());
+ explicitlyNamed = false;
+ }
+ virtual void showRegExSelection(APT::PackageSet const &pkgset, string const &pattern) {
+ for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+ ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"),
+ Pkg.FullName(true).c_str(), pattern.c_str());
+ explicitlyNamed = false;
+ }
+ virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
+ string const &ver, bool const &verIsRel) {
+ if (ver != Ver.VerStr())
+ ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"),
+ Ver.VerStr(), Ver.RelStr().c_str(), Pkg.FullName(true).c_str());
+ }
+
+ bool showVirtualPackageErrors(pkgCacheFile &Cache) {
+ if (virtualPkgs.empty() == true)
+ return true;
+ for (APT::PackageSet::const_iterator Pkg = virtualPkgs.begin();
+ Pkg != virtualPkgs.end(); ++Pkg) {
+ if (Pkg->ProvidesList != 0) {
+ ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
+ Pkg.FullName(true).c_str());
+
+ pkgCache::PrvIterator I = Pkg.ProvidesList();
+ unsigned short provider = 0;
+ for (; I.end() == false; ++I) {
+ pkgCache::PkgIterator Pkg = I.OwnerPkg();
+
+ if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) {
+ out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr();
+ if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
+ out << _(" [Installed]");
+ out << endl;
+ ++provider;
+ }
+ }
+ // if we found no candidate which provide this package, show non-candidates
+ if (provider == 0)
+ for (I = Pkg.ProvidesList(); I.end() == false; I++)
+ out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr()
+ << _(" [Not candidate version]") << endl;
+ else
+ out << _("You should explicitly select one to install.") << endl;
+ } else {
+ ioprintf(out,
+ _("Package %s is not available, but is referred to by another package.\n"
+ "This may mean that the package is missing, has been obsoleted, or\n"
+ "is only available from another source\n"),Pkg.FullName(true).c_str());
+
+ string List;
+ string VersionsList;
+ SPtrArray<bool> Seen = new bool[Cache.GetPkgCache()->Head().PackageCount];
+ memset(Seen,0,Cache.GetPkgCache()->Head().PackageCount*sizeof(*Seen));
+ for (pkgCache::DepIterator Dep = Pkg.RevDependsList();
+ Dep.end() == false; Dep++) {
+ if (Dep->Type != pkgCache::Dep::Replaces)
+ continue;
+ if (Seen[Dep.ParentPkg()->ID] == true)
+ continue;
+ Seen[Dep.ParentPkg()->ID] = true;
+ List += Dep.ParentPkg().FullName(true) + " ";
+ //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
+ }
+ ShowList(out,_("However the following packages replace it:"),List,VersionsList);
+ }
+ out << std::endl;
+ }
+ return false;
+ }
+
+ virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDIDATE);
+ if (verset.empty() == false)
+ return *(verset.begin());
+ if (ShowError == true) {
+ _error->Error(_("Package '%s' has no installation candidate"),Pkg.FullName(true).c_str());
+ virtualPkgs.insert(Pkg);
+ }
+ return pkgCache::VerIterator(Cache, 0);
+ }
+
+ virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST);
+ if (verset.empty() == false)
+ return *(verset.begin());
+ if (ShowError == true)
+ ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str());
+ return pkgCache::VerIterator(Cache, 0);
+ }
+
+ APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
+ APT::VersionSet::Version const &select) {
+ /* This is a pure virtual package and there is a single available
+ candidate providing it. */
+ if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0)
+ return APT::VersionSet();
+
+ pkgCache::PkgIterator Prov;
+ bool found_one = false;
+ for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) {
+ pkgCache::VerIterator const PVer = P.OwnerVer();
+ pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
+
+ /* Ignore versions that are not a candidate. */
+ if (Cache[PPkg].CandidateVer != PVer)
+ continue;
+
+ if (found_one == false) {
+ Prov = PPkg;
+ found_one = true;
+ } else if (PPkg != Prov) {
+ found_one = false; // we found at least two
+ break;
+ }
+ }
+
+ if (found_one == true) {
+ ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
+ Prov.FullName(true).c_str(), Pkg.FullName(true).c_str());
+ return APT::VersionSet::FromPackage(Cache, Prov, select, *this);
+ }
+ return APT::VersionSet();
+ }
+
+ inline bool allPkgNamedExplicitly() const { return explicitlyNamed; }
+
+};
+ /*}}}*/
+// TryToInstall - Mark a package for installation /*{{{*/
+struct TryToInstall {
+ pkgCacheFile* Cache;
+ pkgProblemResolver* Fix;
+ bool FixBroken;
+ unsigned long AutoMarkChanged;
+ APT::PackageSet doAutoInstallLater;
+
+ TryToInstall(pkgCacheFile &Cache, pkgProblemResolver &PM, bool const &FixBroken) : Cache(&Cache), Fix(&PM),
+ FixBroken(FixBroken), AutoMarkChanged(0) {};
+
+ void operator() (pkgCache::VerIterator const &Ver) {
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+
+ Cache->GetDepCache()->SetCandidateVersion(Ver);
+ pkgDepCache::StateCache &State = (*Cache)[Pkg];
+
+ // Handle the no-upgrade case
+ if (_config->FindB("APT::Get::upgrade",true) == false && Pkg->CurrentVer != 0)
+ ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
+ Pkg.FullName(true).c_str());
+ // Ignore request for install if package would be new
+ else if (_config->FindB("APT::Get::Only-Upgrade", false) == true && Pkg->CurrentVer == 0)
+ ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
+ Pkg.FullName(true).c_str());
+ else {
+ Fix->Clear(Pkg);
+ Fix->Protect(Pkg);
+ Cache->GetDepCache()->MarkInstall(Pkg,false);
+
+ if (State.Install() == false) {
+ if (_config->FindB("APT::Get::ReInstall",false) == true) {
+ if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
+ ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
+ Pkg.FullName(true).c_str());
+ else
+ Cache->GetDepCache()->SetReInstall(Pkg, true);
+ } else
+ ioprintf(c1out,_("%s is already the newest version.\n"),
+ Pkg.FullName(true).c_str());
+ }
+
+ // Install it with autoinstalling enabled (if we not respect the minial
+ // required deps or the policy)
+ if (FixBroken == false)
+ doAutoInstallLater.insert(Pkg);
+ }
+
+ // see if we need to fix the auto-mark flag
+ // e.g. apt-get install foo
+ // where foo is marked automatic
+ if (State.Install() == false &&
+ (State.Flags & pkgCache::Flag::Auto) &&
+ _config->FindB("APT::Get::ReInstall",false) == false &&
+ _config->FindB("APT::Get::Only-Upgrade",false) == false &&
+ _config->FindB("APT::Get::Download-Only",false) == false)
+ {
+ ioprintf(c1out,_("%s set to manually installed.\n"),
+ Pkg.FullName(true).c_str());
+ Cache->GetDepCache()->MarkAuto(Pkg,false);
+ AutoMarkChanged++;
+ }
+ }
+
+ void doAutoInstall() {
+ for (APT::PackageSet::const_iterator P = doAutoInstallLater.begin();
+ P != doAutoInstallLater.end(); ++P) {
+ pkgDepCache::StateCache &State = (*Cache)[P];
+ if (State.InstBroken() == false && State.InstPolicyBroken() == false)
+ continue;
+ Cache->GetDepCache()->MarkInstall(P, true);
+ }
+ doAutoInstallLater.clear();
+ }
+};
+ /*}}}*/
+// TryToRemove - Mark a package for removal /*{{{*/
+struct TryToRemove {
+ pkgCacheFile* Cache;
+ pkgProblemResolver* Fix;
+ bool FixBroken;
+ unsigned long AutoMarkChanged;
+
+ TryToRemove(pkgCacheFile &Cache, pkgProblemResolver &PM) : Cache(&Cache), Fix(&PM) {};
+
+ void operator() (pkgCache::VerIterator const &Ver)
+ {
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+
+ Fix->Clear(Pkg);
+ Fix->Protect(Pkg);
+ Fix->Remove(Pkg);
+
+ if (Pkg->CurrentVer == 0)
+ ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str());
+ else
+ Cache->GetDepCache()->MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
+ }
+};
+ /*}}}*/
// CacheFile::NameComp - QSort compare by name /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -1073,219 +1320,35 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
return true;
}
/*}}}*/
-// TryToInstall - Try to install a single package /*{{{*/
+// TryToInstallBuildDep - Try to install a single package /*{{{*/
// ---------------------------------------------------------------------
/* This used to be inlined in DoInstall, but with the advent of regex package
name matching it was split out.. */
-bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
+bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache,
pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
- unsigned int &ExpectedInst,bool AllowFail = true)
+ bool AllowFail = true)
{
- /* This is a pure virtual package and there is a single available
- candidate providing it. */
if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0)
{
- pkgCache::PkgIterator Prov;
- bool found_one = false;
-
- for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; P++)
- {
- pkgCache::VerIterator const PVer = P.OwnerVer();
- pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
-
- /* Ignore versions that are not a candidate. */
- if (Cache[PPkg].CandidateVer != PVer)
- continue;
-
- if (found_one == false)
- {
- Prov = PPkg;
- found_one = true;
- }
- else if (PPkg != Prov)
- {
- found_one = false; // we found at least two
- break;
- }
- }
-
- if (found_one == true)
- {
- ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
- Prov.FullName(true).c_str(),Pkg.FullName(true).c_str());
- Pkg = Prov;
- }
+ CacheSetHelperAPTGet helper(c1out);
+ helper.showErrors(AllowFail == false);
+ pkgCache::VerIterator Ver = helper.canNotFindNewestVer(Cache, Pkg);
+ if (Ver.end() == false)
+ Pkg = Ver.ParentPkg();
+ else if (helper.showVirtualPackageErrors(Cache) == false)
+ return AllowFail;
}
- // Handle the no-upgrade case
- if (_config->FindB("APT::Get::upgrade",true) == false &&
- Pkg->CurrentVer != 0)
- {
- if (AllowFail == true)
- ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
- Pkg.FullName(true).c_str());
- return true;
- }
-
- // Ignore request for install if package would be new
- if (_config->FindB("APT::Get::Only-Upgrade", false) == true &&
- Pkg->CurrentVer == 0)
- {
- if (AllowFail == true)
- ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
- Pkg.Name());
- return true;
- }
-
- // Check if there is something at all to install
- pkgDepCache::StateCache &State = Cache[Pkg];
- if (Remove == true && Pkg->CurrentVer == 0)
- {
- Fix.Clear(Pkg);
- Fix.Protect(Pkg);
- Fix.Remove(Pkg);
-
- /* We want to continue searching for regex hits, so we return false here
- otherwise this is not really an error. */
- if (AllowFail == false)
- return false;
-
- ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str());
- return true;
- }
-
- if (State.CandidateVer == 0 && Remove == false)
- {
- if (AllowFail == false)
- return false;
-
- if (Pkg->ProvidesList != 0)
- {
- ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
- Pkg.FullName(true).c_str());
-
- pkgCache::PrvIterator I = Pkg.ProvidesList();
- unsigned short provider = 0;
- for (; I.end() == false; I++)
- {
- pkgCache::PkgIterator Pkg = I.OwnerPkg();
-
- if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer())
- {
- c1out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr();
- if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
- c1out << _(" [Installed]");
- c1out << endl;
- ++provider;
- }
- }
- // if we found no candidate which provide this package, show non-candidates
- if (provider == 0)
- for (I = Pkg.ProvidesList(); I.end() == false; I++)
- c1out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr()
- << _(" [Not candidate version]") << endl;
- else
- c1out << _("You should explicitly select one to install.") << endl;
- }
- else
- {
- ioprintf(c1out,
- _("Package %s is not available, but is referred to by another package.\n"
- "This may mean that the package is missing, has been obsoleted, or\n"
- "is only available from another source\n"),Pkg.FullName(true).c_str());
-
- string List;
- string VersionsList;
- SPtrArray<bool> Seen = new bool[Cache.Head().PackageCount];
- memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen));
- pkgCache::DepIterator Dep = Pkg.RevDependsList();
- for (; Dep.end() == false; Dep++)
- {
- if (Dep->Type != pkgCache::Dep::Replaces)
- continue;
- if (Seen[Dep.ParentPkg()->ID] == true)
- continue;
- Seen[Dep.ParentPkg()->ID] = true;
- List += Dep.ParentPkg().FullName(true) + " ";
- //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
- }
- ShowList(c1out,_("However the following packages replace it:"),List,VersionsList);
- }
-
- _error->Error(_("Package %s has no installation candidate"),Pkg.FullName(true).c_str());
- return false;
- }
-
- Fix.Clear(Pkg);
- Fix.Protect(Pkg);
if (Remove == true)
{
- Fix.Remove(Pkg);
- Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
- return true;
- }
-
- // Install it
- Cache.MarkInstall(Pkg,false);
- if (State.Install() == false)
- {
- if (_config->FindB("APT::Get::ReInstall",false) == true)
- {
- if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
- ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
- Pkg.FullName(true).c_str());
- else
- Cache.SetReInstall(Pkg,true);
- }
- else
- {
- if (AllowFail == true)
- ioprintf(c1out,_("%s is already the newest version.\n"),
- Pkg.FullName(true).c_str());
- }
- }
- else
- ExpectedInst++;
-
- // Install it with autoinstalling enabled (if we not respect the minial
- // required deps or the policy)
- if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && BrokenFix == false)
- Cache.MarkInstall(Pkg,true);
-
- return true;
-}
- /*}}}*/
-// TryToChangeVer - Try to change a candidate version /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
- const char *VerTag,bool IsRel)
-{
- pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release :
- pkgVersionMatch::Version));
-
- pkgCache::VerIterator Ver = Match.Find(Pkg);
-
- if (Ver.end() == true)
- {
- if (IsRel == true)
- return _error->Error(_("Release '%s' for '%s' was not found"),
- VerTag,Pkg.FullName(true).c_str());
- return _error->Error(_("Version '%s' for '%s' was not found"),
- VerTag,Pkg.FullName(true).c_str());
- }
-
- if (strcmp(VerTag,Ver.VerStr()) != 0)
- {
- ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
- Ver.VerStr(),Ver.RelStr().c_str(),Pkg.FullName(true).c_str());
- }
-
- Cache.SetCandidateVersion(Ver);
-
- // Set the all package to the same candidate
- if (Ver.Pseudo() == true)
- Cache.SetCandidateVersion(Match.Find(Pkg.Group().FindPkg("all")));
+ TryToRemove RemoveAction(Cache, Fix);
+ RemoveAction(Pkg.VersionList());
+ } else if (Cache[Pkg].CandidateVer != 0) {
+ TryToInstall InstallAction(Cache, Fix, BrokenFix);
+ InstallAction(Cache[Pkg].CandidateVerIter(Cache));
+ InstallAction.doAutoInstall();
+ } else
+ return AllowFail;
return true;
}
@@ -1624,61 +1687,6 @@ bool DoUpgrade(CommandLine &CmdL)
return InstallPackages(Cache,true);
}
/*}}}*/
-// DoInstallTask - Install task from the command line /*{{{*/
-// ---------------------------------------------------------------------
-/* Install named task */
-bool TryInstallTask(pkgDepCache &Cache, pkgProblemResolver &Fix,
- bool BrokenFix,
- unsigned int& ExpectedInst,
- const char *taskname,
- bool Remove)
-{
- const char *start, *end;
- pkgCache::PkgIterator Pkg;
- char buf[64*1024];
- regex_t Pattern;
-
- // get the records
- pkgRecords Recs(Cache);
-
- // build regexp for the task
- char S[300];
- snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", taskname);
- if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0)
- return _error->Error("Failed to compile task regexp");
-
- bool found = false;
- bool res = true;
-
- // two runs, first ignore dependencies, second install any missing
- for(int IgnoreBroken=1; IgnoreBroken >= 0; IgnoreBroken--)
- {
- for (Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
- {
- pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache);
- if(ver.end())
- continue;
- pkgRecords::Parser &parser = Recs.Lookup(ver.FileList());
- parser.GetRec(start,end);
- strncpy(buf, start, end-start);
- buf[end-start] = 0x0;
- if (regexec(&Pattern,buf,0,0,0) != 0)
- continue;
- res &= TryToInstall(Pkg,Cache,Fix,Remove,IgnoreBroken,ExpectedInst);
- found = true;
- }
- }
-
- // now let the problem resolver deal with any issues
- Fix.Resolve(true);
-
- if(!found)
- _error->Error(_("Couldn't find task %s"),taskname);
-
- regfree(&Pattern);
- return res;
-}
- /*}}}*/
// DoInstall - Install packages from the command line /*{{{*/
// ---------------------------------------------------------------------
/* Install named packages */
@@ -1694,140 +1702,69 @@ bool DoInstall(CommandLine &CmdL)
if (Cache->BrokenCount() != 0)
BrokenFix = true;
- unsigned int AutoMarkChanged = 0;
- unsigned int ExpectedInst = 0;
- unsigned int Packages = 0;
pkgProblemResolver Fix(Cache);
-
- bool DefRemove = false;
+
+ static const unsigned short MOD_REMOVE = 1;
+ static const unsigned short MOD_INSTALL = 2;
+
+ unsigned short fallback = MOD_INSTALL;
if (strcasecmp(CmdL.FileList[0],"remove") == 0)
- DefRemove = true;
+ fallback = MOD_REMOVE;
else if (strcasecmp(CmdL.FileList[0], "purge") == 0)
{
_config->Set("APT::Get::Purge", true);
- DefRemove = true;
+ fallback = MOD_REMOVE;
}
else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0)
{
_config->Set("APT::Get::AutomaticRemove", "true");
- DefRemove = true;
+ fallback = MOD_REMOVE;
}
- // new scope for the ActionGroup
- {
- pkgDepCache::ActionGroup group(Cache);
- for (const char **I = CmdL.FileList + 1; *I != 0; I++)
- {
- // Duplicate the string
- unsigned int Length = strlen(*I);
- char S[300];
- if (Length >= sizeof(S))
- continue;
- strcpy(S,*I);
-
- // See if we are removing and special indicators..
- bool Remove = DefRemove;
- char *VerTag = 0;
- bool VerIsRel = false;
- // this is a task!
- if (Length >= 1 && S[Length - 1] == '^')
- {
- S[--Length] = 0;
- // tasks must always be confirmed
- ExpectedInst += 1000;
- // see if we can install it
- TryInstallTask(Cache, Fix, BrokenFix, ExpectedInst, S, Remove);
- continue;
- }
+ std::list<APT::VersionSet::Modifier> mods;
+ mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
+ APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE));
+ mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
+ APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST));
+ CacheSetHelperAPTGet helper(c0out);
+ std::map<unsigned short, APT::VersionSet> verset = APT::VersionSet::GroupedFromCommandLine(Cache,
+ CmdL.FileList + 1, mods, fallback, helper);
- while (Cache->FindPkg(S).end() == true)
- {
- // Handle an optional end tag indicating what to do
- if (Length >= 1 && S[Length - 1] == '-')
- {
- Remove = true;
- S[--Length] = 0;
- continue;
- }
-
- if (Length >= 1 && S[Length - 1] == '+')
- {
- Remove = false;
- S[--Length] = 0;
- continue;
- }
-
- char *Slash = strchr(S,'=');
- if (Slash != 0)
- {
- VerIsRel = false;
- *Slash = 0;
- VerTag = Slash + 1;
- }
-
- Slash = strchr(S,'/');
- if (Slash != 0)
- {
- VerIsRel = true;
- *Slash = 0;
- VerTag = Slash + 1;
- }
-
- break;
- }
-
- // Locate the package
- pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
- Packages++;
- if (Pkg.end() == true)
- {
- APT::PackageSet pkgset = APT::PackageSet::FromRegEx(Cache, S, c1out);
- if (pkgset.empty() == true)
- return _error->Error(_("Couldn't find package %s"),S);
+ if (_error->PendingError() == true)
+ {
+ helper.showVirtualPackageErrors(Cache);
+ return false;
+ }
- // Regexs must always be confirmed
- ExpectedInst += 1000;
+ unsigned short order[] = { 0, 0, 0 };
+ if (fallback == MOD_INSTALL) {
+ order[0] = MOD_INSTALL;
+ order[1] = MOD_REMOVE;
+ } else {
+ order[0] = MOD_REMOVE;
+ order[1] = MOD_INSTALL;
+ }
- bool Hit = false;
- for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
- {
- if (VerTag != 0)
- if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
- return false;
+ TryToInstall InstallAction(Cache, Fix, BrokenFix);
+ TryToRemove RemoveAction(Cache, Fix);
- Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
- ExpectedInst,false);
- }
+ // new scope for the ActionGroup
+ {
+ pkgDepCache::ActionGroup group(Cache);
- if (Hit == false)
- return _error->Error(_("Couldn't find package %s"),S);
+ for (unsigned short i = 0; order[i] != 0; ++i)
+ {
+ if (order[i] == MOD_INSTALL) {
+ InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction);
+ InstallAction.doAutoInstall();
}
- else
- {
- if (VerTag != 0)
- if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
- return false;
- if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
- return false;
-
- // see if we need to fix the auto-mark flag
- // e.g. apt-get install foo
- // where foo is marked automatic
- if(!Remove &&
- Cache[Pkg].Install() == false &&
- (Cache[Pkg].Flags & pkgCache::Flag::Auto) &&
- _config->FindB("APT::Get::ReInstall",false) == false &&
- _config->FindB("APT::Get::Only-Upgrade",false) == false &&
- _config->FindB("APT::Get::Download-Only",false) == false)
- {
- ioprintf(c1out,_("%s set to manually installed.\n"),
- Pkg.FullName(true).c_str());
- Cache->MarkAuto(Pkg,false);
- AutoMarkChanged++;
- }
- }
+ else if (order[i] == MOD_REMOVE)
+ RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
}
+ if (_error->PendingError() == true)
+ return false;
+
/* If we are in the Broken fixing mode we do not attempt to fix the
problems. This is if the user invoked install without -f and gave
packages */
@@ -1874,7 +1811,7 @@ bool DoInstall(CommandLine &CmdL)
/* Print out a list of packages that are going to be installed extra
to what the user asked */
- if (Cache->InstCount() != ExpectedInst)
+ if (Cache->InstCount() != verset[MOD_INSTALL].size())
{
string List;
string VersionsList;
@@ -1993,14 +1930,15 @@ bool DoInstall(CommandLine &CmdL)
// if nothing changed in the cache, but only the automark information
// we write the StateFile here, otherwise it will be written in
// cache.commit()
- if (AutoMarkChanged > 0 &&
+ if (InstallAction.AutoMarkChanged > 0 &&
Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
Cache->BadCount() == 0 &&
_config->FindB("APT::Get::Simulate",false) == false)
Cache->writeStateFile(NULL);
// See if we need to prompt
- if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
+ // FIXME: check if really the packages in the set are going to be installed
+ if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0)
return InstallPackages(Cache,false,false);
return InstallPackages(Cache,false);
@@ -2584,7 +2522,6 @@ bool DoBuildDep(CommandLine &CmdL)
}
// Install the requested packages
- unsigned int ExpectedInst = 0;
vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
pkgProblemResolver Fix(Cache);
bool skipAlternatives = false; // skip remaining alternatives in an or group
@@ -2615,7 +2552,7 @@ bool DoBuildDep(CommandLine &CmdL)
*/
if (IV.end() == false &&
Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
- TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
+ TryToInstallBuildDep(Pkg,Cache,Fix,true,false);
}
else // BuildDep || BuildDepIndep
{
@@ -2731,7 +2668,7 @@ bool DoBuildDep(CommandLine &CmdL)
if (_config->FindB("Debug::BuildDeps",false) == true)
cout << " Trying to install " << (*D).Package << endl;
- if (TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst) == true)
+ if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true)
{
// We successfully installed something; skip remaining alternatives
skipAlternatives = hasAlternatives;
@@ -3021,7 +2958,7 @@ int main(int argc,const char *argv[]) /*{{{*/
}
// Deal with stdout not being a tty
- if (!isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
+ if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
_config->Set("quiet","1");
// Setup the output streams
@@ -3042,13 +2979,11 @@ int main(int argc,const char *argv[]) /*{{{*/
CmdL.DispatchArg(Cmds);
// Print any errors or warnings found during parsing
- if (_error->empty() == false)
- {
- bool Errors = _error->PendingError();
+ bool const Errors = _error->PendingError();
+ if (_config->FindI("quiet",0) > 0)
_error->DumpErrors();
- return Errors == true?100:0;
- }
-
- return 0;
+ else
+ _error->DumpErrors(GlobalError::DEBUG);
+ return Errors == true ? 100 : 0;
}
/*}}}*/
diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc
new file mode 100644
index 000000000..78c9d3f6c
--- /dev/null
+++ b/cmdline/cacheset.cc
@@ -0,0 +1,515 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ Simple wrapper around a std::set to provide a similar interface to
+ a set of cache structures as to the complete set of all structures
+ in the pkgCache. Currently only Package is supported.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/versionmatch.h>
+
+#include <apti18n.h>
+
+#include "cacheset.h"
+
+#include <vector>
+
+#include <regex.h>
+ /*}}}*/
+namespace APT {
+// FromTask - Return all packages in the cache from a specific task /*{{{*/
+PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
+ size_t const archfound = pattern.find_last_of(':');
+ std::string arch = "native";
+ if (archfound != std::string::npos) {
+ arch = pattern.substr(archfound+1);
+ pattern.erase(archfound);
+ }
+
+ if (pattern[pattern.length() -1] != '^')
+ return APT::PackageSet(TASK);
+ pattern.erase(pattern.length()-1);
+
+ if (unlikely(Cache.GetPkgCache() == 0 || Cache.GetDepCache() == 0))
+ return APT::PackageSet(TASK);
+
+ PackageSet pkgset(TASK);
+ // get the records
+ pkgRecords Recs(Cache);
+
+ // build regexp for the task
+ regex_t Pattern;
+ char S[300];
+ snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", pattern.c_str());
+ if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) {
+ _error->Error("Failed to compile task regexp");
+ return pkgset;
+ }
+
+ for (pkgCache::GrpIterator Grp = Cache->GrpBegin(); Grp.end() == false; ++Grp) {
+ pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
+ if (Pkg.end() == true)
+ continue;
+ pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache);
+ if(ver.end() == true)
+ continue;
+
+ pkgRecords::Parser &parser = Recs.Lookup(ver.FileList());
+ const char *start, *end;
+ parser.GetRec(start,end);
+ unsigned int const length = end - start;
+ char buf[length];
+ strncpy(buf, start, length);
+ buf[length-1] = '\0';
+ if (regexec(&Pattern, buf, 0, 0, 0) != 0)
+ continue;
+
+ pkgset.insert(Pkg);
+ }
+ regfree(&Pattern);
+
+ if (pkgset.empty() == true)
+ return helper.canNotFindTask(Cache, pattern);
+
+ helper.showTaskSelection(pkgset, pattern);
+ return pkgset;
+}
+ /*}}}*/
+// FromRegEx - Return all packages in the cache matching a pattern /*{{{*/
+PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
+ static const char * const isregex = ".?+*|[^$";
+ if (pattern.find_first_of(isregex) == std::string::npos)
+ return PackageSet(REGEX);
+
+ size_t archfound = pattern.find_last_of(':');
+ std::string arch = "native";
+ if (archfound != std::string::npos) {
+ arch = pattern.substr(archfound+1);
+ if (arch.find_first_of(isregex) == std::string::npos)
+ pattern.erase(archfound);
+ else
+ arch = "native";
+ }
+
+ regex_t Pattern;
+ int Res;
+ if ((Res = regcomp(&Pattern, pattern.c_str() , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) {
+ char Error[300];
+ regerror(Res, &Pattern, Error, sizeof(Error));
+ _error->Error(_("Regex compilation error - %s"), Error);
+ return PackageSet(REGEX);
+ }
+
+ if (unlikely(Cache.GetPkgCache() == 0))
+ return PackageSet(REGEX);
+
+ PackageSet pkgset(REGEX);
+ for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp)
+ {
+ if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0)
+ continue;
+ pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
+ if (Pkg.end() == true) {
+ if (archfound == std::string::npos) {
+ std::vector<std::string> archs = APT::Configuration::getArchitectures();
+ for (std::vector<std::string>::const_iterator a = archs.begin();
+ a != archs.end() && Pkg.end() != true; ++a)
+ Pkg = Grp.FindPkg(*a);
+ }
+ if (Pkg.end() == true)
+ continue;
+ }
+
+ pkgset.insert(Pkg);
+ }
+ regfree(&Pattern);
+
+ if (pkgset.empty() == true)
+ return helper.canNotFindRegEx(Cache, pattern);
+
+ helper.showRegExSelection(pkgset, pattern);
+ return pkgset;
+}
+ /*}}}*/
+// FromName - Returns the package defined by this string /*{{{*/
+pkgCache::PkgIterator PackageSet::FromName(pkgCacheFile &Cache,
+ std::string const &str, CacheSetHelper &helper) {
+ std::string pkg = str;
+ size_t archfound = pkg.find_last_of(':');
+ std::string arch;
+ if (archfound != std::string::npos) {
+ arch = pkg.substr(archfound+1);
+ pkg.erase(archfound);
+ }
+
+ if (Cache.GetPkgCache() == 0)
+ return pkgCache::PkgIterator(Cache, 0);
+
+ pkgCache::PkgIterator Pkg(Cache, 0);
+ if (arch.empty() == true) {
+ pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(pkg);
+ if (Grp.end() == false)
+ Pkg = Grp.FindPreferredPkg();
+ } else
+ Pkg = Cache.GetPkgCache()->FindPkg(pkg, arch);
+
+ if (Pkg.end() == true)
+ return helper.canNotFindPkgName(Cache, str);
+ return Pkg;
+}
+ /*}}}*/
+// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
+std::map<unsigned short, PackageSet> PackageSet::GroupedFromCommandLine(
+ pkgCacheFile &Cache, const char **cmdline,
+ std::list<PackageSet::Modifier> const &mods,
+ unsigned short const &fallback, CacheSetHelper &helper) {
+ std::map<unsigned short, PackageSet> pkgsets;
+ for (const char **I = cmdline; *I != 0; ++I) {
+ unsigned short modID = fallback;
+ std::string str = *I;
+ bool modifierPresent = false;
+ for (std::list<PackageSet::Modifier>::const_iterator mod = mods.begin();
+ mod != mods.end(); ++mod) {
+ size_t const alength = strlen(mod->Alias);
+ switch(mod->Pos) {
+ case PackageSet::Modifier::POSTFIX:
+ if (str.compare(str.length() - alength, alength,
+ mod->Alias, 0, alength) != 0)
+ continue;
+ str.erase(str.length() - alength);
+ modID = mod->ID;
+ break;
+ case PackageSet::Modifier::PREFIX:
+ continue;
+ case PackageSet::Modifier::NONE:
+ continue;
+ }
+ modifierPresent = true;
+ break;
+ }
+ if (modifierPresent == true) {
+ bool const errors = helper.showErrors(false);
+ pkgCache::PkgIterator Pkg = FromName(Cache, *I, helper);
+ helper.showErrors(errors);
+ if (Pkg.end() == false) {
+ pkgsets[fallback].insert(Pkg);
+ continue;
+ }
+ }
+ pkgsets[modID].insert(PackageSet::FromString(Cache, str, helper));
+ }
+ return pkgsets;
+}
+ /*}}}*/
+// FromCommandLine - Return all packages specified on commandline /*{{{*/
+PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) {
+ PackageSet pkgset;
+ for (const char **I = cmdline; *I != 0; ++I) {
+ PackageSet pset = FromString(Cache, *I, helper);
+ pkgset.insert(pset.begin(), pset.end());
+ }
+ return pkgset;
+}
+ /*}}}*/
+// FromString - Return all packages matching a specific string /*{{{*/
+PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) {
+ _error->PushToStack();
+
+ PackageSet pkgset;
+ pkgCache::PkgIterator Pkg = FromName(Cache, str, helper);
+ if (Pkg.end() == false)
+ pkgset.insert(Pkg);
+ else {
+ pkgset = FromTask(Cache, str, helper);
+ if (pkgset.empty() == true) {
+ pkgset = FromRegEx(Cache, str, helper);
+ if (pkgset.empty() == true)
+ pkgset = helper.canNotFindPackage(Cache, str);
+ }
+ }
+
+ if (pkgset.empty() == false)
+ _error->RevertToStack();
+ else
+ _error->MergeWithStack();
+ return pkgset;
+}
+ /*}}}*/
+// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
+std::map<unsigned short, VersionSet> VersionSet::GroupedFromCommandLine(
+ pkgCacheFile &Cache, const char **cmdline,
+ std::list<VersionSet::Modifier> const &mods,
+ unsigned short const &fallback, CacheSetHelper &helper) {
+ std::map<unsigned short, VersionSet> versets;
+ for (const char **I = cmdline; *I != 0; ++I) {
+ unsigned short modID = fallback;
+ VersionSet::Version select = VersionSet::NEWEST;
+ std::string str = *I;
+ bool modifierPresent = false;
+ for (std::list<VersionSet::Modifier>::const_iterator mod = mods.begin();
+ mod != mods.end(); ++mod) {
+ if (modID == fallback && mod->ID == fallback)
+ select = mod->SelectVersion;
+ size_t const alength = strlen(mod->Alias);
+ switch(mod->Pos) {
+ case VersionSet::Modifier::POSTFIX:
+ if (str.compare(str.length() - alength, alength,
+ mod->Alias, 0, alength) != 0)
+ continue;
+ str.erase(str.length() - alength);
+ modID = mod->ID;
+ select = mod->SelectVersion;
+ break;
+ case VersionSet::Modifier::PREFIX:
+ continue;
+ case VersionSet::Modifier::NONE:
+ continue;
+ }
+ modifierPresent = true;
+ break;
+ }
+
+ if (modifierPresent == true) {
+ bool const errors = helper.showErrors(false);
+ VersionSet const vset = VersionSet::FromString(Cache, std::string(*I), select, helper, true);
+ helper.showErrors(errors);
+ if (vset.empty() == false) {
+ versets[fallback].insert(vset);
+ continue;
+ }
+ }
+ versets[modID].insert(VersionSet::FromString(Cache, str, select , helper));
+ }
+ return versets;
+}
+ /*}}}*/
+// FromCommandLine - Return all versions specified on commandline /*{{{*/
+APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
+ APT::VersionSet::Version const &fallback, CacheSetHelper &helper) {
+ VersionSet verset;
+ for (const char **I = cmdline; *I != 0; ++I)
+ verset.insert(VersionSet::FromString(Cache, *I, fallback, helper));
+ return verset;
+}
+ /*}}}*/
+// FromString - Returns all versions spedcified by a string /*{{{*/
+APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg,
+ APT::VersionSet::Version const &fallback, CacheSetHelper &helper,
+ bool const &onlyFromName) {
+ std::string ver;
+ bool verIsRel = false;
+ size_t const vertag = pkg.find_last_of("/=");
+ if (vertag != string::npos) {
+ ver = pkg.substr(vertag+1);
+ verIsRel = (pkg[vertag] == '/');
+ pkg.erase(vertag);
+ }
+ PackageSet pkgset;
+ if (onlyFromName == false)
+ pkgset = PackageSet::FromString(Cache, pkg, helper);
+ else {
+ pkgset.insert(PackageSet::FromName(Cache, pkg, helper));
+ }
+
+ VersionSet verset;
+ bool errors = true;
+ if (pkgset.getConstructor() != PackageSet::UNKNOWN)
+ errors = helper.showErrors(false);
+ for (PackageSet::const_iterator P = pkgset.begin();
+ P != pkgset.end(); ++P) {
+ if (vertag == string::npos) {
+ verset.insert(VersionSet::FromPackage(Cache, P, fallback, helper));
+ continue;
+ }
+ pkgCache::VerIterator V;
+ if (ver == "installed")
+ V = getInstalledVer(Cache, P, helper);
+ else if (ver == "candidate")
+ V = getCandidateVer(Cache, P, helper);
+ else {
+ pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release :
+ pkgVersionMatch::Version));
+ V = Match.Find(P);
+ if (V.end() == true) {
+ if (verIsRel == true)
+ _error->Error(_("Release '%s' for '%s' was not found"),
+ ver.c_str(), P.FullName(true).c_str());
+ else
+ _error->Error(_("Version '%s' for '%s' was not found"),
+ ver.c_str(), P.FullName(true).c_str());
+ continue;
+ }
+ }
+ if (V.end() == true)
+ continue;
+ helper.showSelectedVersion(P, V, ver, verIsRel);
+ verset.insert(V);
+ }
+ if (pkgset.getConstructor() != PackageSet::UNKNOWN)
+ helper.showErrors(errors);
+ return verset;
+}
+ /*}}}*/
+// FromPackage - versions from package based on fallback /*{{{*/
+VersionSet VersionSet::FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
+ VersionSet::Version const &fallback, CacheSetHelper &helper) {
+ VersionSet verset;
+ pkgCache::VerIterator V;
+ bool showErrors;
+ switch(fallback) {
+ case VersionSet::ALL:
+ if (P->VersionList != 0)
+ for (V = P.VersionList(); V.end() != true; ++V)
+ verset.insert(V);
+ else
+ verset.insert(helper.canNotFindAllVer(Cache, P));
+ break;
+ case VersionSet::CANDANDINST:
+ verset.insert(getInstalledVer(Cache, P, helper));
+ verset.insert(getCandidateVer(Cache, P, helper));
+ break;
+ case VersionSet::CANDIDATE:
+ verset.insert(getCandidateVer(Cache, P, helper));
+ break;
+ case VersionSet::INSTALLED:
+ verset.insert(getInstalledVer(Cache, P, helper));
+ break;
+ case VersionSet::CANDINST:
+ showErrors = helper.showErrors(false);
+ V = getCandidateVer(Cache, P, helper);
+ if (V.end() == true)
+ V = getInstalledVer(Cache, P, helper);
+ helper.showErrors(showErrors);
+ if (V.end() == false)
+ verset.insert(V);
+ else
+ verset.insert(helper.canNotFindInstCandVer(Cache, P));
+ break;
+ case VersionSet::INSTCAND:
+ showErrors = helper.showErrors(false);
+ V = getInstalledVer(Cache, P, helper);
+ if (V.end() == true)
+ V = getCandidateVer(Cache, P, helper);
+ helper.showErrors(showErrors);
+ if (V.end() == false)
+ verset.insert(V);
+ else
+ verset.insert(helper.canNotFindInstCandVer(Cache, P));
+ break;
+ case VersionSet::NEWEST:
+ if (P->VersionList != 0)
+ verset.insert(P.VersionList());
+ else
+ verset.insert(helper.canNotFindNewestVer(Cache, P));
+ break;
+ }
+ return verset;
+}
+ /*}}}*/
+// getCandidateVer - Returns the candidate version of the given package /*{{{*/
+pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) {
+ pkgCache::VerIterator Cand;
+ if (Cache.IsPolicyBuilt() == true || Cache.IsDepCacheBuilt() == false)
+ {
+ if (unlikely(Cache.GetPolicy() == 0))
+ return pkgCache::VerIterator(Cache);
+ Cand = Cache.GetPolicy()->GetCandidateVer(Pkg);
+ } else {
+ Cand = Cache[Pkg].CandidateVerIter(Cache);
+ }
+ if (Cand.end() == true)
+ return helper.canNotFindCandidateVer(Cache, Pkg);
+ return Cand;
+}
+ /*}}}*/
+// getInstalledVer - Returns the installed version of the given package /*{{{*/
+pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) {
+ if (Pkg->CurrentVer == 0)
+ return helper.canNotFindInstalledVer(Cache, Pkg);
+ return Pkg.CurrentVer();
+}
+ /*}}}*/
+// canNotFindPkgName - handle the case no package has this name /*{{{*/
+pkgCache::PkgIterator CacheSetHelper::canNotFindPkgName(pkgCacheFile &Cache,
+ std::string const &str) {
+ if (ShowError == true)
+ _error->Error(_("Unable to locate package %s"), str.c_str());
+ return pkgCache::PkgIterator(Cache, 0);
+}
+ /*}}}*/
+// canNotFindTask - handle the case no package is found for a task /*{{{*/
+PackageSet CacheSetHelper::canNotFindTask(pkgCacheFile &Cache, std::string pattern) {
+ if (ShowError == true)
+ _error->Error(_("Couldn't find task '%s'"), pattern.c_str());
+ return PackageSet();
+}
+ /*}}}*/
+// canNotFindRegEx - handle the case no package is found by a regex /*{{{*/
+PackageSet CacheSetHelper::canNotFindRegEx(pkgCacheFile &Cache, std::string pattern) {
+ if (ShowError == true)
+ _error->Error(_("Couldn't find any package by regex '%s'"), pattern.c_str());
+ return PackageSet();
+}
+ /*}}}*/
+// canNotFindPackage - handle the case no package is found from a string/*{{{*/
+PackageSet CacheSetHelper::canNotFindPackage(pkgCacheFile &Cache, std::string const &str) {
+ return PackageSet();
+}
+ /*}}}*/
+// canNotFindAllVer /*{{{*/
+VersionSet CacheSetHelper::canNotFindAllVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select versions from package '%s' as it purely virtual"), Pkg.FullName(true).c_str());
+ return VersionSet();
+}
+ /*}}}*/
+// canNotFindInstCandVer /*{{{*/
+VersionSet CacheSetHelper::canNotFindInstCandVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str());
+ return VersionSet();
+}
+ /*}}}*/
+// canNotFindInstCandVer /*{{{*/
+VersionSet CacheSetHelper::canNotFindCandInstVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str());
+ return VersionSet();
+}
+ /*}}}*/
+// canNotFindNewestVer /*{{{*/
+pkgCache::VerIterator CacheSetHelper::canNotFindNewestVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), Pkg.FullName(true).c_str());
+ return pkgCache::VerIterator(Cache, 0);
+}
+ /*}}}*/
+// canNotFindCandidateVer /*{{{*/
+pkgCache::VerIterator CacheSetHelper::canNotFindCandidateVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str());
+ return pkgCache::VerIterator(Cache, 0);
+}
+ /*}}}*/
+// canNotFindInstalledVer /*{{{*/
+pkgCache::VerIterator CacheSetHelper::canNotFindInstalledVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str());
+ return pkgCache::VerIterator(Cache, 0);
+}
+ /*}}}*/
+}
diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h
new file mode 100644
index 000000000..c8c3dd096
--- /dev/null
+++ b/cmdline/cacheset.h
@@ -0,0 +1,375 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/** \file cacheset.h
+ Wrappers around std::set to have set::iterators which behave
+ similar to the Iterators of the cache structures.
+
+ Provides also a few helper methods which work with these sets */
+ /*}}}*/
+#ifndef APT_CACHESET_H
+#define APT_CACHESET_H
+// Include Files /*{{{*/
+#include <iostream>
+#include <fstream>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/pkgcache.h>
+ /*}}}*/
+namespace APT {
+class PackageSet;
+class VersionSet;
+class CacheSetHelper { /*{{{*/
+/** \class APT::CacheSetHelper
+ Simple base class with a lot of virtual methods which can be overridden
+ to alter the behavior or the output of the CacheSets.
+
+ This helper is passed around by the static methods in the CacheSets and
+ used every time they hit an error condition or something could be
+ printed out.
+*/
+public: /*{{{*/
+ CacheSetHelper(bool const &ShowError = true) : ShowError(ShowError) {};
+ virtual ~CacheSetHelper() {};
+
+ virtual void showTaskSelection(PackageSet const &pkgset, string const &pattern) {};
+ virtual void showRegExSelection(PackageSet const &pkgset, string const &pattern) {};
+ virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
+ string const &ver, bool const &verIsRel) {};
+
+ virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str);
+ virtual PackageSet canNotFindTask(pkgCacheFile &Cache, std::string pattern);
+ virtual PackageSet canNotFindRegEx(pkgCacheFile &Cache, std::string pattern);
+ virtual PackageSet canNotFindPackage(pkgCacheFile &Cache, std::string const &str);
+ virtual VersionSet canNotFindAllVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
+ virtual VersionSet canNotFindInstCandVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg);
+ virtual VersionSet canNotFindCandInstVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg);
+ virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg);
+ virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg);
+ virtual pkgCache::VerIterator canNotFindInstalledVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg);
+
+ bool showErrors() const { return ShowError; };
+ bool showErrors(bool const &newValue) { if (ShowError == newValue) return ShowError; else return ((ShowError = newValue) == false); };
+ /*}}}*/
+protected:
+ bool ShowError;
+}; /*}}}*/
+class PackageSet : public std::set<pkgCache::PkgIterator> { /*{{{*/
+/** \class APT::PackageSet
+
+ Simple wrapper around a std::set to provide a similar interface to
+ a set of packages as to the complete set of all packages in the
+ pkgCache. */
+public: /*{{{*/
+ /** \brief smell like a pkgCache::PkgIterator */
+ class const_iterator : public std::set<pkgCache::PkgIterator>::const_iterator {/*{{{*/
+ public:
+ const_iterator(std::set<pkgCache::PkgIterator>::const_iterator x) :
+ std::set<pkgCache::PkgIterator>::const_iterator(x) {}
+
+ operator pkgCache::PkgIterator(void) { return **this; }
+
+ inline const char *Name() const {return (**this).Name(); }
+ inline std::string FullName(bool const &Pretty) const { return (**this).FullName(Pretty); }
+ inline std::string FullName() const { return (**this).FullName(); }
+ inline const char *Section() const {return (**this).Section(); }
+ inline bool Purge() const {return (**this).Purge(); }
+ inline const char *Arch() const {return (**this).Arch(); }
+ inline pkgCache::GrpIterator Group() const { return (**this).Group(); }
+ inline pkgCache::VerIterator VersionList() const { return (**this).VersionList(); }
+ inline pkgCache::VerIterator CurrentVer() const { return (**this).CurrentVer(); }
+ inline pkgCache::DepIterator RevDependsList() const { return (**this).RevDependsList(); }
+ inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); }
+ inline pkgCache::PkgIterator::OkState State() const { return (**this).State(); }
+ inline const char *CandVersion() const { return (**this).CandVersion(); }
+ inline const char *CurVersion() const { return (**this).CurVersion(); }
+ inline pkgCache *Cache() const { return (**this).Cache(); };
+ inline unsigned long Index() const {return (**this).Index();};
+ // we have only valid iterators here
+ inline bool end() const { return false; };
+
+ friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, (*i)); }
+
+ inline pkgCache::Package const * operator->() const {
+ return &***this;
+ };
+ };
+ // 103. set::iterator is required to be modifiable, but this allows modification of keys
+ typedef APT::PackageSet::const_iterator iterator;
+ /*}}}*/
+
+ using std::set<pkgCache::PkgIterator>::insert;
+ inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set<pkgCache::PkgIterator>::insert(P); };
+ inline void insert(PackageSet const &pkgset) { insert(pkgset.begin(), pkgset.end()); };
+
+ /** \brief returns all packages in the cache who belong to the given task
+
+ A simple helper responsible for search for all members of a task
+ in the cache. Optional it prints a a notice about the
+ packages chosen cause of the given task.
+ \param Cache the packages are in
+ \param pattern name of the task
+ \param helper responsible for error and message handling */
+ static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
+ static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) {
+ CacheSetHelper helper;
+ return APT::PackageSet::FromTask(Cache, pattern, helper);
+ }
+
+ /** \brief returns all packages in the cache whose name matchs a given pattern
+
+ A simple helper responsible for executing a regular expression on all
+ package names in the cache. Optional it prints a a notice about the
+ packages chosen cause of the given package.
+ \param Cache the packages are in
+ \param pattern regular expression for package names
+ \param helper responsible for error and message handling */
+ static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
+ static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) {
+ CacheSetHelper helper;
+ return APT::PackageSet::FromRegEx(Cache, pattern, helper);
+ }
+
+ /** \brief returns all packages specified by a string
+
+ \param Cache the packages are in
+ \param string String the package name(s) should be extracted from
+ \param helper responsible for error and message handling */
+ static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper);
+ static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) {
+ CacheSetHelper helper;
+ return APT::PackageSet::FromString(Cache, string, helper);
+ }
+
+ /** \brief returns a package specified by a string
+
+ \param Cache the package is in
+ \param string String the package name should be extracted from
+ \param helper responsible for error and message handling */
+ static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper);
+ static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string) {
+ CacheSetHelper helper;
+ return APT::PackageSet::FromName(Cache, string, helper);
+ }
+
+ /** \brief returns all packages specified on the commandline
+
+ Get all package names from the commandline and executes regex's if needed.
+ No special package command is supported, just plain names.
+ \param Cache the packages are in
+ \param cmdline Command line the package names should be extracted from
+ \param helper responsible for error and message handling */
+ static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper);
+ static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
+ CacheSetHelper helper;
+ return APT::PackageSet::FromCommandLine(Cache, cmdline, helper);
+ }
+
+ struct Modifier {
+ enum Position { NONE, PREFIX, POSTFIX };
+ unsigned short ID;
+ const char * const Alias;
+ Position Pos;
+ Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {};
+ };
+
+ /** \brief group packages by a action modifiers
+
+ At some point it is needed to get from the same commandline
+ different package sets grouped by a modifier. Take
+ apt-get install apt awesome-
+ as an example.
+ \param Cache the packages are in
+ \param cmdline Command line the package names should be extracted from
+ \param mods list of modifiers the method should accept
+ \param fallback the default modifier group for a package
+ \param helper responsible for error and message handling */
+ static std::map<unsigned short, PackageSet> GroupedFromCommandLine(
+ pkgCacheFile &Cache, const char **cmdline,
+ std::list<PackageSet::Modifier> const &mods,
+ unsigned short const &fallback, CacheSetHelper &helper);
+ static std::map<unsigned short, PackageSet> GroupedFromCommandLine(
+ pkgCacheFile &Cache, const char **cmdline,
+ std::list<PackageSet::Modifier> const &mods,
+ unsigned short const &fallback) {
+ CacheSetHelper helper;
+ return APT::PackageSet::GroupedFromCommandLine(Cache, cmdline,
+ mods, fallback, helper);
+ }
+
+ enum Constructor { UNKNOWN, REGEX, TASK };
+ Constructor getConstructor() const { return ConstructedBy; };
+
+ PackageSet() : ConstructedBy(UNKNOWN) {};
+ PackageSet(Constructor const &by) : ConstructedBy(by) {};
+ /*}}}*/
+private: /*{{{*/
+ Constructor ConstructedBy;
+ /*}}}*/
+}; /*}}}*/
+class VersionSet : public std::set<pkgCache::VerIterator> { /*{{{*/
+/** \class APT::VersionSet
+
+ Simple wrapper around a std::set to provide a similar interface to
+ a set of versions as to the complete set of all versions in the
+ pkgCache. */
+public: /*{{{*/
+ /** \brief smell like a pkgCache::VerIterator */
+ class const_iterator : public std::set<pkgCache::VerIterator>::const_iterator {/*{{{*/
+ public:
+ const_iterator(std::set<pkgCache::VerIterator>::const_iterator x) :
+ std::set<pkgCache::VerIterator>::const_iterator(x) {}
+
+ operator pkgCache::VerIterator(void) { return **this; }
+
+ inline pkgCache *Cache() const { return (**this).Cache(); };
+ inline unsigned long Index() const {return (**this).Index();};
+ // we have only valid iterators here
+ inline bool end() const { return false; };
+
+ inline pkgCache::Version const * operator->() const {
+ return &***this;
+ };
+
+ inline int CompareVer(const pkgCache::VerIterator &B) const { return (**this).CompareVer(B); };
+ inline const char *VerStr() const { return (**this).VerStr(); };
+ inline const char *Section() const { return (**this).Section(); };
+ inline const char *Arch() const { return (**this).Arch(); };
+ inline const char *Arch(bool const pseudo) const { return (**this).Arch(pseudo); };
+ inline pkgCache::PkgIterator ParentPkg() const { return (**this).ParentPkg(); };
+ inline pkgCache::DescIterator DescriptionList() const { return (**this).DescriptionList(); };
+ inline pkgCache::DescIterator TranslatedDescription() const { return (**this).TranslatedDescription(); };
+ inline pkgCache::DepIterator DependsList() const { return (**this).DependsList(); };
+ inline pkgCache::PrvIterator ProvidesList() const { return (**this).ProvidesList(); };
+ inline pkgCache::VerFileIterator FileList() const { return (**this).FileList(); };
+ inline bool Downloadable() const { return (**this).Downloadable(); };
+ inline const char *PriorityType() const { return (**this).PriorityType(); };
+ inline string RelStr() const { return (**this).RelStr(); };
+ inline bool Automatic() const { return (**this).Automatic(); };
+ inline bool Pseudo() const { return (**this).Pseudo(); };
+ inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); };
+ };
+ /*}}}*/
+ // 103. set::iterator is required to be modifiable, but this allows modification of keys
+ typedef APT::VersionSet::const_iterator iterator;
+
+ using std::set<pkgCache::VerIterator>::insert;
+ inline void insert(pkgCache::VerIterator const &V) { if (V.end() == false) std::set<pkgCache::VerIterator>::insert(V); };
+ inline void insert(VersionSet const &verset) { insert(verset.begin(), verset.end()); };
+
+ /** \brief specifies which version(s) will be returned if non is given */
+ enum Version {
+ /** All versions */
+ ALL,
+ /** Candidate and installed version */
+ CANDANDINST,
+ /** Candidate version */
+ CANDIDATE,
+ /** Installed version */
+ INSTALLED,
+ /** Candidate or if non installed version */
+ CANDINST,
+ /** Installed or if non candidate version */
+ INSTCAND,
+ /** Newest version */
+ NEWEST
+ };
+
+ /** \brief returns all versions specified on the commandline
+
+ Get all versions from the commandline, uses given default version if
+ non specifically requested and executes regex's if needed on names.
+ \param Cache the packages and versions are in
+ \param cmdline Command line the versions should be extracted from
+ \param helper responsible for error and message handling */
+ static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
+ APT::VersionSet::Version const &fallback, CacheSetHelper &helper);
+ static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
+ APT::VersionSet::Version const &fallback) {
+ CacheSetHelper helper;
+ return APT::VersionSet::FromCommandLine(Cache, cmdline, fallback, helper);
+ }
+ static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
+ return APT::VersionSet::FromCommandLine(Cache, cmdline, CANDINST);
+ }
+
+ static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg,
+ APT::VersionSet::Version const &fallback, CacheSetHelper &helper,
+ bool const &onlyFromName = false);
+ static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg,
+ APT::VersionSet::Version const &fallback) {
+ CacheSetHelper helper;
+ return APT::VersionSet::FromString(Cache, pkg, fallback, helper);
+ }
+ static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg) {
+ return APT::VersionSet::FromString(Cache, pkg, CANDINST);
+ }
+
+ /** \brief returns all versions specified for the package
+
+ \param Cache the package and versions are in
+ \param P the package in question
+ \param fallback the version(s) you want to get
+ \param helper the helper used for display and error handling */
+ static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
+ VersionSet::Version const &fallback, CacheSetHelper &helper);
+ static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
+ APT::VersionSet::Version const &fallback) {
+ CacheSetHelper helper;
+ return APT::VersionSet::FromPackage(Cache, P, fallback, helper);
+ }
+ static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
+ return APT::VersionSet::FromPackage(Cache, P, CANDINST);
+ }
+
+ struct Modifier {
+ enum Position { NONE, PREFIX, POSTFIX };
+ unsigned short ID;
+ const char * const Alias;
+ Position Pos;
+ VersionSet::Version SelectVersion;
+ Modifier (unsigned short const &id, const char * const alias, Position const &pos,
+ VersionSet::Version const &select) : ID(id), Alias(alias), Pos(pos),
+ SelectVersion(select) {};
+ };
+
+ static std::map<unsigned short, VersionSet> GroupedFromCommandLine(
+ pkgCacheFile &Cache, const char **cmdline,
+ std::list<VersionSet::Modifier> const &mods,
+ unsigned short const &fallback, CacheSetHelper &helper);
+ static std::map<unsigned short, VersionSet> GroupedFromCommandLine(
+ pkgCacheFile &Cache, const char **cmdline,
+ std::list<VersionSet::Modifier> const &mods,
+ unsigned short const &fallback) {
+ CacheSetHelper helper;
+ return APT::VersionSet::GroupedFromCommandLine(Cache, cmdline,
+ mods, fallback, helper);
+ }
+ /*}}}*/
+protected: /*{{{*/
+
+ /** \brief returns the candidate version of the package
+
+ \param Cache to be used to query for information
+ \param Pkg we want the candidate version from this package */
+ static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
+
+ /** \brief returns the installed version of the package
+
+ \param Cache to be used to query for information
+ \param Pkg we want the installed version from this package */
+ static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
+ /*}}}*/
+}; /*}}}*/
+}
+#endif
diff --git a/cmdline/makefile b/cmdline/makefile
index 917ccc96a..4ffe49ee0 100644
--- a/cmdline/makefile
+++ b/cmdline/makefile
@@ -9,14 +9,14 @@ include ../buildlib/defaults.mak
PROGRAM=apt-cache
SLIBS = -lapt-pkg $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
-SOURCE = apt-cache.cc
+SOURCE = apt-cache.cc cacheset.cc
include $(PROGRAM_H)
# The apt-get program
PROGRAM=apt-get
SLIBS = -lapt-pkg -lutil $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
-SOURCE = apt-get.cc acqprogress.cc
+SOURCE = apt-get.cc acqprogress.cc cacheset.cc
include $(PROGRAM_H)
# The apt-config program