diff options
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/algorithms.cc | 64 | ||||
-rw-r--r-- | apt-pkg/aptconfiguration.cc | 87 | ||||
-rw-r--r-- | apt-pkg/aptconfiguration.h | 29 | ||||
-rw-r--r-- | apt-pkg/cacheiterators.h | 8 | ||||
-rw-r--r-- | apt-pkg/cacheset.h | 4 | ||||
-rw-r--r-- | apt-pkg/contrib/configuration.h | 2 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 84 | ||||
-rw-r--r-- | apt-pkg/deb/debsrcrecords.cc | 8 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 19 | ||||
-rw-r--r-- | apt-pkg/depcache.cc | 304 | ||||
-rw-r--r-- | apt-pkg/depcache.h | 8 | ||||
-rw-r--r-- | apt-pkg/orderlist.cc | 4 | ||||
-rw-r--r-- | apt-pkg/packagemanager.cc | 35 | ||||
-rw-r--r-- | apt-pkg/pkgcache.cc | 18 | ||||
-rw-r--r-- | apt-pkg/pkgcache.h | 4 | ||||
-rw-r--r-- | apt-pkg/pkgcachegen.cc | 49 | ||||
-rw-r--r-- | apt-pkg/policy.cc | 7 |
17 files changed, 199 insertions, 535 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 66c182b23..0b4366e5e 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -90,21 +90,6 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/) Describe(Pkg,cout,true,true); Sim.MarkInstall(Pkg,false); - if (strcmp(Pkg.Arch(),"all") == 0) - { - pkgCache::GrpIterator G = Pkg.Group(); - pkgCache::GrpIterator iG = iPkg.Group(); - for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P)) - { - if (strcmp(P.Arch(), "all") == 0) - continue; - if (iG.FindPkg(P.Arch())->CurrentVer == 0) - continue; - Flags[P->ID] = 1; - Sim.MarkInstall(P, false); - } - } - // Look for broken conflicts+predepends. for (PkgIterator I = Sim.PkgBegin(); I.end() == false; I++) { @@ -150,40 +135,6 @@ bool pkgSimulate::Configure(PkgIterator iPkg) Flags[Pkg->ID] = 2; - if (strcmp(Pkg.Arch(),"all") == 0) - { - pkgCache::GrpIterator G = Pkg.Group(); - for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P)) - { - if (strcmp(P.Arch(), "all") == 0) - continue; - if (Flags[P->ID] == 1) - Flags[P->ID] = 2; - } - } - - if (Sim[Pkg].InstBroken() == true) - { - /* We don't call Configure for Pseudo packages and if the 'all' is already installed - the simulation will think the pseudo package is not installed, so if something is - broken we walk over the dependencies and search for not installed pseudo packages */ - for (pkgCache::DepIterator D = Sim[Pkg].InstVerIter(Sim).DependsList(); D.end() == false; D++) - { - if (Sim.IsImportantDep(D) == false || - (Sim[D] & pkgDepCache::DepInstall) != 0) - continue; - pkgCache::PkgIterator T = D.TargetPkg(); - if (T.end() == true || T->CurrentVer != 0 || Flags[T->ID] != 0) - continue; - pkgCache::PkgIterator A = T.Group().FindPkg("all"); - if (A.end() == true || A->VersionList == 0 || A->CurrentVer == 0 || - Cache.VS().CheckDep(A.CurVersion(), pkgCache::Dep::Equals, T.CandVersion()) == false) - continue; - Sim.MarkInstall(T, false); - Flags[T->ID] = 2; - } - } - if (Sim[Pkg].InstBroken() == true) { cout << "Conf " << Pkg.FullName(false) << " broken" << endl; @@ -235,21 +186,6 @@ bool pkgSimulate::Remove(PkgIterator iPkg,bool Purge) Flags[Pkg->ID] = 3; Sim.MarkDelete(Pkg); - if (strcmp(Pkg.Arch(),"all") == 0) - { - pkgCache::GrpIterator G = Pkg.Group(); - pkgCache::GrpIterator iG = iPkg.Group(); - for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P)) - { - if (strcmp(P.Arch(), "all") == 0) - continue; - if (iG.FindPkg(P.Arch())->CurrentVer == 0) - continue; - Flags[P->ID] = 3; - Sim.MarkDelete(P); - } - } - if (Purge == true) cout << "Purg "; else diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 3cf4d2429..b23e12acb 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -38,12 +38,11 @@ const Configuration::getCompressionTypes(bool const &Cached) { // setup the defaults for the compressiontypes => method mapping _config->CndSet("Acquire::CompressionTypes::bz2","bzip2"); + _config->CndSet("Acquire::CompressionTypes::xz","xz"); _config->CndSet("Acquire::CompressionTypes::lzma","lzma"); _config->CndSet("Acquire::CompressionTypes::gz","gzip"); - // Set default application paths to check for optional compression types - _config->CndSet("Dir::Bin::lzma", "/usr/bin/lzma"); - _config->CndSet("Dir::Bin::bzip2", "/bin/bzip2"); + setDefaultConfigurationForCompressors(); // accept non-list order as override setting for config settings on commandline std::string const overrideOrder = _config->Find("Acquire::CompressionTypes::Order",""); @@ -344,4 +343,86 @@ bool const Configuration::checkArchitecture(std::string const &Arch) { return (std::find(archs.begin(), archs.end(), Arch) != archs.end()); } /*}}}*/ +// setDefaultConfigurationForCompressors /*{{{*/ +void Configuration::setDefaultConfigurationForCompressors() { + // Set default application paths to check for optional compression types + _config->CndSet("Dir::Bin::lzma", "/usr/bin/lzma"); + _config->CndSet("Dir::Bin::xz", "/usr/bin/xz"); + _config->CndSet("Dir::Bin::bzip2", "/bin/bzip2"); +} + /*}}}*/ +// getCompressors - Return Vector of usbale compressors /*{{{*/ +// --------------------------------------------------------------------- +/* return a vector of compressors used by apt-ftparchive in the + multicompress functionality or to detect data.tar files */ +std::vector<APT::Configuration::Compressor> +const Configuration::getCompressors(bool const Cached) { + static std::vector<APT::Configuration::Compressor> compressors; + if (compressors.empty() == false) { + if (Cached == true) + return compressors; + else + compressors.clear(); + } + + setDefaultConfigurationForCompressors(); + + compressors.push_back(Compressor(".", "", "", "", "", 1)); + if (_config->Exists("Dir::Bin::gzip") == false || FileExists(_config->FindFile("Dir::Bin::gzip")) == true) + compressors.push_back(Compressor("gzip",".gz","gzip","-9n","-d",2)); + if (_config->Exists("Dir::Bin::bzip2") == false || FileExists(_config->FindFile("Dir::Bin::bzip2")) == true) + compressors.push_back(Compressor("bzip2",".bz2","bzip2","-9","-d",3)); + if (_config->Exists("Dir::Bin::lzma") == false || FileExists(_config->FindFile("Dir::Bin::lzma")) == true) + compressors.push_back(Compressor("lzma",".lzma","lzma","-9","-d",4)); + if (_config->Exists("Dir::Bin::xz") == false || FileExists(_config->FindFile("Dir::Bin::xz")) == true) + compressors.push_back(Compressor("xz",".xz","xz","-6","-d",5)); + + std::vector<std::string> const comp = _config->FindVector("APT::Compressor"); + for (std::vector<std::string>::const_iterator c = comp.begin(); + c != comp.end(); ++c) { + if (*c == "." || *c == "gzip" || *c == "bzip2" || *c == "lzma" || *c == "xz") + continue; + compressors.push_back(Compressor(c->c_str(), std::string(".").append(*c).c_str(), c->c_str(), "-9", "-d", 100)); + } + + return compressors; +} + /*}}}*/ +// getCompressorExtensions - supported data.tar extensions /*{{{*/ +// --------------------------------------------------------------------- +/* */ +std::vector<std::string> const Configuration::getCompressorExtensions() { + std::vector<APT::Configuration::Compressor> const compressors = getCompressors(); + std::vector<std::string> ext; + for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressors.begin(); + c != compressors.end(); ++c) + if (c->Extension.empty() == false && c->Extension != ".") + ext.push_back(c->Extension); + return ext; +} + /*}}}*/ +// Compressor constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +Configuration::Compressor::Compressor(char const *name, char const *extension, + char const *binary, + char const *compressArg, char const *uncompressArg, + unsigned short const cost) { + std::string const config = string("APT:Compressor::").append(name).append("::"); + Name = _config->Find(std::string(config).append("Name"), name); + Extension = _config->Find(std::string(config).append("Extension"), extension); + Binary = _config->Find(std::string(config).append("Binary"), binary); + Cost = _config->FindI(std::string(config).append("Cost"), cost); + std::string const compConf = std::string(config).append("CompressArg"); + if (_config->Exists(compConf) == true) + CompressArgs = _config->FindVector(compConf); + else if (compressArg != NULL) + CompressArgs.push_back(compressArg); + std::string const uncompConf = std::string(config).append("UncompressArg"); + if (_config->Exists(uncompConf) == true) + UncompressArgs = _config->FindVector(uncompConf); + else if (uncompressArg != NULL) + UncompressArgs.push_back(uncompressArg); +} + /*}}}*/ } diff --git a/apt-pkg/aptconfiguration.h b/apt-pkg/aptconfiguration.h index dd339d841..815db6cae 100644 --- a/apt-pkg/aptconfiguration.h +++ b/apt-pkg/aptconfiguration.h @@ -82,6 +82,35 @@ public: /*{{{*/ */ bool static const checkArchitecture(std::string const &Arch); + /** \brief Representation of supported compressors */ + struct Compressor { + std::string Name; + std::string Extension; + std::string Binary; + std::vector<std::string> CompressArgs; + std::vector<std::string> UncompressArgs; + unsigned short Cost; + + Compressor(char const *name, char const *extension, char const *binary, + char const *compressArg, char const *uncompressArg, + unsigned short const cost); + Compressor() {}; + }; + + /** \brief Return a vector of Compressors supported for data.tar's + * + * \param Cached saves the result so we need to calculated it only once + * this parameter should ony be used for testing purposes. + * + * \return a vector of Compressors + */ + std::vector<Compressor> static const getCompressors(bool const Cached = true); + + /** \brief Return a vector of extensions supported for data.tar's */ + std::vector<std::string> static const getCompressorExtensions(); + /*}}}*/ + private: /*{{{*/ + void static setDefaultConfigurationForCompressors(); /*}}}*/ }; /*}}}*/ diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 449d4b441..31b3aced3 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -206,13 +206,9 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> { inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;}; inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;}; inline const char *Arch() const { - if(S->MultiArch == pkgCache::Version::All) - return "all"; return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch; }; - inline const char *Arch(bool const pseudo) const { - if(pseudo == false) - return Arch(); + __deprecated inline const char *Arch(bool const pseudo) const { return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch; }; inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);}; @@ -227,7 +223,7 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> { string RelStr() const; bool Automatic() const; - bool Pseudo() const; + __deprecated bool Pseudo() const; VerFileIterator NewestFile() const; inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) { diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index 3f4f0066b..e690d660c 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -257,7 +257,7 @@ public: /*{{{*/ 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); }; + __deprecated inline const char *Arch(bool const pseudo) const { return (**this).Arch(); }; inline pkgCache::PkgIterator ParentPkg() const { return (**this).ParentPkg(); }; inline pkgCache::DescIterator DescriptionList() const { return (**this).DescriptionList(); }; inline pkgCache::DescIterator TranslatedDescription() const { return (**this).TranslatedDescription(); }; @@ -268,7 +268,7 @@ public: /*{{{*/ 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(); }; + __deprecated inline bool Pseudo() const { return false; }; inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); }; }; /*}}}*/ diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h index 175c1bef3..71e5a0e47 100644 --- a/apt-pkg/contrib/configuration.h +++ b/apt-pkg/contrib/configuration.h @@ -72,8 +72,8 @@ class Configuration string Find(string const &Name, string const &Default) const {return Find(Name.c_str(),Default.c_str());}; string FindFile(const char *Name,const char *Default = 0) const; string FindDir(const char *Name,const char *Default = 0) const; - std::vector<string> FindVector(string const &Name) const; std::vector<string> FindVector(const char *Name) const; + std::vector<string> FindVector(string const &Name) const { return FindVector(Name.c_str()); }; int FindI(const char *Name,int const &Default = 0) const; int FindI(string const &Name,int const &Default = 0) const {return FindI(Name.c_str(),Default);}; bool FindB(const char *Name,bool const &Default = false) const; diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 9201e6a54..edc001abb 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -67,23 +67,12 @@ string debListParser::Package() { /*}}}*/ // ListParser::Architecture - Return the package arch /*{{{*/ // --------------------------------------------------------------------- -/* This will return the Architecture of the package this section describes - Note that architecture "all" packages will get the architecture of the - Packages file parsed here. */ +/* This will return the Architecture of the package this section describes */ string debListParser::Architecture() { - string const Result = Section.FindS("Architecture"); - if (Result.empty() == true || Result == "all") - { - if (Arch.empty() == true) - /* FIXME: this is a problem for installed arch all - packages as we don't know from which arch this - package was installed - and therefore which - dependency this package resolves. */ - return _config->Find("APT::Architecture"); - else - return Arch; - } - return Result; + std::string const Arch = Section.FindS("Architecture"); + if (Arch.empty() == true) + return _config->Find("APT::Architecture"); + return Arch; } /*}}}*/ // ListParser::ArchitectureAll /*{{{*/ @@ -112,27 +101,30 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) Ver->Section = UniqFindTagWrite("Section"); // Parse multi-arch - if (Section.FindS("Architecture") == "all") - /* Arch all packages can't have a Multi-Arch field, - but we need a special treatment for them nonetheless */ - Ver->MultiArch = pkgCache::Version::All; - else - { - string const MultiArch = Section.FindS("Multi-Arch"); - if (MultiArch.empty() == true) - Ver->MultiArch = pkgCache::Version::None; - else if (MultiArch == "same") - Ver->MultiArch = pkgCache::Version::Same; - else if (MultiArch == "foreign") - Ver->MultiArch = pkgCache::Version::Foreign; - else if (MultiArch == "allowed") - Ver->MultiArch = pkgCache::Version::Allowed; - else + string const MultiArch = Section.FindS("Multi-Arch"); + if (MultiArch.empty() == true) + Ver->MultiArch = pkgCache::Version::None; + else if (MultiArch == "same") { + // Parse multi-arch + if (Section.FindS("Architecture") == "all") { - _error->Warning("Unknown Multi-Arch type »%s« for package »%s«", - MultiArch.c_str(), Section.FindS("Package").c_str()); + /* Arch all packages can't be Multi-Arch: same */ + _error->Warning("Architecture: all package '%s' can't be Multi-Arch: same", + Section.FindS("Package").c_str()); Ver->MultiArch = pkgCache::Version::None; } + else + Ver->MultiArch = pkgCache::Version::Same; + } + else if (MultiArch == "foreign") + Ver->MultiArch = pkgCache::Version::Foreign; + else if (MultiArch == "allowed") + Ver->MultiArch = pkgCache::Version::Allowed; + else + { + _error->Warning("Unknown Multi-Arch type '%s' for package '%s'", + MultiArch.c_str(), Section.FindS("Package").c_str()); + Ver->MultiArch = pkgCache::Version::None; } // Archive Size @@ -150,24 +142,6 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) Ver->Priority = pkgCache::State::Extra; } - if (Ver->MultiArch == pkgCache::Version::All) - { - /* We maintain a "pseudo" arch=all package for architecture all versions - on which these versions can depend on. This pseudo package is many used - for downloading/installing: The other pseudo-packages will degenerate - to a NOP in the download/install step - this package will ensure that - it is downloaded only one time and installed only one time -- even if - the architecture bound versions coming in and out on regular basis. */ - if (strcmp(Ver.Arch(true),"all") == 0) - return true; - else if (MultiArchEnabled == true) - { - // our pseudo packages have no size to not confuse the fetcher - Ver->Size = 0; - Ver->InstalledSize = 0; - } - } - if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false) return false; if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false) @@ -644,7 +618,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver, return true; string Package; - string const pkgArch = Ver.Arch(true); + string const pkgArch = Ver.Arch(); string Version; unsigned int Op; @@ -683,7 +657,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) { string Package; string Version; - string const Arch = Ver.Arch(true); + string const Arch = Ver.Arch(); unsigned int Op; while (1) @@ -768,7 +742,7 @@ bool debListParser::Step() if (Architecture == Arch) return true; - if (Architecture == "all") + if (Architecture == "all" && Arch == _config->Find("APT::Architecture")) return true; } diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc index 21336e1af..749305005 100644 --- a/apt-pkg/deb/debsrcrecords.cc +++ b/apt-pkg/deb/debsrcrecords.cc @@ -14,6 +14,7 @@ #include <apt-pkg/error.h> #include <apt-pkg/strutl.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/aptconfiguration.h> using std::max; /*}}}*/ @@ -111,7 +112,9 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List) string Base = Sect.FindS("Directory"); if (Base.empty() == false && Base[Base.length()-1] != '/') Base += '/'; - + + std::vector<std::string> const compExts = APT::Configuration::getCompressorExtensions(); + // Iterate over the entire list grabbing each triplet const char *C = Files.c_str(); while (*C != 0) @@ -144,7 +147,8 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List) } F.Type = string(F.Path,Tmp+1,Pos-Tmp); - if (F.Type == "gz" || F.Type == "bz2" || F.Type == "lzma" || F.Type == "tar") + if (std::find(compExts.begin(), compExts.end(), std::string(".").append(F.Type)) != compExts.end() || + F.Type == "tar") { Pos = Tmp-1; continue; diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 7d0d34a46..7b0955b96 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -881,7 +881,10 @@ bool pkgDPkgPM::Go(int OutStatusFd) // Generate the argument list const char *Args[MaxArgs + 50]; - + // keep track of allocated strings for multiarch package names + char *Packages[MaxArgs + 50]; + unsigned int pkgcount = 0; + // Now check if we are within the MaxArgs limit // // this code below is problematic, because it may happen that @@ -989,13 +992,20 @@ bool pkgDPkgPM::Go(int OutStatusFd) } else { + string const nativeArch = _config->Find("APT::Architecture"); for (;I != J && Size < MaxArgBytes; I++) { if((*I).Pkg.end() == true) continue; if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end()) continue; - Args[n++] = I->Pkg.Name(); + if (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all")) + Args[n++] = I->Pkg.Name(); + else + { + Packages[pkgcount] = strdup(I->Pkg.FullName(false).c_str()); + Args[n++] = Packages[pkgcount++]; + } Size += strlen(Args[n-1]); } } @@ -1145,6 +1155,11 @@ bool pkgDPkgPM::Go(int OutStatusFd) sigemptyset(&sigmask); sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask); + /* clean up the temporary allocation for multiarch package names in + the parent, so we don't leak memory when we return. */ + for (unsigned int i = 0; i < pkgcount; i++) + free(Packages[i]); + // the result of the waitpid call int res; int select_ret; diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index ddbd37699..fba6ad054 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -705,107 +705,6 @@ void pkgDepCache::UpdateVerState(PkgIterator Pkg) } } /*}}}*/ -// DepCache::RemovePseudoInstalledPkg - MultiArch helper for Update() /*{{{*/ -// --------------------------------------------------------------------- -/* We "install" arch all packages for all archs if it is installed. Many - of these will be broken. This method will look at these broken Pkg and - "remove" it. */ -bool pkgDepCache::RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned long> &recheck) { - if (unlikely(Pkg->CurrentVer == 0)) - return false; - - VerIterator V = Pkg.CurrentVer(); - if (V->MultiArch != Version::All) - return false; - - // Never ever kill an "all" package - they have no dependency so they can't be broken - if (strcmp(Pkg.Arch(),"all") == 0) - return false; - - unsigned char const CurDepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); - if ((CurDepState & DepInstMin) == DepInstMin) { - // okay, the package isn't broken, but is the package also required? - // If it has no real dependencies, no installed rdepends and doesn't - // provide something of value, we will kill it as not required. - // These pseudopackages have otherwise interesting effects if they get - // a new dependency in a newer version… - for (pkgCache::DepIterator D = V.DependsList(); - D.end() != true; ++D) - if (D.IsCritical() == true && D.ParentPkg()->Group != Pkg->Group) - return false; - for (DepIterator D = Pkg.RevDependsList(); D.end() != true; ++D) - { - if (D.IsCritical() == false) - continue; - PkgIterator const P = D.ParentPkg(); - if (P->Group == Pkg->Group) - continue; - if (P->CurrentVer != 0) - return false; - } - for (PrvIterator Prv = V.ProvidesList(); Prv.end() != true; Prv++) - for (DepIterator d = Prv.ParentPkg().RevDependsList(); - d.end() != true; ++d) - { - PkgIterator const P = d.ParentPkg(); - if (P->CurrentVer != 0 && - P->Group != Pkg->Group) - return false; - } - } - - // Dependencies for this arch all package are not statisfied - // so we installed it only for our convenience: get right of it now. - RemoveSizes(Pkg); - RemoveStates(Pkg); - - Pkg->CurrentVer = 0; - PkgState[Pkg->ID].InstallVer = 0; - - AddStates(Pkg); - Update(Pkg); - AddSizes(Pkg); - - // After the remove previously satisfied pseudo pkg could be now - // no longer satisfied, so we need to recheck the reverse dependencies - for (DepIterator d = Pkg.RevDependsList(); d.end() != true; ++d) - { - PkgIterator const P = d.ParentPkg(); - if (P->CurrentVer != 0) - recheck.insert(P.Index()); - } - - for (DepIterator d = V.DependsList(); d.end() != true; ++d) - { - PkgIterator const P = d.TargetPkg(); - for (PrvIterator Prv = P.ProvidesList(); Prv.end() != true; ++Prv) - { - PkgIterator const O = Prv.OwnerPkg(); - if (O->CurrentVer != 0) - recheck.insert(O.Index()); - } - - if (P->CurrentVer != 0) - recheck.insert(P.Index()); - } - - for (PrvIterator Prv = V.ProvidesList(); Prv.end() != true; Prv++) - { - for (DepIterator d = Prv.ParentPkg().RevDependsList(); - d.end() != true; ++d) - { - PkgIterator const P = d.ParentPkg(); - if (P->CurrentVer == 0) - continue; - - recheck.insert(P.Index()); - } - } - - - return true; -} - /*}}}*/ // DepCache::Update - Figure out all the state information /*{{{*/ // --------------------------------------------------------------------- /* This will figure out the state of all the packages and all the @@ -820,12 +719,8 @@ void pkgDepCache::Update(OpProgress *Prog) iBrokenCount = 0; iBadCount = 0; - std::set<unsigned long> recheck; - // Perform the depends pass int Done = 0; - bool const checkMultiArch = APT::Configuration::getArchitectures().size() > 1; - unsigned long killed = 0; for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++) { if (Prog != 0 && Done%20 == 0) @@ -858,69 +753,6 @@ void pkgDepCache::Update(OpProgress *Prog) AddSizes(I); UpdateVerState(I); AddStates(I); - - if (checkMultiArch != true || I->CurrentVer == 0) - continue; - - VerIterator const V = I.CurrentVer(); - if (V->MultiArch != Version::All) - continue; - - recheck.insert(I.Index()); - --Done; // no progress if we need to recheck the package - } - - if (checkMultiArch == true) { - /* FIXME: recheck breaks proper progress reporting as we don't know - how many packages we need to recheck. To lower the effect - a bit we increase with a kill, but we should do something more clever… */ - while(recheck.empty() == false) - for (std::set<unsigned long>::const_iterator p = recheck.begin(); - p != recheck.end();) { - if (Prog != 0 && Done%20 == 0) - Prog->Progress(Done); - PkgIterator P = PkgIterator(*Cache, Cache->PkgP + *p); - if (RemovePseudoInstalledPkg(P, recheck) == true) { - ++killed; - ++Done; - } - recheck.erase(p++); - } - - /* Okay, we have killed a great amount of pseudopackages - - we have killed so many that we have now arch "all" packages - without an installed pseudo package, but we NEED an installed - pseudo package, so we will search now for a pseudo package - we can install without breaking everything. */ - for (GrpIterator G = Cache->GrpBegin(); G.end() != true; ++G) - { - PkgIterator P = G.FindPkg("all"); - if (P.end() == true) - continue; - if (P->CurrentVer == 0) - continue; - bool installed = false; - for (P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P)) - { - if (strcmp(P.Arch(), "all") == 0) - continue; - if (P->CurrentVer == 0) - continue; - installed = true; - break; - } - if (installed == false) - recheck.insert(G.Index()); - } - - while (recheck.empty() != true) - { - std::set<unsigned long>::const_iterator g = recheck.begin(); - unsigned long const G = *g; - recheck.erase(g); - if (unlikely(ReInstallPseudoForGroup(G, recheck) == false)) - _error->Warning(_("Internal error, group '%s' has no installable pseudo package"), GrpIterator(*Cache, Cache->GrpP + G).Name()); - } } if (Prog != 0) @@ -929,80 +761,6 @@ void pkgDepCache::Update(OpProgress *Prog) readStateFile(Prog); } /*}}}*/ -// DepCache::ReInstallPseudoForGroup - MultiArch helper for Update() /*{{{*/ -// --------------------------------------------------------------------- -/* RemovePseudoInstalledPkg() is very successful. It even kills packages - to an amount that no pseudo package is left, but we need a pseudo package - for upgrading senarios so we need to reinstall one pseudopackage which - doesn't break everything. Thankfully we can't have architecture depending - negative dependencies so this problem is already eliminated */ -bool pkgDepCache::ReInstallPseudoForGroup(pkgCache::PkgIterator const &P, std::set<unsigned long> &recheck) -{ - if (P->CurrentVer != 0) - return true; - // recursive call for packages which provide this package - for (pkgCache::PrvIterator Prv = P.ProvidesList(); Prv.end() != true; ++Prv) - ReInstallPseudoForGroup(Prv.OwnerPkg(), recheck); - // check if we actually need to look at this group - unsigned long const G = P->Group; - std::set<unsigned long>::const_iterator Pi = recheck.find(G); - if (Pi == recheck.end()) - return true; - recheck.erase(Pi); // remove here, so we can't fall into an endless loop - if (unlikely(ReInstallPseudoForGroup(G, recheck) == false)) - { - recheck.insert(G); - return false; - } - return true; -} -bool pkgDepCache::ReInstallPseudoForGroup(unsigned long const &G, std::set<unsigned long> &recheck) -{ - std::vector<std::string> static const Archs = APT::Configuration::getArchitectures(); - pkgCache::GrpIterator Grp(*Cache, Cache->GrpP + G); - if (unlikely(Grp.end() == true)) - return false; - for (std::vector<std::string>::const_iterator a = Archs.begin(); - a != Archs.end(); ++a) - { - pkgCache::PkgIterator P = Grp.FindPkg(*a); - if (P.end() == true) - continue; - pkgCache::VerIterator allV = Grp.FindPkg("all").CurrentVer(); - for (VerIterator V = P.VersionList(); V.end() != true; ++V) - { - // search for the same version as the all package - if (allV->Hash != V->Hash || strcmp(allV.VerStr(),V.VerStr()) != 0) - continue; - unsigned char const CurDepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); - // If it is broken, try to install dependencies first before retry - if ((CurDepState & DepInstMin) != DepInstMin) - { - for (pkgCache::DepIterator D = V.DependsList(); D.end() != true; ++D) - { - if (D->Type != pkgCache::Dep::PreDepends && D->Type != pkgCache::Dep::Depends) - continue; - ReInstallPseudoForGroup(D.TargetPkg(), recheck); - } - unsigned char const CurDepState = VersionState(V.DependsList(),DepInstall,DepInstMin,DepInstPolicy); - // if package ist still broken… try another arch - if ((CurDepState & DepInstMin) != DepInstMin) - break; - } - // dependencies satisfied: reinstall the package - RemoveSizes(P); - RemoveStates(P); - P->CurrentVer = V.Index(); - PkgState[P->ID].InstallVer = V; - AddStates(P); - Update(P); - AddSizes(P); - return true; - } - } - return false; -} - /*}}}*/ // DepCache::Update - Update the deps list of a package /*{{{*/ // --------------------------------------------------------------------- /* This is a helper for update that only does the dep portion of the scan. @@ -1165,18 +923,6 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge, Update(Pkg); AddSizes(Pkg); - // if we remove the pseudo package, we also need to remove the "real" - if (Pkg->CurrentVer != 0 && Pkg.CurrentVer().Pseudo() == true) - MarkDelete(Pkg.Group().FindPkg("all"), rPurge, Depth+1, FromUser); - else if (rPurge == true && Pkg->CurrentVer == 0 && - Pkg->CurrentState != pkgCache::State::NotInstalled && - strcmp(Pkg.Arch(), "all") != 0) - { - PkgIterator const allPkg = Pkg.Group().FindPkg("all"); - if (allPkg.end() == false && allPkg->CurrentVer == 0 && - allPkg->CurrentState != pkgCache::State::NotInstalled) - MarkDelete(allPkg, rPurge, Depth+1, FromUser); - } } /*}}}*/ // DepCache::IsDeleteOk - check if it is ok to remove this package /*{{{*/ @@ -1276,10 +1022,6 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, Update(Pkg); AddSizes(Pkg); - // always trigger the install of the all package for a pseudo package - if (P.CandidateVerIter(*Cache).Pseudo() == true) - MarkInstall(Pkg.Group().FindPkg("all"), AutoInst, Depth, FromUser, ForceImportantDeps); - if (AutoInst == false) return; @@ -1499,7 +1241,7 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To) AddStates(Pkg); AddSizes(Pkg); - if (unlikely(Pkg.CurrentVer().end() == true) || Pkg.CurrentVer().Pseudo() == false) + if (unlikely(Pkg.CurrentVer().end() == true)) return; SetReInstall(Pkg.Group().FindPkg("all"), To); @@ -1510,7 +1252,6 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To) /* */ void pkgDepCache::SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo) { - pkgCache::PkgIterator Pkg = TargetVer.ParentPkg(); StateCache &P = PkgState[Pkg->ID]; @@ -1531,27 +1272,6 @@ void pkgDepCache::SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo) Update(Pkg); AddSizes(Pkg); - if (TargetVer.Pseudo() == false || Pseudo == false) - return; - - // the version was pseudo: set all other pseudos also - pkgCache::GrpIterator Grp = Pkg.Group(); - for (Pkg = Grp.FindPkg("any"); Pkg.end() == false; ++Pkg) - { - StateCache &P = PkgState[Pkg->ID]; - if (TargetVer.SimilarVer(P.CandidateVerIter(*this)) == true || - (P.CandidateVerIter(*this).Pseudo() == false && - strcmp(Pkg.Arch(), "all") != 0)) - continue; - - for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) - { - if (TargetVer.SimilarVer(Ver) == false) - continue; - SetCandidateVersion(Ver, false); - break; - } - } } /*}}}*/ // DepCache::SetCandidateRelease - Change the candidate version /*{{{*/ @@ -1967,28 +1687,6 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg, if(ver.end() == true) return; - // If the version belongs to a Multi-Arch all package - // we will mark all others in this Group with this version also - if (ver->MultiArch == pkgCache::Version::All && - strcmp(ver.Arch(true), "all") == 0) - { - GrpIterator G = pkg.Group(); - const char* const VerStr = ver.VerStr(); - for (PkgIterator P = G.FindPkg("any"); - P.end() != true; P = G.NextPkg(P)) - { - for (VerIterator V = P.VersionList(); - V.end() != true; ++V) - { - if (ver->Hash != V->Hash || - strcmp(VerStr, V.VerStr()) != 0) - continue; - MarkPackage(P, V, follow_recommends, follow_suggests); - break; - } - } - } - for(DepIterator d = ver.DependsList(); !d.end(); ++d) { if(d->Type == Dep::Depends || diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index dba3e22dc..b95681118 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -395,6 +395,7 @@ class pkgDepCache : protected pkgCache::Namespace bool ForceImportantDeps = false); void SetReInstall(PkgIterator const &Pkg,bool To); + // FIXME: Remove the unused boolean parameter on abi break void SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo = true); bool SetCandidateRelease(pkgCache::VerIterator TargetVer, std::string const &TargetRel); @@ -481,9 +482,10 @@ class pkgDepCache : protected pkgCache::Namespace private: // Helper for Update(OpProgress) to remove pseudoinstalled arch all packages - bool RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned long> &recheck); - bool ReInstallPseudoForGroup(unsigned long const &Grp, std::set<unsigned long> &recheck); - bool ReInstallPseudoForGroup(pkgCache::PkgIterator const &P, std::set<unsigned long> &recheck); + // FIXME: they are private so shouldn't affect abi, but just in case… + __deprecated bool RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned long> &recheck) { return true; }; + __deprecated bool ReInstallPseudoForGroup(unsigned long const &Grp, std::set<unsigned long> &recheck) { return true; }; + __deprecated bool ReInstallPseudoForGroup(pkgCache::PkgIterator const &P, std::set<unsigned long> &recheck) { return true; }; }; #endif diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc index a53854a26..d5bd19581 100644 --- a/apt-pkg/orderlist.cc +++ b/apt-pkg/orderlist.cc @@ -128,10 +128,6 @@ bool pkgOrderList::IsMissing(PkgIterator Pkg) if (FileList[Pkg->ID].empty() == false) return false; - // Missing Pseudo packages are missing if the real package is missing - if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == true) - return IsMissing(Pkg.Group().FindPkg("all")); - return true; } /*}}}*/ diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index cff34058c..4c655cb7b 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -81,9 +81,6 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, if (List->IsNow(Pkg) == false) continue; - if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == true) - continue; - new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache), FileNames[Pkg->ID]); } @@ -281,9 +278,7 @@ bool pkgPackageManager::ConfigureAll() { PkgIterator Pkg(Cache,*I); - if (ConfigurePkgs == true && - pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false && - Configure(Pkg) == false) + if (ConfigurePkgs == true && Configure(Pkg) == false) return false; List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); @@ -318,9 +313,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) { PkgIterator Pkg(Cache,*I); - if (ConfigurePkgs == true && - pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false && - Configure(Pkg) == false) + if (ConfigurePkgs == true && Configure(Pkg) == false) return false; List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); @@ -473,10 +466,7 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg) List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); - if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false) - return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge); - else - return SmartRemove(Pkg.Group().FindPkg("all")); + return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge); return true; } /*}}}*/ @@ -592,22 +582,9 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) P.end() == false; P++) CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); - if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == false) - { - if(Install(Pkg,FileNames[Pkg->ID]) == false) - return false; - } else { - // Pseudo packages will not be unpacked - instead we will do this - // for the "real" package, but only once and if it is already - // configured we don't need to unpack it again… - PkgIterator const P = Pkg.Group().FindPkg("all"); - if (List->IsFlag(P,pkgOrderList::UnPacked) != true && - List->IsFlag(P,pkgOrderList::Configured) != true && - P.State() != pkgCache::PkgIterator::NeedsNothing) { - if (SmartUnPack(P) == false) - return false; - } - } + if(Install(Pkg,FileNames[Pkg->ID]) == false) + return false; + List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); // Perform immedate configuration of the package. diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 616d400a2..7014aee22 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -737,22 +737,8 @@ bool pkgCache::VerIterator::Automatic() const return false; } /*}}}*/ -// VerIterator::Pseudo - Check if this version is a pseudo one /*{{{*/ -// --------------------------------------------------------------------- -/* Sometimes you have the need to express dependencies with versions - which doesn't really exist or exist multiply times for "different" - packages. We need these versions for dependency resolution but they - are a problem everytime we need to download/install something. */ -bool pkgCache::VerIterator::Pseudo() const -{ - if (S->MultiArch == pkgCache::Version::All && - strcmp(Arch(true),"all") != 0) - { - GrpIterator const Grp = ParentPkg().Group(); - return (Grp->LastPackage != Grp->FirstPackage); - } - return false; -} +// VerIterator::Pseudo - deprecated no-op method /*{{{*/ +bool pkgCache::VerIterator::Pseudo() const { return false; } /*}}}*/ // VerIterator::NewestFile - Return the newest file version relation /*{{{*/ // --------------------------------------------------------------------- diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 82a69b2ca..89a296ce9 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -505,8 +505,8 @@ struct pkgCache::Version Foreign means that this version can fulfill dependencies even if it is built for another architecture as the requester. Same indicates that builds for different architectures can - be co-installed on the system and All is the marker for a - version with the Architecture: all. */ + be co-installed on the system */ + // FIXME: remove All on abi break enum {None, All, Foreign, Same, Allowed} MultiArch; /** \brief references all the PackageFile's that this version came from diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 5b943cca1..d44dbf3a9 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -178,23 +178,17 @@ bool pkgCacheGenerator::MergeList(ListParser &List, if (PackageName.empty() == true) return false; - /* As we handle Arch all packages as architecture bounded - we add all information to every (simulated) arch package */ - std::vector<string> genArch; - if (List.ArchitectureAll() == true) { - genArch = APT::Configuration::getArchitectures(); - if (genArch.size() != 1) - genArch.push_back("all"); - } else - genArch.push_back(List.Architecture()); - - for (std::vector<string>::const_iterator arch = genArch.begin(); - arch != genArch.end(); ++arch) - { + /* Treat Arch all packages as the same as the native arch. */ + string Arch; + if (List.ArchitectureAll() == true) + Arch = _config->Find("APT::Architecture"); + else + Arch = List.Architecture(); + // Get a pointer to the package structure pkgCache::PkgIterator Pkg; Dynamic<pkgCache::PkgIterator> DynPkg(Pkg); - if (NewPackage(Pkg, PackageName, *arch) == false) + if (NewPackage(Pkg, PackageName, Arch) == false) return _error->Error(_("Error occurred while processing %s (NewPackage)"),PackageName.c_str()); Counter++; if (Counter % 100 == 0 && Progress != 0) @@ -351,7 +345,6 @@ bool pkgCacheGenerator::MergeList(ListParser &List, if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false) return _error->Error(_("Error occurred while processing %s (NewFileDesc2)"),PackageName.c_str()); - } } FoundFileDeps |= List.HasFileDeps(); @@ -650,10 +643,7 @@ bool pkgCacheGenerator::FinishCache(OpProgress *Progress) - MultiArch: same → Co-Installable if they have the same version - Architecture: all → Need to be Co-Installable for internal reasons - All others conflict with all other group members */ - bool const coInstall = ((V->MultiArch == pkgCache::Version::All && strcmp(Arch, "all") != 0) || - V->MultiArch == pkgCache::Version::Same); - if (V->MultiArch == pkgCache::Version::All && allPkg.end() == true) - allPkg = G.FindPkg("all"); + bool const coInstall = (V->MultiArch == pkgCache::Version::Same); for (vector<string>::const_iterator A = archs.begin(); A != archs.end(); ++A) { if (*A == Arch) @@ -675,24 +665,11 @@ bool pkgCacheGenerator::FinishCache(OpProgress *Progress) NewDepends(D, V, V.VerStr(), pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks, OldDepLast); - if (V->MultiArch == pkgCache::Version::All) - { - // Depend on ${self}:all which does depend on nothing - NewDepends(allPkg, V, V.VerStr(), - pkgCache::Dep::Equals, pkgCache::Dep::Depends, - OldDepLast); - } } else { // Conflicts: ${self}:other - if (strcmp(Arch, "all") == 0) { - NewDepends(D, V, V.VerStr(), - pkgCache::Dep::NotEquals, pkgCache::Dep::Conflicts, - OldDepLast); - } else { - NewDepends(D, V, "", - pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts, - OldDepLast); - } + NewDepends(D, V, "", + pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts, + OldDepLast); } } } @@ -810,7 +787,7 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator &Ver, pkgCache &Cache = Owner->Cache; // We do not add self referencing provides - if (Ver.ParentPkg().Name() == PkgName && PkgArch == Ver.Arch(true)) + if (Ver.ParentPkg().Name() == PkgName && PkgArch == Ver.Arch()) return true; // Get a structure diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 5427271b6..94c7fd4af 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -152,13 +152,6 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk { /* Lets see if this version is the installed version */ bool instVer = (Pkg.CurrentVer() == Ver); - if (Ver.Pseudo() == true && instVer == false) - { - pkgCache::PkgIterator const allPkg = Ver.ParentPkg().Group().FindPkg("all"); - if (allPkg->CurrentVer != 0 && allPkg.CurrentVer()->Hash == Ver->Hash && - strcmp(allPkg.CurVersion(), Ver.VerStr()) == 0) - instVer = true; - } for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; VF++) { |