From d8276801a1c84582a85ed9ea1f2eb4e66e052e6b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 15 Jun 2010 20:46:09 +0200 Subject: * cmdline/cacheset.cc: - doesn't include it in the library for now as it is too volatile --- cmdline/cacheset.cc | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++++ cmdline/cacheset.h | 274 +++++++++++++++++++++++++++++++++++++++++++ cmdline/makefile | 4 +- 3 files changed, 606 insertions(+), 2 deletions(-) create mode 100644 cmdline/cacheset.cc create mode 100644 cmdline/cacheset.h (limited to 'cmdline') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc new file mode 100644 index 000000000..fde52168a --- /dev/null +++ b/cmdline/cacheset.cc @@ -0,0 +1,330 @@ +// -*- 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 +#include +#include +#include +#include + +#include + +#include + +#include + /*}}}*/ +namespace APT { +// FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ +PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { + PackageSet pkgset; + std::string arch = "native"; + static const char * const isregex = ".?+*|[^$"; + + if (pattern.find_first_of(isregex) == std::string::npos) + return pkgset; + + size_t archfound = pattern.find_last_of(':'); + 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 pkgset; + } + + 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 archs = APT::Configuration::getArchitectures(); + for (std::vector::const_iterator a = archs.begin(); + a != archs.end() && Pkg.end() != true; ++a) + Pkg = Grp.FindPkg(*a); + } + if (Pkg.end() == true) + continue; + } + + ioprintf(out, _("Note, selecting %s for regex '%s'\n"), + Pkg.FullName(true).c_str(), pattern.c_str()); + + pkgset.insert(Pkg); + } + + regfree(&Pattern); + + return pkgset; +} + /*}}}*/ +// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ +std::map PackageSet::GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, std::ostream &out) { + std::map pkgsets; + for (const char **I = cmdline; *I != 0; ++I) { + unsigned short modID = fallback; + std::string str = *I; + for (std::list::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; + } + break; + } + PackageSet pset = PackageSet::FromString(Cache, str, out); + pkgsets[modID].insert(pset.begin(), pset.end()); + } + return pkgsets; +} + /*}}}*/ +// FromCommandLine - Return all packages specified on commandline /*{{{*/ +PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out) { + PackageSet pkgset; + for (const char **I = cmdline; *I != 0; ++I) { + PackageSet pset = FromString(Cache, *I, out); + 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, std::ostream &out) { + 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); + } + + pkgCache::PkgIterator Pkg; + 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() == false) { + PackageSet pkgset; + pkgset.insert(Pkg); + return pkgset; + } + PackageSet regex = FromRegEx(Cache, str, out); + if (regex.empty() == true) + _error->Warning(_("Unable to locate package %s"), str.c_str()); + return regex; +} + /*}}}*/ +// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ +std::map VersionSet::GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, std::ostream &out) { + std::map versets; + for (const char **I = cmdline; *I != 0; ++I) { + unsigned short modID = fallback; + VersionSet::Version select = VersionSet::NEWEST; + std::string str = *I; + for (std::list::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; + } + break; + } + VersionSet vset = VersionSet::FromString(Cache, str, select , out); + versets[modID].insert(vset.begin(), vset.end()); + } + return versets; +} + /*}}}*/ +// FromCommandLine - Return all versions specified on commandline /*{{{*/ +APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + APT::VersionSet::Version const &fallback, std::ostream &out) { + VersionSet verset; + for (const char **I = cmdline; *I != 0; ++I) { + VersionSet vset = VersionSet::FromString(Cache, *I, fallback, out); + verset.insert(vset.begin(), vset.end()); + } + return verset; +} + /*}}}*/ +// FromString - Returns all versions spedcified by a string /*{{{*/ +APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, + APT::VersionSet::Version const &fallback, std::ostream &out) { + 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 = PackageSet::FromString(Cache, pkg.c_str(), out); + VersionSet verset; + for (PackageSet::const_iterator P = pkgset.begin(); + P != pkgset.end(); ++P) { + if (vertag == string::npos) { + AddSelectedVersion(Cache, verset, P, fallback); + continue; + } + pkgCache::VerIterator V; + if (ver == "installed") + V = getInstalledVer(Cache, P); + else if (ver == "candidate") + V = getCandidateVer(Cache, P); + 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; + if (ver == V.VerStr()) + ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), + V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); + verset.insert(V); + } + return verset; +} + /*}}}*/ +// AddSelectedVersion - add version from package based on fallback /*{{{*/ +bool VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, + pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, + bool const &AllowError) { + pkgCache::VerIterator V; + switch(fallback) { + case VersionSet::ALL: + if (P->VersionList != 0) + for (V = P.VersionList(); V.end() != true; ++V) + verset.insert(V); + else if (AllowError == false) + return _error->Error(_("Can't select versions from package '%s' as it purely virtual"), P.FullName(true).c_str()); + else + return false; + break; + case VersionSet::CANDANDINST: + verset.insert(getInstalledVer(Cache, P, AllowError)); + verset.insert(getCandidateVer(Cache, P, AllowError)); + break; + case VersionSet::CANDIDATE: + verset.insert(getCandidateVer(Cache, P, AllowError)); + break; + case VersionSet::INSTALLED: + verset.insert(getInstalledVer(Cache, P, AllowError)); + break; + case VersionSet::CANDINST: + V = getCandidateVer(Cache, P, true); + if (V.end() == true) + V = getInstalledVer(Cache, P, true); + if (V.end() == false) + verset.insert(V); + else if (AllowError == false) + return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); + else + return false; + break; + case VersionSet::INSTCAND: + V = getInstalledVer(Cache, P, true); + if (V.end() == true) + V = getCandidateVer(Cache, P, true); + if (V.end() == false) + verset.insert(V); + else if (AllowError == false) + return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); + else + return false; + break; + case VersionSet::NEWEST: + if (P->VersionList != 0) + verset.insert(P.VersionList()); + else if (AllowError == false) + return _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), P.FullName(true).c_str()); + else + return false; + break; + } + return true; +} + /*}}}*/ +// getCandidateVer - Returns the candidate version of the given package /*{{{*/ +pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, bool const &AllowError) { + pkgCache::VerIterator Cand; + if (Cache.IsDepCacheBuilt() == true) + Cand = Cache[Pkg].CandidateVerIter(Cache); + else { + if (unlikely(Cache.BuildPolicy() == false)) + return pkgCache::VerIterator(*Cache); + Cand = Cache.GetPolicy()->GetCandidateVer(Pkg); + } + if (AllowError == false && Cand.end() == true) + _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); + return Cand; +} + /*}}}*/ +// getInstalledVer - Returns the installed version of the given package /*{{{*/ +pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, bool const &AllowError) { + if (AllowError == false && Pkg->CurrentVer == 0) + _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str()); + return Pkg.CurrentVer(); +} + /*}}}*/ +} diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h new file mode 100644 index 000000000..2bc268380 --- /dev/null +++ b/cmdline/cacheset.h @@ -0,0 +1,274 @@ +// -*- 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 +#include +#include +#include +#include +#include + +#include +#include + /*}}}*/ +namespace APT { +class PackageSet : public std::set { /*{{{*/ +/** \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::const_iterator { + public: + const_iterator(std::set::const_iterator x) : + std::set::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::insert; + inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set::insert(P); }; + + /** \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 out stream to print the notice to */ + static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out); + static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::FromRegEx(Cache, pattern, out); + } + + /** \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 out stream to print various notices to */ + static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, std::ostream &out); + static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::FromString(Cache, string, out); + } + + /** \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 out stream to print various notices to */ + static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out); + static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::FromCommandLine(Cache, cmdline, out); + } + + 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) {}; + }; + + static std::map GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, std::ostream &out); + static std::map GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::GroupedFromCommandLine(Cache, cmdline, + mods, fallback, out); + } + /*}}}*/ +}; /*}}}*/ +class VersionSet : public std::set { /*{{{*/ +/** \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::const_iterator { + public: + const_iterator(std::set::const_iterator x) : + std::set::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::insert; + inline void insert(pkgCache::VerIterator const &V) { if (V.end() == false) std::set::insert(V); }; + + /** \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 out stream to print various notices to */ + static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + APT::VersionSet::Version const &fallback, std::ostream &out); + static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + APT::VersionSet::Version const &fallback) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::VersionSet::FromCommandLine(Cache, cmdline, fallback, out); + } + 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, std::ostream &out); + static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, + APT::VersionSet::Version const &fallback) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::VersionSet::FromString(Cache, pkg, fallback, out); + } + static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg) { + return APT::VersionSet::FromString(Cache, pkg, 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 GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback, std::ostream &out); + static std::map GroupedFromCommandLine( + pkgCacheFile &Cache, const char **cmdline, + std::list const &mods, + unsigned short const &fallback) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::VersionSet::GroupedFromCommandLine(Cache, cmdline, + mods, fallback, out); + } + /*}}}*/ +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 + \param AllowError add an error to the stack if not */ + static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, bool const &AllowError = false); + + /** \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 + \param AllowError add an error to the stack if not */ + static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, bool const &AllowError = false); + + + static bool AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, + pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, + bool const &AllowError = false); + + /*}}}*/ +}; /*}}}*/ +} +#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 -- cgit v1.2.3 From dc0f01f7cbe2ed8ae6a1d2dbc0e00c19bb04679d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 19 Jun 2010 11:49:38 +0200 Subject: get packages by task^ with FromTask() --- cmdline/cacheset.cc | 76 ++++++++++++++++++++++++++++++++++++++++++++++++----- cmdline/cacheset.h | 20 ++++++++++++-- 2 files changed, 87 insertions(+), 9 deletions(-) (limited to 'cmdline') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index fde52168a..55ab26780 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -11,27 +11,83 @@ // Include Files /*{{{*/ #include #include -#include #include #include #include +#include "cacheset.h" + #include #include /*}}}*/ namespace APT { +// FromTask - Return all packages in the cache from a specific task /*{{{*/ +PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { + PackageSet pkgset; + if (Cache.BuildCaches() == false || Cache.BuildDepCache() == false) + return pkgset; + + size_t 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 pkgset; + pattern.erase(pattern.length()-1); + + // 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) + pkgset.insert(Pkg); + } + + if (pkgset.empty() == true) + _error->Error(_("Couldn't find task %s"), pattern.c_str()); + + regfree(&Pattern); + return pkgset; +} + /*}}}*/ // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { PackageSet pkgset; - std::string arch = "native"; static const char * const isregex = ".?+*|[^$"; if (pattern.find_first_of(isregex) == std::string::npos) return pkgset; 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) @@ -142,10 +198,16 @@ PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, s pkgset.insert(Pkg); return pkgset; } - PackageSet regex = FromRegEx(Cache, str, out); - if (regex.empty() == true) - _error->Warning(_("Unable to locate package %s"), str.c_str()); - return regex; + PackageSet pset = FromTask(Cache, str, out); + if (pset.empty() == false) + return pset; + + pset = FromRegEx(Cache, str, out); + if (pset.empty() == false) + return pset; + + _error->Warning(_("Unable to locate package %s"), str.c_str()); + return pset; } /*}}}*/ // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ @@ -236,7 +298,7 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, } if (V.end() == true) continue; - if (ver == V.VerStr()) + if (ver != V.VerStr()) ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); verset.insert(V); diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index 2bc268380..64a72e758 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -28,7 +28,7 @@ class PackageSet : public std::set { /*{{{*/ pkgCache. */ public: /*{{{*/ /** \brief smell like a pkgCache::PkgIterator */ - class const_iterator : public std::set::const_iterator { + class const_iterator : public std::set::const_iterator {/*{{{*/ public: const_iterator(std::set::const_iterator x) : std::set::const_iterator(x) {} @@ -62,10 +62,25 @@ public: /*{{{*/ }; // 103. set::iterator is required to be modifiable, but this allows modification of keys typedef APT::PackageSet::const_iterator iterator; + /*}}}*/ using std::set::insert; inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set::insert(P); }; + /** \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 out stream to print the notice to */ + static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, std::ostream &out); + static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::FromTask(Cache, pattern, out); + } + /** \brief returns all packages in the cache whose name matchs a given pattern A simple helper responsible for executing a regular expression on all @@ -134,7 +149,7 @@ class VersionSet : public std::set { /*{{{*/ pkgCache. */ public: /*{{{*/ /** \brief smell like a pkgCache::VerIterator */ - class const_iterator : public std::set::const_iterator { + class const_iterator : public std::set::const_iterator {/*{{{*/ public: const_iterator(std::set::const_iterator x) : std::set::const_iterator(x) {} @@ -168,6 +183,7 @@ public: /*{{{*/ 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; -- cgit v1.2.3 From 313678129b6f8ad37216db0b4e7679059ab37e56 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 19 Jun 2010 14:16:40 +0200 Subject: * cmdline/apt-get.cc: - use the cachsets in the install commands --- cmdline/apt-cache.cc | 3 +- cmdline/apt-get.cc | 249 ++++++++++----------------------------------------- 2 files changed, 49 insertions(+), 203 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 7cb95b3f8..2332a0f13 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -29,7 +29,8 @@ #include #include #include -#include + +#include "cacheset.h" #include #include diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 0ada46c73..c081ca130 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -40,12 +40,12 @@ #include #include #include -#include #include #include #include "acqprogress.h" +#include "cacheset.h" #include #include @@ -1252,41 +1252,6 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, 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"))); - return true; } /*}}}*/ @@ -1624,61 +1589,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 */ @@ -1696,138 +1606,73 @@ bool DoInstall(CommandLine &CmdL) unsigned int AutoMarkChanged = 0; unsigned int ExpectedInst = 0; - unsigned int Packages = 0; pkgProblemResolver Fix(Cache); - - bool DefRemove = false; + + unsigned short fallback = 0; if (strcasecmp(CmdL.FileList[0],"remove") == 0) - DefRemove = true; + fallback = 1; else if (strcasecmp(CmdL.FileList[0], "purge") == 0) { _config->Set("APT::Get::Purge", true); - DefRemove = true; + fallback = 1; } else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0) { _config->Set("APT::Get::AutomaticRemove", "true"); - DefRemove = true; + fallback = 1; } // new scope for the ActionGroup { + // TODO: Howto get an ExpectedInst count ? 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; + std::list mods; + mods.push_back(APT::VersionSet::Modifier(0, "+", + APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDINST)); + mods.push_back(APT::VersionSet::Modifier(1, "-", + APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::INSTCAND)); + std::map verset = APT::VersionSet::GroupedFromCommandLine(Cache, + CmdL.FileList + 1, mods, fallback, c0out); - // 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; - } + if (_error->PendingError() == true) + return false; - while (Cache->FindPkg(S).end() == true) + for (APT::VersionSet::const_iterator Ver = verset[0].begin(); + Ver != verset[0].end(); ++Ver) + { + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + Cache->SetCandidateVersion(Ver); + + if (TryToInstall(Pkg, Cache, Fix, false, 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 (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) { - // 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; + ioprintf(c1out,_("%s set to manually installed.\n"), + Pkg.FullName(true).c_str()); + Cache->MarkAuto(Pkg,false); + AutoMarkChanged++; } - - // 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); - - // Regexs must always be confirmed - ExpectedInst += 1000; - - 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; + } - Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix, - ExpectedInst,false); - } + for (APT::VersionSet::const_iterator Ver = verset[1].begin(); + Ver != verset[1].end(); ++Ver) + { + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - if (Hit == false) - return _error->Error(_("Couldn't find package %s"),S); - } - 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++; - } - } + if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix, ExpectedInst) == false) + return false; } + 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 */ -- cgit v1.2.3 From 70e706adf75ed319d931a220ce27db2b981093f5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 22 Jun 2010 18:01:11 +0200 Subject: =?UTF-8?q?Use=20an=20abstract=20helper=20for=20error=20handling?= =?UTF-8?q?=20and=20output=20instead=20of=20doing=20this=20directly=20in?= =?UTF-8?q?=20the=20CacheSets.=20With=20this=20method=20an=20application?= =?UTF-8?q?=20like=20apt-get=20can=20change=20the=20behavior=20of=20the=20?= =?UTF-8?q?CacheSets=20to=20his=20liking.=20It=20can=20for=20example=20eas?= =?UTF-8?q?ily=20keep=20track=20of=20how=20packages=20were=20added=20to=20?= =?UTF-8?q?the=20set:=20by=20names=20or=20with=20regex's=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmdline/apt-get.cc | 79 ++++++++++++++++------- cmdline/cacheset.cc | 179 ++++++++++++++++++++++++++++++++++------------------ cmdline/cacheset.h | 104 ++++++++++++++++++++---------- 3 files changed, 244 insertions(+), 118 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index c081ca130..6a7d7a448 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1079,7 +1079,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, name matching it was split out.. */ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &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. */ @@ -1244,9 +1244,7 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, 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) @@ -1589,6 +1587,41 @@ bool DoUpgrade(CommandLine &CmdL) return InstallPackages(Cache,true); } /*}}}*/ +// 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; + +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()); + } + + inline bool allPkgNamedExplicitly() const { return explicitlyNamed; } + +}; + /*}}}*/ // DoInstall - Install packages from the command line /*{{{*/ // --------------------------------------------------------------------- /* Install named packages */ @@ -1605,7 +1638,6 @@ bool DoInstall(CommandLine &CmdL) BrokenFix = true; unsigned int AutoMarkChanged = 0; - unsigned int ExpectedInst = 0; pkgProblemResolver Fix(Cache); unsigned short fallback = 0; @@ -1621,28 +1653,29 @@ bool DoInstall(CommandLine &CmdL) _config->Set("APT::Get::AutomaticRemove", "true"); fallback = 1; } - // new scope for the ActionGroup - { - // TODO: Howto get an ExpectedInst count ? - pkgDepCache::ActionGroup group(Cache); - std::list mods; - mods.push_back(APT::VersionSet::Modifier(0, "+", + + std::list mods; + mods.push_back(APT::VersionSet::Modifier(0, "+", APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDINST)); - mods.push_back(APT::VersionSet::Modifier(1, "-", + mods.push_back(APT::VersionSet::Modifier(1, "-", APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::INSTCAND)); - std::map verset = APT::VersionSet::GroupedFromCommandLine(Cache, - CmdL.FileList + 1, mods, fallback, c0out); + CacheSetHelperAPTGet helper(c0out); + std::map verset = APT::VersionSet::GroupedFromCommandLine(Cache, + CmdL.FileList + 1, mods, fallback, helper); - if (_error->PendingError() == true) - return false; + if (_error->PendingError() == true) + return false; + // new scope for the ActionGroup + { + pkgDepCache::ActionGroup group(Cache); for (APT::VersionSet::const_iterator Ver = verset[0].begin(); Ver != verset[0].end(); ++Ver) { pkgCache::PkgIterator Pkg = Ver.ParentPkg(); Cache->SetCandidateVersion(Ver); - if (TryToInstall(Pkg, Cache, Fix, false, BrokenFix, ExpectedInst) == false) + if (TryToInstall(Pkg, Cache, Fix, false, BrokenFix) == false) return false; // see if we need to fix the auto-mark flag @@ -1666,7 +1699,7 @@ bool DoInstall(CommandLine &CmdL) { pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix, ExpectedInst) == false) + if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix) == false) return false; } @@ -1719,7 +1752,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[0].size()) { string List; string VersionsList; @@ -1845,7 +1878,8 @@ bool DoInstall(CommandLine &CmdL) 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[0].size() && Cache->DelCount() == 0) return InstallPackages(Cache,false,false); return InstallPackages(Cache,false); @@ -2429,7 +2463,6 @@ bool DoBuildDep(CommandLine &CmdL) } // Install the requested packages - unsigned int ExpectedInst = 0; vector ::iterator D; pkgProblemResolver Fix(Cache); bool skipAlternatives = false; // skip remaining alternatives in an or group @@ -2460,7 +2493,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); + TryToInstall(Pkg,Cache,Fix,true,false); } else // BuildDep || BuildDepIndep { @@ -2576,7 +2609,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 (TryToInstall(Pkg,Cache,Fix,false,false) == true) { // We successfully installed something; skip remaining alternatives skipAlternatives = hasAlternatives; diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 55ab26780..88a98fdbe 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -24,7 +24,7 @@ /*}}}*/ namespace APT { // FromTask - Return all packages in the cache from a specific task /*{{{*/ -PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { +PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { PackageSet pkgset; if (Cache.BuildCaches() == false || Cache.BuildDepCache() == false) return pkgset; @@ -67,19 +67,22 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, std::o char buf[length]; strncpy(buf, start, length); buf[length-1] = '\0'; - if (regexec(&Pattern, buf, 0, 0, 0) == 0) - pkgset.insert(Pkg); + if (regexec(&Pattern, buf, 0, 0, 0) != 0) + continue; + + pkgset.insert(Pkg); } + regfree(&Pattern); if (pkgset.empty() == true) - _error->Error(_("Couldn't find task %s"), pattern.c_str()); + return helper.canNotFindTask(Cache, pattern); - regfree(&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, std::ostream &out) { +PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { PackageSet pkgset; static const char * const isregex = ".?+*|[^$"; @@ -121,14 +124,14 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std:: continue; } - ioprintf(out, _("Note, selecting %s for regex '%s'\n"), - Pkg.FullName(true).c_str(), pattern.c_str()); - pkgset.insert(Pkg); } - regfree(&Pattern); + if (pkgset.empty() == true) + return helper.canNotFindRegEx(Cache, pattern); + + helper.showRegExSelection(pkgset, pattern); return pkgset; } /*}}}*/ @@ -136,7 +139,7 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std:: std::map PackageSet::GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, - unsigned short const &fallback, std::ostream &out) { + unsigned short const &fallback, CacheSetHelper &helper) { std::map pkgsets; for (const char **I = cmdline; *I != 0; ++I) { unsigned short modID = fallback; @@ -159,24 +162,23 @@ std::map PackageSet::GroupedFromCommandLine( } break; } - PackageSet pset = PackageSet::FromString(Cache, str, out); - pkgsets[modID].insert(pset.begin(), pset.end()); + 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, std::ostream &out) { +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, out); + 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, std::ostream &out) { +PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) { std::string pkg = str; size_t archfound = pkg.find_last_of(':'); std::string arch; @@ -198,23 +200,22 @@ PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, s pkgset.insert(Pkg); return pkgset; } - PackageSet pset = FromTask(Cache, str, out); + PackageSet pset = FromTask(Cache, str, helper); if (pset.empty() == false) return pset; - pset = FromRegEx(Cache, str, out); + pset = FromRegEx(Cache, str, helper); if (pset.empty() == false) return pset; - _error->Warning(_("Unable to locate package %s"), str.c_str()); - return pset; + return helper.canNotFindPackage(Cache, str); } /*}}}*/ // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ std::map VersionSet::GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, - unsigned short const &fallback, std::ostream &out) { + unsigned short const &fallback, CacheSetHelper &helper) { std::map versets; for (const char **I = cmdline; *I != 0; ++I) { unsigned short modID = fallback; @@ -241,18 +242,17 @@ std::map VersionSet::GroupedFromCommandLine( } break; } - VersionSet vset = VersionSet::FromString(Cache, str, select , out); - versets[modID].insert(vset.begin(), vset.end()); + 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, std::ostream &out) { + APT::VersionSet::Version const &fallback, CacheSetHelper &helper) { VersionSet verset; for (const char **I = cmdline; *I != 0; ++I) { - VersionSet vset = VersionSet::FromString(Cache, *I, fallback, out); + VersionSet vset = VersionSet::FromString(Cache, *I, fallback, helper); verset.insert(vset.begin(), vset.end()); } return verset; @@ -260,7 +260,7 @@ APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cm /*}}}*/ // FromString - Returns all versions spedcified by a string /*{{{*/ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback, std::ostream &out) { + APT::VersionSet::Version const &fallback, CacheSetHelper &helper) { std::string ver; bool verIsRel = false; size_t const vertag = pkg.find_last_of("/="); @@ -269,19 +269,19 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, verIsRel = (pkg[vertag] == '/'); pkg.erase(vertag); } - PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), out); + PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), helper); VersionSet verset; for (PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) { if (vertag == string::npos) { - AddSelectedVersion(Cache, verset, P, fallback); + AddSelectedVersion(Cache, verset, P, fallback, helper); continue; } pkgCache::VerIterator V; if (ver == "installed") - V = getInstalledVer(Cache, P); + V = getInstalledVer(Cache, P, helper); else if (ver == "candidate") - V = getCandidateVer(Cache, P); + V = getCandidateVer(Cache, P, helper); else { pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : pkgVersionMatch::Version)); @@ -298,76 +298,70 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, } if (V.end() == true) continue; - if (ver != V.VerStr()) - ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), - V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); + helper.showSelectedVersion(P, V, ver, verIsRel); verset.insert(V); } return verset; } /*}}}*/ // AddSelectedVersion - add version from package based on fallback /*{{{*/ -bool VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, +void VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, - bool const &AllowError) { + CacheSetHelper &helper) { 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 if (AllowError == false) - return _error->Error(_("Can't select versions from package '%s' as it purely virtual"), P.FullName(true).c_str()); else - return false; + verset.insert(helper.canNotFindAllVer(Cache, P)); break; case VersionSet::CANDANDINST: - verset.insert(getInstalledVer(Cache, P, AllowError)); - verset.insert(getCandidateVer(Cache, P, AllowError)); + verset.insert(getInstalledVer(Cache, P, helper)); + verset.insert(getCandidateVer(Cache, P, helper)); break; case VersionSet::CANDIDATE: - verset.insert(getCandidateVer(Cache, P, AllowError)); + verset.insert(getCandidateVer(Cache, P, helper)); break; case VersionSet::INSTALLED: - verset.insert(getInstalledVer(Cache, P, AllowError)); + verset.insert(getInstalledVer(Cache, P, helper)); break; case VersionSet::CANDINST: - V = getCandidateVer(Cache, P, true); + showErrors = helper.showErrors(false); + V = getCandidateVer(Cache, P, helper); if (V.end() == true) - V = getInstalledVer(Cache, P, true); + V = getInstalledVer(Cache, P, helper); + helper.showErrors(showErrors); if (V.end() == false) verset.insert(V); - else if (AllowError == false) - return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); else - return false; + verset.insert(helper.canNotFindInstCandVer(Cache, P)); break; case VersionSet::INSTCAND: - V = getInstalledVer(Cache, P, true); + showErrors = helper.showErrors(false); + V = getInstalledVer(Cache, P, helper); if (V.end() == true) - V = getCandidateVer(Cache, P, true); + V = getCandidateVer(Cache, P, helper); + helper.showErrors(showErrors); if (V.end() == false) verset.insert(V); - else if (AllowError == false) - return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str()); else - return false; + verset.insert(helper.canNotFindInstCandVer(Cache, P)); break; case VersionSet::NEWEST: if (P->VersionList != 0) verset.insert(P.VersionList()); - else if (AllowError == false) - return _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), P.FullName(true).c_str()); else - return false; + verset.insert(helper.canNotFindNewestVer(Cache, P)); break; } - return true; } /*}}}*/ // getCandidateVer - Returns the candidate version of the given package /*{{{*/ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, bool const &AllowError) { + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) { pkgCache::VerIterator Cand; if (Cache.IsDepCacheBuilt() == true) Cand = Cache[Pkg].CandidateVerIter(Cache); @@ -376,17 +370,78 @@ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, return pkgCache::VerIterator(*Cache); Cand = Cache.GetPolicy()->GetCandidateVer(Pkg); } - if (AllowError == false && Cand.end() == true) - _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str()); + 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, bool const &AllowError) { - if (AllowError == false && Pkg->CurrentVer == 0) - _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str()); + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) { + if (Pkg->CurrentVer == 0) + return helper.canNotFindInstalledVer(Cache, Pkg); return Pkg.CurrentVer(); } /*}}}*/ +// 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) { + if (ShowError == true) + _error->Error(_("Unable to locate package %s"), str.c_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(); +} + /*}}}*/ +// 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); +} + /*}}}*/ +// 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); +} + /*}}}*/ +// 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); +} + /*}}}*/ } diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index 64a72e758..9c9491020 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -20,6 +20,45 @@ #include /*}}}*/ 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 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 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 { /*{{{*/ /** \class APT::PackageSet @@ -66,6 +105,7 @@ public: /*{{{*/ using std::set::insert; inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set::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 @@ -75,10 +115,10 @@ public: /*{{{*/ \param Cache the packages are in \param pattern name of the task \param out stream to print the notice to */ - static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, std::ostream &out); + static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromTask(Cache, pattern, out); + CacheSetHelper helper; + return APT::PackageSet::FromTask(Cache, pattern, helper); } /** \brief returns all packages in the cache whose name matchs a given pattern @@ -89,10 +129,10 @@ public: /*{{{*/ \param Cache the packages are in \param pattern regular expression for package names \param out stream to print the notice to */ - static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out); + static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper); static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromRegEx(Cache, pattern, out); + CacheSetHelper helper; + return APT::PackageSet::FromRegEx(Cache, pattern, helper); } /** \brief returns all packages specified by a string @@ -100,10 +140,10 @@ public: /*{{{*/ \param Cache the packages are in \param string String the package name(s) should be extracted from \param out stream to print various notices to */ - static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, std::ostream &out); + static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper); static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromString(Cache, string, out); + CacheSetHelper helper; + return APT::PackageSet::FromString(Cache, string, helper); } /** \brief returns all packages specified on the commandline @@ -113,10 +153,10 @@ public: /*{{{*/ \param Cache the packages are in \param cmdline Command line the package names should be extracted from \param out stream to print various notices to */ - static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out); + static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper); static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::PackageSet::FromCommandLine(Cache, cmdline, out); + CacheSetHelper helper; + return APT::PackageSet::FromCommandLine(Cache, cmdline, helper); } struct Modifier { @@ -130,14 +170,14 @@ public: /*{{{*/ static std::map GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, - unsigned short const &fallback, std::ostream &out); + unsigned short const &fallback, CacheSetHelper &helper); static std::map GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, unsigned short const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); + CacheSetHelper helper; return APT::PackageSet::GroupedFromCommandLine(Cache, cmdline, - mods, fallback, out); + mods, fallback, helper); } /*}}}*/ }; /*}}}*/ @@ -189,6 +229,7 @@ public: /*{{{*/ using std::set::insert; inline void insert(pkgCache::VerIterator const &V) { if (V.end() == false) std::set::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 { @@ -216,22 +257,22 @@ public: /*{{{*/ \param cmdline Command line the versions should be extracted from \param out stream to print various notices to */ static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, - APT::VersionSet::Version const &fallback, std::ostream &out); + APT::VersionSet::Version const &fallback, CacheSetHelper &helper); static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, APT::VersionSet::Version const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::VersionSet::FromCommandLine(Cache, cmdline, fallback, out); + 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, std::ostream &out); + APT::VersionSet::Version const &fallback, CacheSetHelper &helper); static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, APT::VersionSet::Version const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); - return APT::VersionSet::FromString(Cache, pkg, fallback, out); + 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); @@ -251,14 +292,14 @@ public: /*{{{*/ static std::map GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, - unsigned short const &fallback, std::ostream &out); + unsigned short const &fallback, CacheSetHelper &helper); static std::map GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, unsigned short const &fallback) { - std::ostream out (std::ofstream("/dev/null").rdbuf()); + CacheSetHelper helper; return APT::VersionSet::GroupedFromCommandLine(Cache, cmdline, - mods, fallback, out); + mods, fallback, helper); } /*}}}*/ protected: /*{{{*/ @@ -266,23 +307,20 @@ 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 - \param AllowError add an error to the stack if not */ + \param Pkg we want the candidate version from this package */ static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, bool const &AllowError = false); + 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 - \param AllowError add an error to the stack if not */ + \param Pkg we want the installed version from this package */ static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache, - pkgCache::PkgIterator const &Pkg, bool const &AllowError = false); - + pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper); - static bool AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, + static void AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, - bool const &AllowError = false); + CacheSetHelper &helper); /*}}}*/ }; /*}}}*/ -- cgit v1.2.3 From 65beb5720f82845bf175e0cd80f070da21838827 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 25 Jun 2010 20:11:11 +0200 Subject: print all messages if the application is in an interactive run --- cmdline/apt-cache.cc | 12 +++++------- cmdline/apt-cdrom.cc | 12 +++++------- cmdline/apt-get.cc | 12 +++++------- 3 files changed, 15 insertions(+), 21 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 2332a0f13..a4ec63eed 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1876,13 +1876,11 @@ int main(int argc,const char *argv[]) /*{{{*/ 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..da2ffa390 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -273,13 +273,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/apt-get.cc b/cmdline/apt-get.cc index 6a7d7a448..605eedb0f 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2920,13 +2920,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; } /*}}}*/ -- cgit v1.2.3 From c340d1851242e691e7e0baad18a662d6c7a62bc8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 26 Jun 2010 19:04:20 +0200 Subject: do not override the user set quiet setting even if the target is not a tty --- cmdline/apt-cache.cc | 2 +- cmdline/apt-cdrom.cc | 2 +- cmdline/apt-get.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index a4ec63eed..a5b3141d7 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1868,7 +1868,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"); // if (_config->FindB("APT::Cache::Generate",true) == false) diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index da2ffa390..d1268edf9 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -266,7 +266,7 @@ 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 diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 605eedb0f..e3477b6db 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2899,7 +2899,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 -- cgit v1.2.3 From 320352e00477f3b0cfd12efd736bd08c7908fecc Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 26 Jun 2010 19:22:23 +0200 Subject: give the APT::Cache::Generate option her effect back --- cmdline/apt-cache.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'cmdline') diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index a5b3141d7..c790559e7 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1871,7 +1871,9 @@ int main(int argc,const char *argv[]) /*{{{*/ 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); -- cgit v1.2.3 From 48c39e3246b72802a6f723eef1ce0c30e06be33d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 26 Jun 2010 21:17:34 +0200 Subject: - only print errors if all tries to get a package by string failed * --- cmdline/cacheset.cc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'cmdline') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 88a98fdbe..2b00187d8 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -200,15 +200,21 @@ PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, C pkgset.insert(Pkg); return pkgset; } + + _error->PushToStack(); + PackageSet pset = FromTask(Cache, str, helper); - if (pset.empty() == false) - return pset; + if (pset.empty() == true) { + pset = FromRegEx(Cache, str, helper); + if (pset.empty() == true) + pset = helper.canNotFindPackage(Cache, str); + } - pset = FromRegEx(Cache, str, helper); if (pset.empty() == false) - return pset; - - return helper.canNotFindPackage(Cache, str); + _error->RevertToStack(); + else + _error->MergeWithStack(); + return pset; } /*}}}*/ // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ -- cgit v1.2.3 From bd631595620ca5b3c53ede4ef46c89399c26c5f3 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 28 Jun 2010 22:13:17 +0200 Subject: - factor out code to get a single package FromName() - check in Grouped* first without modifier interpretation --- cmdline/cacheset.cc | 151 ++++++++++++++++++++++++++++++++++------------------ cmdline/cacheset.h | 15 +++++- 2 files changed, 113 insertions(+), 53 deletions(-) (limited to 'cmdline') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 2b00187d8..42bc79693 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -25,11 +25,7 @@ namespace APT { // FromTask - Return all packages in the cache from a specific task /*{{{*/ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { - PackageSet pkgset; - if (Cache.BuildCaches() == false || Cache.BuildDepCache() == false) - return pkgset; - - size_t archfound = pattern.find_last_of(':'); + size_t const archfound = pattern.find_last_of(':'); std::string arch = "native"; if (archfound != std::string::npos) { arch = pattern.substr(archfound+1); @@ -37,9 +33,13 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS } if (pattern[pattern.length() -1] != '^') - return pkgset; + return APT::PackageSet(); pattern.erase(pattern.length()-1); + if (unlikely(Cache.GetPkgCache() == 0 || Cache.GetDepCache() == 0)) + return APT::PackageSet(); + + PackageSet pkgset; // get the records pkgRecords Recs(Cache); @@ -83,11 +83,9 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS /*}}}*/ // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) { - PackageSet pkgset; static const char * const isregex = ".?+*|[^$"; - if (pattern.find_first_of(isregex) == std::string::npos) - return pkgset; + return PackageSet(); size_t archfound = pattern.find_last_of(':'); std::string arch = "native"; @@ -105,9 +103,13 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, Cache char Error[300]; regerror(Res, &Pattern, Error, sizeof(Error)); _error->Error(_("Regex compilation error - %s"), Error); - return pkgset; + return PackageSet(); } + if (unlikely(Cache.GetPkgCache() == 0)) + return PackageSet(); + + PackageSet pkgset; for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) { if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) @@ -135,6 +137,33 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, Cache 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 PackageSet::GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, @@ -144,6 +173,7 @@ std::map PackageSet::GroupedFromCommandLine( for (const char **I = cmdline; *I != 0; ++I) { unsigned short modID = fallback; std::string str = *I; + bool modifierPresent = false; for (std::list::const_iterator mod = mods.begin(); mod != mods.end(); ++mod) { size_t const alength = strlen(mod->Alias); @@ -160,8 +190,18 @@ std::map PackageSet::GroupedFromCommandLine( 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; @@ -179,42 +219,26 @@ PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline /*}}}*/ // FromString - Return all packages matching a specific string /*{{{*/ PackageSet PackageSet::FromString(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); - } - - pkgCache::PkgIterator Pkg; - 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() == false) { - PackageSet pkgset; - pkgset.insert(Pkg); - return pkgset; - } - _error->PushToStack(); - PackageSet pset = FromTask(Cache, str, helper); - if (pset.empty() == true) { - pset = FromRegEx(Cache, str, helper); - if (pset.empty() == true) - pset = helper.canNotFindPackage(Cache, str); + 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 (pset.empty() == false) + if (pkgset.empty() == false) _error->RevertToStack(); else _error->MergeWithStack(); - return pset; + return pkgset; } /*}}}*/ // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ @@ -227,6 +251,7 @@ std::map VersionSet::GroupedFromCommandLine( unsigned short modID = fallback; VersionSet::Version select = VersionSet::NEWEST; std::string str = *I; + bool modifierPresent = false; for (std::list::const_iterator mod = mods.begin(); mod != mods.end(); ++mod) { if (modID == fallback && mod->ID == fallback) @@ -246,8 +271,19 @@ std::map VersionSet::GroupedFromCommandLine( 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; @@ -257,16 +293,15 @@ std::map VersionSet::GroupedFromCommandLine( 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) { - VersionSet vset = VersionSet::FromString(Cache, *I, fallback, helper); - verset.insert(vset.begin(), vset.end()); - } + 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) { + APT::VersionSet::Version const &fallback, CacheSetHelper &helper, + bool const &onlyFromName) { std::string ver; bool verIsRel = false; size_t const vertag = pkg.find_last_of("/="); @@ -275,7 +310,13 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, verIsRel = (pkg[vertag] == '/'); pkg.erase(vertag); } - PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), helper); + PackageSet pkgset; + if (onlyFromName == false) + pkgset = PackageSet::FromString(Cache, pkg, helper); + else { + pkgset.insert(PackageSet::FromName(Cache, pkg, helper)); + } + VersionSet verset; for (PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) { @@ -372,8 +413,8 @@ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, if (Cache.IsDepCacheBuilt() == true) Cand = Cache[Pkg].CandidateVerIter(Cache); else { - if (unlikely(Cache.BuildPolicy() == false)) - return pkgCache::VerIterator(*Cache); + if (unlikely(Cache.GetPolicy() == 0)) + return pkgCache::VerIterator(Cache); Cand = Cache.GetPolicy()->GetCandidateVer(Pkg); } if (Cand.end() == true) @@ -389,6 +430,14 @@ pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache, 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) @@ -405,8 +454,6 @@ PackageSet CacheSetHelper::canNotFindRegEx(pkgCacheFile &Cache, std::string patt /*}}}*/ // canNotFindPackage - handle the case no package is found from a string/*{{{*/ PackageSet CacheSetHelper::canNotFindPackage(pkgCacheFile &Cache, std::string const &str) { - if (ShowError == true) - _error->Error(_("Unable to locate package %s"), str.c_str()); return PackageSet(); } /*}}}*/ @@ -431,7 +478,7 @@ 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); + return pkgCache::VerIterator(Cache); } /*}}}*/ // canNotFindCandidateVer /*{{{*/ @@ -439,7 +486,7 @@ 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); + return pkgCache::VerIterator(Cache); } /*}}}*/ // canNotFindInstalledVer /*{{{*/ @@ -447,7 +494,7 @@ 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); + return pkgCache::VerIterator(Cache); } /*}}}*/ } diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index 9c9491020..21c42c511 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -40,6 +40,7 @@ public: /*{{{*/ 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); @@ -146,6 +147,17 @@ public: /*{{{*/ 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 out stream to print various notices to */ + 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. @@ -268,7 +280,8 @@ public: /*{{{*/ } static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg, - APT::VersionSet::Version const &fallback, CacheSetHelper &helper); + 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; -- cgit v1.2.3 From e67c08344dbb9ecd827658d74121fa9b66b28961 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 29 Jun 2010 17:14:45 +0200 Subject: for install, do all installs first and then the removes and vice versa --- cmdline/apt-get.cc | 92 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 38 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index e3477b6db..7ba0e8e5c 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1640,24 +1640,27 @@ bool DoInstall(CommandLine &CmdL) unsigned int AutoMarkChanged = 0; pkgProblemResolver Fix(Cache); - unsigned short fallback = 0; + 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) - fallback = 1; + fallback = MOD_REMOVE; else if (strcasecmp(CmdL.FileList[0], "purge") == 0) { _config->Set("APT::Get::Purge", true); - fallback = 1; + fallback = MOD_REMOVE; } else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0) { _config->Set("APT::Get::AutomaticRemove", "true"); - fallback = 1; + fallback = MOD_REMOVE; } std::list mods; - mods.push_back(APT::VersionSet::Modifier(0, "+", + mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+", APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDINST)); - mods.push_back(APT::VersionSet::Modifier(1, "-", + mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-", APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::INSTCAND)); CacheSetHelperAPTGet helper(c0out); std::map verset = APT::VersionSet::GroupedFromCommandLine(Cache, @@ -1666,41 +1669,54 @@ bool DoInstall(CommandLine &CmdL) if (_error->PendingError() == true) return false; + 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; + } + // new scope for the ActionGroup { pkgDepCache::ActionGroup group(Cache); - for (APT::VersionSet::const_iterator Ver = verset[0].begin(); - Ver != verset[0].end(); ++Ver) - { - pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - Cache->SetCandidateVersion(Ver); - - if (TryToInstall(Pkg, Cache, Fix, false, BrokenFix) == 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 (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++; - } - } - - for (APT::VersionSet::const_iterator Ver = verset[1].begin(); - Ver != verset[1].end(); ++Ver) + for (unsigned short i = 0; order[i] != 0; ++i) { - pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + if (order[i] == MOD_INSTALL) + for (APT::VersionSet::const_iterator Ver = verset[MOD_INSTALL].begin(); + Ver != verset[MOD_INSTALL].end(); ++Ver) + { + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + Cache->SetCandidateVersion(Ver); + + if (TryToInstall(Pkg, Cache, Fix, false, BrokenFix) == 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 (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) + for (APT::VersionSet::const_iterator Ver = verset[MOD_REMOVE].begin(); + Ver != verset[MOD_REMOVE].end(); ++Ver) + { + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix) == false) - return false; + if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix) == false) + return false; + } } if (_error->PendingError() == true) @@ -1752,7 +1768,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() != verset[0].size()) + if (Cache->InstCount() != verset[MOD_INSTALL].size()) { string List; string VersionsList; @@ -1879,7 +1895,7 @@ bool DoInstall(CommandLine &CmdL) // See if we need to prompt // FIXME: check if really the packages in the set are going to be installed - if (Cache->InstCount() == verset[0].size() && Cache->DelCount() == 0) + if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0) return InstallPackages(Cache,false,false); return InstallPackages(Cache,false); -- cgit v1.2.3 From fb83c1d078b9f5e2e28a828c325dc62dcf060f2b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 29 Jun 2010 19:10:47 +0200 Subject: rename AddSelectedVersion() to a better public FromPackage() --- cmdline/cacheset.cc | 11 ++++++----- cmdline/cacheset.h | 14 +++++++++----- 2 files changed, 15 insertions(+), 10 deletions(-) (limited to 'cmdline') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 42bc79693..35ef74f9a 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -321,7 +321,7 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, for (PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) { if (vertag == string::npos) { - AddSelectedVersion(Cache, verset, P, fallback, helper); + verset.insert(VersionSet::FromPackage(Cache, P, fallback, helper)); continue; } pkgCache::VerIterator V; @@ -351,10 +351,10 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, return verset; } /*}}}*/ -// AddSelectedVersion - add version from package based on fallback /*{{{*/ -void VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, - pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, - CacheSetHelper &helper) { +// 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) { @@ -404,6 +404,7 @@ void VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, verset.insert(helper.canNotFindNewestVer(Cache, P)); break; } + return verset; } /*}}}*/ // getCandidateVer - Returns the candidate version of the given package /*{{{*/ diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index 21c42c511..bf863fb39 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -291,6 +291,15 @@ public: /*{{{*/ 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 VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, + VersionSet::Version const &fallback, CacheSetHelper &helper); + struct Modifier { enum Position { NONE, PREFIX, POSTFIX }; unsigned short ID; @@ -330,11 +339,6 @@ protected: /*{{{*/ \param Pkg we want the installed version from this package */ static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper); - - static void AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset, - pkgCache::PkgIterator const &P, VersionSet::Version const &fallback, - CacheSetHelper &helper); - /*}}}*/ }; /*}}}*/ } -- cgit v1.2.3 From cf28bcadb301d00f6534fea97ccf1fde63041e7b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 29 Jun 2010 19:21:35 +0200 Subject: if the package has no installed & candidate but is virtual see if only one package provides it - if it is only one use this package instead --- cmdline/apt-get.cc | 86 ++++++++++++++++++++++++++++++----------------------- cmdline/cacheset.cc | 8 +++++ cmdline/cacheset.h | 2 ++ 3 files changed, 59 insertions(+), 37 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 7ba0e8e5c..d3ddcbfe8 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1081,41 +1081,6 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, pkgProblemResolver &Fix,bool Remove,bool BrokenFix, 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; - } - } // Handle the no-upgrade case if (_config->FindB("APT::Get::upgrade",true) == false && @@ -1601,13 +1566,13 @@ public: 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"), + 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"), + ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"), Pkg.FullName(true).c_str(), pattern.c_str()); explicitlyNamed = false; } @@ -1618,6 +1583,53 @@ public: Ver.VerStr(), Ver.RelStr().c_str(), Pkg.FullName(true).c_str()); } + virtual APT::VersionSet canNotFindCandInstVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { + return tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDINST); + } + + virtual APT::VersionSet canNotFindInstCandVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { + return tryVirtualPackage(Cache, Pkg, APT::VersionSet::INSTCAND); + } + + 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) { + if (select == APT::VersionSet::CANDINST) + return APT::CacheSetHelper::canNotFindCandInstVer(Cache, Pkg); + return APT::CacheSetHelper::canNotFindInstCandVer(Cache, Pkg); + } + + 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); + } + if (select == APT::VersionSet::CANDINST) + return APT::CacheSetHelper::canNotFindCandInstVer(Cache, Pkg); + return APT::CacheSetHelper::canNotFindInstCandVer(Cache, Pkg); + } + inline bool allPkgNamedExplicitly() const { return explicitlyNamed; } }; diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 35ef74f9a..cc2860a22 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -474,6 +474,14 @@ VersionSet CacheSetHelper::canNotFindInstCandVer(pkgCacheFile &Cache, 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) { diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index bf863fb39..2ca794f28 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -47,6 +47,8 @@ public: /*{{{*/ 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, -- cgit v1.2.3 From c8db3fff877f102dc6fb62c4e4c7f700160b68f5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 2 Jul 2010 07:06:53 +0200 Subject: add a ConstructedBy member to the PackageSet which can be used by the e.g. FromString to tell the caller if the string was an exact match or found by regex or task. The two later ones can match packages for which we want to ignore failures in the VersionSet --- cmdline/cacheset.cc | 26 ++++++++++++++++---------- cmdline/cacheset.h | 42 +++++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 17 deletions(-) (limited to 'cmdline') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index cc2860a22..4d6d6a87c 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -33,13 +33,13 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS } if (pattern[pattern.length() -1] != '^') - return APT::PackageSet(); + return APT::PackageSet(TASK); pattern.erase(pattern.length()-1); if (unlikely(Cache.GetPkgCache() == 0 || Cache.GetDepCache() == 0)) - return APT::PackageSet(); + return APT::PackageSet(TASK); - PackageSet pkgset; + PackageSet pkgset(TASK); // get the records pkgRecords Recs(Cache); @@ -85,7 +85,7 @@ PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheS 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(); + return PackageSet(REGEX); size_t archfound = pattern.find_last_of(':'); std::string arch = "native"; @@ -103,13 +103,13 @@ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, Cache char Error[300]; regerror(Res, &Pattern, Error, sizeof(Error)); _error->Error(_("Regex compilation error - %s"), Error); - return PackageSet(); + return PackageSet(REGEX); } if (unlikely(Cache.GetPkgCache() == 0)) - return PackageSet(); + return PackageSet(REGEX); - PackageSet pkgset; + PackageSet pkgset(REGEX); for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) { if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) @@ -318,8 +318,12 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, } 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) { + helper.canNotFindCandidateVer(Cache, P); if (vertag == string::npos) { verset.insert(VersionSet::FromPackage(Cache, P, fallback, helper)); continue; @@ -348,6 +352,8 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, helper.showSelectedVersion(P, V, ver, verIsRel); verset.insert(V); } + if (pkgset.getConstructor() != PackageSet::UNKNOWN) + helper.showErrors(errors); return verset; } /*}}}*/ @@ -487,7 +493,7 @@ 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); + return pkgCache::VerIterator(Cache, 0); } /*}}}*/ // canNotFindCandidateVer /*{{{*/ @@ -495,7 +501,7 @@ 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); + return pkgCache::VerIterator(Cache, 0); } /*}}}*/ // canNotFindInstalledVer /*{{{*/ @@ -503,7 +509,7 @@ 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); + return pkgCache::VerIterator(Cache, 0); } /*}}}*/ } diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index 2ca794f28..c8c3dd096 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -117,7 +117,7 @@ public: /*{{{*/ packages chosen cause of the given task. \param Cache the packages are in \param pattern name of the task - \param out stream to print the notice to */ + \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; @@ -131,7 +131,7 @@ public: /*{{{*/ packages chosen cause of the given package. \param Cache the packages are in \param pattern regular expression for package names - \param out stream to print the notice to */ + \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; @@ -142,7 +142,7 @@ public: /*{{{*/ \param Cache the packages are in \param string String the package name(s) should be extracted from - \param out stream to print various notices to */ + \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; @@ -153,7 +153,7 @@ public: /*{{{*/ \param Cache the package is in \param string String the package name should be extracted from - \param out stream to print various notices to */ + \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; @@ -166,7 +166,7 @@ public: /*{{{*/ 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 out stream to print various notices to */ + \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; @@ -181,6 +181,17 @@ public: /*{{{*/ 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 GroupedFromCommandLine( pkgCacheFile &Cache, const char **cmdline, std::list const &mods, @@ -193,6 +204,15 @@ public: /*{{{*/ 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 { /*{{{*/ @@ -269,7 +289,7 @@ public: /*{{{*/ 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 out stream to print various notices to */ + \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, @@ -299,8 +319,16 @@ public: /*{{{*/ \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 VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, + 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 }; -- cgit v1.2.3 From b8ad551295c70a882b629ee94668e8ea527d1a7d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 3 Jul 2010 20:09:17 +0200 Subject: Refactor TryToInstall to look a bit saner by splitting the Remove and the Virtual packages part out of the loop. The function still exists unchanged as TryToInstallBuildDep through for the BuildDep installation method --- cmdline/apt-get.cc | 229 ++++++++++++++++++++++++++++++++++++++++------------ cmdline/cacheset.cc | 1 - 2 files changed, 177 insertions(+), 53 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index d3ddcbfe8..d17300943 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1073,11 +1073,11 @@ 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,pkgDepCache &Cache, pkgProblemResolver &Fix,bool Remove,bool BrokenFix, bool AllowFail = true) { @@ -1552,6 +1552,93 @@ bool DoUpgrade(CommandLine &CmdL) return InstallPackages(Cache,true); } /*}}}*/ +// TryToInstall - Mark a package for installation /*{{{*/ +struct TryToInstall { + pkgCacheFile* Cache; + pkgProblemResolver* Fix; + bool FixBroken; + unsigned long AutoMarkChanged; + + 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 ((State.InstBroken() == true || State.InstPolicyBroken() == true) && FixBroken == false) + Cache->GetDepCache()->MarkInstall(Pkg,true); + } + + // 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++; + } + } +}; + /*}}}*/ +// 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)); + } +}; + /*}}}*/ // CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/ class CacheSetHelperAPTGet : public APT::CacheSetHelper { /** \brief stream message should be printed to */ @@ -1559,6 +1646,8 @@ class CacheSetHelperAPTGet : public APT::CacheSetHelper { /** \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; @@ -1583,23 +1672,85 @@ public: Ver.VerStr(), Ver.RelStr().c_str(), Pkg.FullName(true).c_str()); } - virtual APT::VersionSet canNotFindCandInstVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { - return tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDINST); + void showVirtualPackageErrors(pkgCacheFile &Cache) { + 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 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; + } } - virtual APT::VersionSet canNotFindInstCandVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) { - return tryVirtualPackage(Cache, Pkg, APT::VersionSet::INSTCAND); + 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) { - if (select == APT::VersionSet::CANDINST) - return APT::CacheSetHelper::canNotFindCandInstVer(Cache, Pkg); - return APT::CacheSetHelper::canNotFindInstCandVer(Cache, Pkg); - } + if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0) + return APT::VersionSet(); pkgCache::PkgIterator Prov; bool found_one = false; @@ -1625,9 +1776,7 @@ public: Prov.FullName(true).c_str(), Pkg.FullName(true).c_str()); return APT::VersionSet::FromPackage(Cache, Prov, select, *this); } - if (select == APT::VersionSet::CANDINST) - return APT::CacheSetHelper::canNotFindCandInstVer(Cache, Pkg); - return APT::CacheSetHelper::canNotFindInstCandVer(Cache, Pkg); + return APT::VersionSet(); } inline bool allPkgNamedExplicitly() const { return explicitlyNamed; } @@ -1649,7 +1798,6 @@ bool DoInstall(CommandLine &CmdL) if (Cache->BrokenCount() != 0) BrokenFix = true; - unsigned int AutoMarkChanged = 0; pkgProblemResolver Fix(Cache); static const unsigned short MOD_REMOVE = 1; @@ -1671,15 +1819,18 @@ bool DoInstall(CommandLine &CmdL) std::list mods; mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+", - APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDINST)); + APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE)); mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-", - APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::INSTCAND)); + APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST)); CacheSetHelperAPTGet helper(c0out); std::map verset = APT::VersionSet::GroupedFromCommandLine(Cache, CmdL.FileList + 1, mods, fallback, helper); if (_error->PendingError() == true) + { + helper.showVirtualPackageErrors(Cache); return false; + } unsigned short order[] = { 0, 0, 0 }; if (fallback == MOD_INSTALL) { @@ -1690,45 +1841,19 @@ bool DoInstall(CommandLine &CmdL) order[1] = MOD_INSTALL; } + TryToInstall InstallAction(Cache, Fix, BrokenFix); + TryToRemove RemoveAction(Cache, Fix); + // new scope for the ActionGroup { pkgDepCache::ActionGroup group(Cache); + for (unsigned short i = 0; order[i] != 0; ++i) { if (order[i] == MOD_INSTALL) - for (APT::VersionSet::const_iterator Ver = verset[MOD_INSTALL].begin(); - Ver != verset[MOD_INSTALL].end(); ++Ver) - { - pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - Cache->SetCandidateVersion(Ver); - - if (TryToInstall(Pkg, Cache, Fix, false, BrokenFix) == 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 (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++; - } - } + InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction); else if (order[i] == MOD_REMOVE) - for (APT::VersionSet::const_iterator Ver = verset[MOD_REMOVE].begin(); - Ver != verset[MOD_REMOVE].end(); ++Ver) - { - pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - - if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix) == false) - return false; - } + RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction); } if (_error->PendingError() == true) @@ -1899,7 +2024,7 @@ 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) @@ -2521,7 +2646,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); + TryToInstallBuildDep(Pkg,Cache,Fix,true,false); } else // BuildDep || BuildDepIndep { @@ -2637,7 +2762,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) == true) + if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true) { // We successfully installed something; skip remaining alternatives skipAlternatives = hasAlternatives; diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index 4d6d6a87c..b96b60450 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -323,7 +323,6 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, errors = helper.showErrors(false); for (PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P) { - helper.canNotFindCandidateVer(Cache, P); if (vertag == string::npos) { verset.insert(VersionSet::FromPackage(Cache, P, fallback, helper)); continue; -- cgit v1.2.3 From 21d4c9f192b5af9c8edb39356712aac853881348 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 3 Jul 2010 23:55:12 +0200 Subject: reorder classes a bit and make TryToInstallBuildDep use them --- cmdline/apt-get.cc | 610 ++++++++++++++++++++++------------------------------- 1 file changed, 250 insertions(+), 360 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index d17300943..38b93e7e5 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -609,6 +609,240 @@ 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 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; + + 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 ((State.InstBroken() == true || State.InstPolicyBroken() == true) && FixBroken == false) + Cache->GetDepCache()->MarkInstall(Pkg,true); + } + + // 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++; + } + } +}; + /*}}}*/ +// 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 /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -1077,143 +1311,30 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, // --------------------------------------------------------------------- /* This used to be inlined in DoInstall, but with the advent of regex package name matching it was split out.. */ -bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, +bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, pkgProblemResolver &Fix,bool Remove,bool BrokenFix, bool AllowFail = true) { - - // 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 (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0) { - 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 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; + 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; } - 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()); - } - } - - // 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); + TryToRemove RemoveAction(Cache, Fix); + RemoveAction(Pkg.VersionList()); + } else if (Cache[Pkg].CandidateVer != 0) { + TryToInstall InstallAction(Cache, Fix, BrokenFix); + InstallAction(Cache[Pkg].CandidateVerIter(Cache)); + } else + return AllowFail; return true; } @@ -1552,237 +1673,6 @@ bool DoUpgrade(CommandLine &CmdL) return InstallPackages(Cache,true); } /*}}}*/ -// TryToInstall - Mark a package for installation /*{{{*/ -struct TryToInstall { - pkgCacheFile* Cache; - pkgProblemResolver* Fix; - bool FixBroken; - unsigned long AutoMarkChanged; - - 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 ((State.InstBroken() == true || State.InstPolicyBroken() == true) && FixBroken == false) - Cache->GetDepCache()->MarkInstall(Pkg,true); - } - - // 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++; - } - } -}; - /*}}}*/ -// 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)); - } -}; - /*}}}*/ -// 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()); - } - - void showVirtualPackageErrors(pkgCacheFile &Cache) { - 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 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; - } - } - - 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; } - -}; - /*}}}*/ // DoInstall - Install packages from the command line /*{{{*/ // --------------------------------------------------------------------- /* Install named packages */ -- cgit v1.2.3 From 2fbfb111312257fa5fc29b0c2ed386fb712f960e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 4 Jul 2010 00:32:52 +0200 Subject: prefer the Policy if it is built instead of the DepCache and if DepCache is not available as fallback built the Policy --- cmdline/apt-get.cc | 3 +++ cmdline/cacheset.cc | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 38b93e7e5..9a6c12ee0 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -768,6 +768,9 @@ struct TryToInstall { void operator() (pkgCache::VerIterator const &Ver) { pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + +std::clog << "INSTALL " << Pkg << " VER " << Ver.VerStr() << std::endl; + Cache->GetDepCache()->SetCandidateVersion(Ver); pkgDepCache::StateCache &State = (*Cache)[Pkg]; diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index b96b60450..78c9d3f6c 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -416,12 +416,13 @@ VersionSet VersionSet::FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator co pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) { pkgCache::VerIterator Cand; - if (Cache.IsDepCacheBuilt() == true) - Cand = Cache[Pkg].CandidateVerIter(Cache); - else { + 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); -- cgit v1.2.3 From 6806db8ac030ab7401b7b8b8324c62bb7b4a0275 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 5 Jul 2010 11:34:35 +0200 Subject: make the specify order of packages irrelevant (half-close #196021) --- cmdline/apt-get.cc | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 9a6c12ee0..7cf760c27 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -762,6 +762,7 @@ struct TryToInstall { 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) {}; @@ -769,8 +770,6 @@ struct TryToInstall { void operator() (pkgCache::VerIterator const &Ver) { pkgCache::PkgIterator Pkg = Ver.ParentPkg(); -std::clog << "INSTALL " << Pkg << " VER " << Ver.VerStr() << std::endl; - Cache->GetDepCache()->SetCandidateVersion(Ver); pkgDepCache::StateCache &State = (*Cache)[Pkg]; @@ -801,8 +800,8 @@ std::clog << "INSTALL " << Pkg << " VER " << Ver.VerStr() << std::endl; // Install it with autoinstalling enabled (if we not respect the minial // required deps or the policy) - if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && FixBroken == false) - Cache->GetDepCache()->MarkInstall(Pkg,true); + if (FixBroken == false) + doAutoInstallLater.insert(Pkg); } // see if we need to fix the auto-mark flag @@ -820,6 +819,17 @@ std::clog << "INSTALL " << Pkg << " VER " << Ver.VerStr() << std::endl; 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 /*{{{*/ @@ -1336,6 +1346,7 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, } else if (Cache[Pkg].CandidateVer != 0) { TryToInstall InstallAction(Cache, Fix, BrokenFix); InstallAction(Cache[Pkg].CandidateVerIter(Cache)); + InstallAction.doAutoInstall(); } else return AllowFail; @@ -1743,8 +1754,10 @@ bool DoInstall(CommandLine &CmdL) for (unsigned short i = 0; order[i] != 0; ++i) { - if (order[i] == MOD_INSTALL) + if (order[i] == MOD_INSTALL) { InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction); + InstallAction.doAutoInstall(); + } else if (order[i] == MOD_REMOVE) RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction); } -- cgit v1.2.3