From 0d29b9d4368284782862c7b507c47002b79ddb27 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 26 Apr 2014 00:00:51 +0200 Subject: WIP local deb install --- apt-pkg/deb/deblistparser.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index a1bcfb710..d5e3ccb65 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -959,3 +959,23 @@ bool debListParser::SameVersion(unsigned short const Hash, /*{{{*/ } /*}}}*/ #endif + + +debDebFileParser::debDebFileParser(FileFd *File, std::string const &DebFile) + : debListParser(File, ""), DebFile(DebFile) +{ +} + +bool debDebFileParser::UsePackage(pkgCache::PkgIterator &Pkg, + pkgCache::VerIterator &Ver) +{ + bool res = debListParser::UsePackage(Pkg, Ver); + // we use the full file path as a provides so that the file is found + // by its name + if(NewProvidesAllArch(Ver, DebFile, Ver.VerStr()) == false) + return false; + return res; +} + + + -- cgit v1.2.3 From ffe3c68e494efc1c2c4d748fa9d69e150867e5c2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 18 Aug 2013 22:20:25 +0200 Subject: parse and retrieve multiple Descriptions in one record It seems unlikely for now that proper archives will carry multiple Description-* stanzas in the Packages (or Translation-*) file, but sometimes apt eats its own output as shown by the usage of the CD team and it would be interesting to let apt output multiple translations e.g. in 'apt-cache show'. --- apt-pkg/deb/deblistparser.cc | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index d5e3ccb65..40d332196 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -194,35 +194,31 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) /* This is to return the string describing the package in debian form. If this returns the blank string then the entry is assumed to only describe package properties */ -string debListParser::Description() +string debListParser::Description(std::string const &lang) { - string const lang = DescriptionLanguage(); if (lang.empty()) return Section.FindS("Description"); else return Section.FindS(string("Description-").append(lang).c_str()); } - /*}}}*/ -// ListParser::DescriptionLanguage - Return the description lang string /*{{{*/ -// --------------------------------------------------------------------- -/* This is to return the string describing the language of - description. If this returns the blank string then the entry is - assumed to describe original description. */ -string debListParser::DescriptionLanguage() + /*}}}*/ +// ListParser::AvailableDescriptionLanguages /*{{{*/ +std::vector debListParser::AvailableDescriptionLanguages() { - if (Section.FindS("Description").empty() == false) - return ""; - - std::vector const lang = APT::Configuration::getLanguages(true); - for (std::vector::const_iterator l = lang.begin(); - l != lang.end(); ++l) - if (Section.FindS(string("Description-").append(*l).c_str()).empty() == false) - return *l; - - return ""; + std::vector const understood = APT::Configuration::getLanguages(); + std::vector avail; + if (Section.Exists("Description") == true) + avail.push_back(""); + for (std::vector::const_iterator lang = understood.begin(); lang != understood.end(); ++lang) + { + std::string const tagname = "Description-" + *lang; + if (Section.Exists(tagname.c_str()) == true) + avail.push_back(*lang); + } + return avail; } - /*}}}*/ -// ListParser::Description - Return the description_md5 MD5SumValue /*{{{*/ + /*}}}*/ +// ListParser::Description_md5 - Return the description_md5 MD5SumValue /*{{{*/ // --------------------------------------------------------------------- /* This is to return the md5 string to allow the check if it is the right description. If no Description-md5 is found in the section it will be @@ -233,7 +229,7 @@ MD5SumValue debListParser::Description_md5() string const value = Section.FindS("Description-md5"); if (value.empty() == true) { - std::string const desc = Description() + "\n"; + std::string const desc = Description("") + "\n"; if (desc == "\n") return MD5SumValue(); -- cgit v1.2.3 From 4ad8619bb1f0bf777d17c568bb7a6cf7f30aac34 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 12 Jun 2014 12:22:45 +0200 Subject: cleanup datatypes mix used in binary cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We had a wild mixture of (unsigned) int, long and long long here without much sense, so this commit adds a few typedefs to get some sense in the typesystem and ensures that a ID isn't sometimes computed as int, stored as long and compared with a long long… as this could potentially bite us later on as the size of the archive only increases over time. --- apt-pkg/deb/deblistparser.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 40d332196..4447b54dd 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -61,7 +61,7 @@ debListParser::debListParser(FileFd *File, string const &Arch) : Tags(File), // ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ // --------------------------------------------------------------------- /* */ -unsigned long debListParser::UniqFindTagWrite(const char *Tag) +map_stringitem_t debListParser::UniqFindTagWrite(const char *Tag) { const char *Start; const char *Stop; @@ -893,7 +893,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, { // apt-secure does no longer download individual (per-section) Release // file. to provide Component pinning we use the section name now - map_ptrloc const storage = WriteUniqString(component); + map_stringitem_t const storage = WriteUniqString(component); FileI->Component = storage; pkgTagFile TagFile(&File, File.Size()); @@ -906,7 +906,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, data = Section.FindS(TAG); \ if (data.empty() == false) \ { \ - map_ptrloc const storage = WriteUniqString(data); \ + map_stringitem_t const storage = WriteUniqString(data); \ STORE = storage; \ } APT_INRELEASE("Suite", FileI->Archive) -- cgit v1.2.3 From 7a66977486804d46d5860f568cbd80f54f0c42d0 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 13 Jun 2014 08:35:32 +0200 Subject: remove the Section member from package struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A version belongs to a section and has hence a section member of its own. A package on the other hand can have multiple versions from different sections. This was "solved" by using the section which was parsed first as order of sources.list defines, but that is obviously a horribly unpredictable thing. We therefore directly remove this struct member to free some space and mark the access method as deprecated, which is told to return the section of the 'newest' known version, which is at least predictable, but possible not what it returned before – but nobody knows. Users are way better of with the Section() as returned by the version they are dealing with. It is likely the same for all versions of a package, but in the few cases it isn't, it is important (like packages moving from main/* to contrib/* or into oldlibs …). --- apt-pkg/deb/deblistparser.cc | 3 --- 1 file changed, 3 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 4447b54dd..192a281db 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -255,9 +255,6 @@ MD5SumValue debListParser::Description_md5() bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver) { - if (Pkg->Section == 0) - Pkg->Section = UniqFindTagWrite("Section"); - string const static myArch = _config->Find("APT::Architecture"); // Possible values are: "all", "native", "installed" and "none" // The "installed" mode is handled by ParseStatus(), See #544481 and friends. -- cgit v1.2.3 From 4ea471ecb013d188d03a5c3efb9b21e58ef56065 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 7 Jul 2014 17:19:29 +0200 Subject: handle moved mmap after UniqFindTagWrite call A call to UniqFindTagWrite can trigger the need for a bigger mmap, which is usually done by moving it, but with this move all pointers into it become invalid (and have to be remapped). The compiler calculates the pointer before the execution of the call though, so it tries to store the returned value at the old location, resulting in a segfault. We solve this by use of a temprorary variable as we did in the other instances of this problem before. Closes: #753941 --- apt-pkg/deb/deblistparser.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index a1bcfb710..02b9cb239 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -145,7 +145,8 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) { // Parse the section - Ver->Section = UniqFindTagWrite("Section"); + unsigned long const idxSection = UniqFindTagWrite("Section"); + Ver->Section = idxSection; Ver->MultiArch = ParseMultiArch(true); // Archive Size Ver->Size = Section.FindULL("Size"); @@ -260,7 +261,10 @@ bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver) { if (Pkg->Section == 0) - Pkg->Section = UniqFindTagWrite("Section"); + { + unsigned long const idxSection = UniqFindTagWrite("Section"); + Pkg->Section = idxSection; + } string const static myArch = _config->Find("APT::Architecture"); // Possible values are: "all", "native", "installed" and "none" -- cgit v1.2.3 From 8f617600aeb931574baf0b53617e7759baa3f370 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 24 Aug 2014 18:43:07 +0200 Subject: Fix debListParser to accept "no" as a value for the Multi-Arch field Seems this was missed somehow. Closes: #759099 --- apt-pkg/deb/deblistparser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 02b9cb239..28c898542 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -108,7 +108,7 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/ { unsigned char MA; string const MultiArch = Section.FindS("Multi-Arch"); - if (MultiArch.empty() == true) + if (MultiArch.empty() == true || MultiArch == "no") MA = pkgCache::Version::None; else if (MultiArch == "same") { if (ArchitectureAll() == true) -- cgit v1.2.3 From 19fb04e82cdc90d429777fcc4c7a2b33e34d20e5 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 24 Aug 2014 18:43:07 +0200 Subject: Fix debListParser to accept "no" as a value for the Multi-Arch field Seems this was missed somehow. Closes: #759099 --- apt-pkg/deb/deblistparser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 30ae91cca..4ac5aa238 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -108,7 +108,7 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/ { unsigned char MA; string const MultiArch = Section.FindS("Multi-Arch"); - if (MultiArch.empty() == true) + if (MultiArch.empty() == true || MultiArch == "no") MA = pkgCache::Version::None; else if (MultiArch == "same") { if (ArchitectureAll() == true) -- cgit v1.2.3 From 40faab46c4d5fa766c80090f0fdb54120dbb37f2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 16 Aug 2014 16:33:46 +0200 Subject: support versioned provides as implemented by dpkg APT supported versioned provides for a long while in an attempt to get it working with rpm. While this support is old, we can be relatively sure that it works as versioned provides are used internally to make Multi-Arch:foreign work. Previous versions of apt will print a warning indicating that the versioned provides is ignored, so that something which "Provides: foo (= 2)" doesn't provide anything. Note that dpkg does allow only a equals-relation in the provides line as anything else is deemed too complex. apt doesn't support anything else either and such a support would require potentially big changes. Closes: 758153 --- apt-pkg/deb/deblistparser.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 28c898542..7d4fd52cf 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -803,8 +803,8 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) Start = ParseDepends(Start,Stop,Package,Version,Op); if (Start == 0) return _error->Error("Problem parsing Provides line"); - if (Op != pkgCache::Dep::NoOp) { - _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str()); + if (Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals) { + _error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.c_str()); } else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) { if (NewProvidesAllArch(Ver, Package, Version) == false) return false; -- cgit v1.2.3 From 78a5476f3177a2a74ae51a1878c26ca322a25003 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 20 Jun 2014 21:33:56 +0200 Subject: drop stored StringItems in favor of in-memory mappings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Strings like Section names or architectures are needed vary often. Instead of writing them each time we need them, we deploy sharing for these special strings. Until now, this was done with a linked list of strings in which we would search, which was stored in the cache. It turns out we can do this just as well in memory as well with a bunch of std::map's. In memory means here that it isn't available anymore if we have a partly invalid cache, but that isn't much of a problem in practice as the status file is compared to the other files we parse very small and includes mostly duplicates, so the space we would gain by storing is more or less equal to the size of the stored linked list… --- apt-pkg/deb/deblistparser.cc | 45 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 3e0d3a791..9919d2036 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -58,18 +58,6 @@ debListParser::debListParser(FileFd *File, string const &Arch) : Tags(File), MultiArchEnabled = Architectures.size() > 1; } /*}}}*/ -// ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ -// --------------------------------------------------------------------- -/* */ -map_stringitem_t debListParser::UniqFindTagWrite(const char *Tag) -{ - const char *Start; - const char *Stop; - if (Section.Find(Tag,Start,Stop) == false) - return 0; - return WriteUniqString(Start,Stop - Start); -} - /*}}}*/ // ListParser::Package - Return the package name /*{{{*/ // --------------------------------------------------------------------- /* This is to return the name of the package this section describes */ @@ -144,9 +132,16 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/ /* */ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) { + const char *Start; + const char *Stop; + // Parse the section - unsigned long const idxSection = UniqFindTagWrite("Section"); - Ver->Section = idxSection; + if (Section.Find("Section",Start,Stop) == true) + { + map_stringitem_t const idx = StoreString(pkgCacheGenerator::SECTION, Start, Stop - Start); + Ver->Section = idx; + } + Ver->MultiArch = ParseMultiArch(true); // Archive Size Ver->Size = Section.FindULL("Size"); @@ -155,10 +150,8 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) Ver->InstalledSize *= 1024; // Priority - const char *Start; - const char *Stop; if (Section.Find("Priority",Start,Stop) == true) - { + { if (GrabWord(string(Start,Stop-Start),PrioList,Ver->Priority) == false) Ver->Priority = pkgCache::State::Extra; } @@ -891,7 +884,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, { // apt-secure does no longer download individual (per-section) Release // file. to provide Component pinning we use the section name now - map_stringitem_t const storage = WriteUniqString(component); + map_stringitem_t const storage = StoreString(pkgCacheGenerator::MIXED, component); FileI->Component = storage; pkgTagFile TagFile(&File, File.Size()); @@ -900,19 +893,19 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, return false; std::string data; - #define APT_INRELEASE(TAG, STORE) \ + #define APT_INRELEASE(TYPE, TAG, STORE) \ data = Section.FindS(TAG); \ if (data.empty() == false) \ { \ - map_stringitem_t const storage = WriteUniqString(data); \ + map_stringitem_t const storage = StoreString(pkgCacheGenerator::TYPE, data); \ STORE = storage; \ } - APT_INRELEASE("Suite", FileI->Archive) - APT_INRELEASE("Component", FileI->Component) - APT_INRELEASE("Version", FileI->Version) - APT_INRELEASE("Origin", FileI->Origin) - APT_INRELEASE("Codename", FileI->Codename) - APT_INRELEASE("Label", FileI->Label) + APT_INRELEASE(MIXED, "Suite", FileI->Archive) + APT_INRELEASE(MIXED, "Component", FileI->Component) + APT_INRELEASE(VERSION, "Version", FileI->Version) + APT_INRELEASE(MIXED, "Origin", FileI->Origin) + APT_INRELEASE(MIXED, "Codename", FileI->Codename) + APT_INRELEASE(MIXED, "Label", FileI->Label) #undef APT_INRELEASE Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic); Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades); -- cgit v1.2.3 From a221efc331693f8905da870141756c892911c433 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 20 Jun 2014 19:34:40 +0200 Subject: store source name and version in binary cache Accessing the package records to acquire this information is pretty costly, so that information wasn't used so far in many places. The most noticeable user by far is EDSP at the moment, but there are ideas to change that which this commit tries to enable. --- apt-pkg/deb/deblistparser.cc | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 9919d2036..103b126de 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -141,6 +141,57 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) map_stringitem_t const idx = StoreString(pkgCacheGenerator::SECTION, Start, Stop - Start); Ver->Section = idx; } + // Parse the source package name + pkgCache::GrpIterator const G = Ver.ParentPkg().Group(); + Ver->SourcePkgName = G->Name; + Ver->SourceVerStr = Ver->VerStr; + if (Section.Find("Source",Start,Stop) == true) + { + const char * const Space = (const char * const) memchr(Start, ' ', Stop - Start); + pkgCache::VerIterator V; + + if (Space != NULL) + { + Stop = Space; + const char * const Open = (const char * const) memchr(Space, '(', Stop - Space); + if (likely(Open != NULL)) + { + const char * const Close = (const char * const) memchr(Open, ')', Stop - Open); + if (likely(Close != NULL)) + { + std::string const version(Open + 1, (Close - Open) - 1); + if (version != Ver.VerStr()) + { + map_stringitem_t const idx = StoreString(pkgCacheGenerator::VERSION, version); + Ver->SourceVerStr = idx; + } + } + } + } + + std::string const pkgname(Start, Stop - Start); + if (pkgname != G.Name()) + { + for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P)) + { + for (V = P.VersionList(); V.end() == false; ++V) + { + if (pkgname == V.SourcePkgName()) + { + Ver->SourcePkgName = V->SourcePkgName; + break; + } + } + if (V.end() == false) + break; + } + if (V.end() == true) + { + map_stringitem_t const idx = StoreString(pkgCacheGenerator::PKGNAME, pkgname); + Ver->SourcePkgName = idx; + } + } + } Ver->MultiArch = ParseMultiArch(true); // Archive Size -- cgit v1.2.3 From 30b45652d6b8c710e7a5e7e95cfa431a5df4462c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 3 Oct 2014 00:18:53 +0200 Subject: rename StringType VERSION to VERSIONNUMBER aptitude has a define for VERSION, so to not generate a FTBFS we just rename our enum element to a slightly less generic name. Git-Dch: Ignore --- apt-pkg/deb/deblistparser.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 103b126de..63414c944 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -162,7 +162,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) std::string const version(Open + 1, (Close - Open) - 1); if (version != Ver.VerStr()) { - map_stringitem_t const idx = StoreString(pkgCacheGenerator::VERSION, version); + map_stringitem_t const idx = StoreString(pkgCacheGenerator::VERSIONNUMBER, version); Ver->SourceVerStr = idx; } } @@ -953,7 +953,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, } APT_INRELEASE(MIXED, "Suite", FileI->Archive) APT_INRELEASE(MIXED, "Component", FileI->Component) - APT_INRELEASE(VERSION, "Version", FileI->Version) + APT_INRELEASE(VERSIONNUMBER, "Version", FileI->Version) APT_INRELEASE(MIXED, "Origin", FileI->Origin) APT_INRELEASE(MIXED, "Codename", FileI->Codename) APT_INRELEASE(MIXED, "Label", FileI->Label) -- cgit v1.2.3 From ac81c0f9b79351258d3a29212f7fda312e5afeb5 Mon Sep 17 00:00:00 2001 From: josch Date: Tue, 19 Aug 2014 10:29:29 +0200 Subject: implement the updated build profile spec --- apt-pkg/deb/deblistparser.cc | 112 ++++++++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 45 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 7d4fd52cf..8311b5d7d 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -635,72 +635,94 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, if (ParseRestrictionsList == true) { - // Parse a restrictions list - if (I != Stop && *I == '<') + // Parse a restrictions formula which is in disjunctive normal form: + // (foo AND bar) OR (blub AND bla) + + std::vector const profiles = APT::Configuration::getBuildProfiles(); + + // if the next character is a restriction list, then by default the + // dependency does not apply and the conditions have to be checked + // if the next character is not a restriction list, then by default the + // dependency applies + bool applies1 = (*I != '<'); + while (I != Stop) { + if (*I != '<') + break; + ++I; // malformed if (unlikely(I == Stop)) return 0; - std::vector const profiles = APT::Configuration::getBuildProfiles(); - const char *End = I; - bool Found = false; - bool NegRestriction = false; - while (I != Stop) - { - // look for whitespace or ending '>' - for (;End != Stop && !isspace(*End) && *End != '>'; ++End); - if (unlikely(End == Stop)) - return 0; - - if (*I == '!') + // if of the prior restriction list is already fulfilled, then + // we can just skip to the end of the current list + if (applies1) { + for (;End != Stop && *End != '>'; ++End); + I = ++End; + // skip whitespace + for (;I != Stop && isspace(*I) != 0; I++); + } else { + bool applies2 = true; + // all the conditions inside a restriction list have to be + // met so once we find one that is not met, we can skip to + // the end of this list + while (I != Stop) { - NegRestriction = true; - ++I; - } + // look for whitespace or ending '>' + // End now points to the character after the current term + for (;End != Stop && !isspace(*End) && *End != '>'; ++End); - std::string restriction(I, End); + if (unlikely(End == Stop)) + return 0; - std::string prefix = "profile."; - // only support for "profile" prefix, ignore others - if (restriction.size() > prefix.size() && - restriction.substr(0, prefix.size()) == prefix) - { - // get the name of the profile - restriction = restriction.substr(prefix.size()); + bool NegRestriction = false; + if (*I == '!') + { + NegRestriction = true; + ++I; + } + + std::string restriction(I, End); if (restriction.empty() == false && profiles.empty() == false && - std::find(profiles.begin(), profiles.end(), restriction) != profiles.end()) + std::find(profiles.begin(), profiles.end(), restriction) != profiles.end()) { - Found = true; - if (I[-1] != '!') - NegRestriction = false; - // we found a match, so fast-forward to the end of the wildcards - for (; End != Stop && *End != '>'; ++End); + if (NegRestriction) { + applies2 = false; + // since one of the terms does not apply we don't have to check the others + for (; End != Stop && *End != '>'; ++End); + } + } else { + if (!NegRestriction) { + applies2 = false; + // since one of the terms does not apply we don't have to check the others + for (; End != Stop && *End != '>'; ++End); + } + } + + if (*End++ == '>') { + I = End; + // skip whitespace + for (;I != Stop && isspace(*I) != 0; I++); + break; } - } - if (*End++ == '>') { I = End; - break; + // skip whitespace + for (;I != Stop && isspace(*I) != 0; I++); + } + if (applies2) { + applies1 = true; } - - I = End; - for (;I != Stop && isspace(*I) != 0; I++); } - - if (NegRestriction == true) - Found = !Found; - - if (Found == false) - Package = ""; /* not for this restriction */ } - // Skip whitespace - for (;I != Stop && isspace(*I) != 0; I++); + if (applies1 == false) { + Package = ""; //not for this restriction + } } if (I != Stop && *I == '|') -- cgit v1.2.3 From 9227645d6d355f9f4332f400b8d58c8fa8f1e899 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Mon, 1 Sep 2014 16:09:48 +0200 Subject: Update Status field values handling Remove long obsolete (hold, hold-reinstreq, removal-failed) or just wrong (post-inst-failed vs postinst-failed) values, that have been autoconverted by dpkg at run-time to their new equivalents, so there should not be any such instance in any recent system (removal-failed since dpkg 1.1.4 in Apr 1996, hold and hold-reinstreq since dpkg 1.2.0 in May 1996). dpkg even stopped doing the mapping in 1.15.4 and 1.15.8 respectively. At the same time sort the list in the same order as they appear in the dpkg code. --- apt-pkg/deb/deblistparser.cc | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 8311b5d7d..4eef66c2b 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -338,13 +338,9 @@ unsigned short debListParser::VersionHash() /* Status lines are of the form, Status: want flag status want = unknown, install, hold, deinstall, purge - flag = ok, reinstreq, hold, hold-reinstreq - status = not-installed, unpacked, half-configured, - half-installed, config-files, post-inst-failed, - removal-failed, installed - - Some of the above are obsolete (I think?) flag = hold-* and - status = post-inst-failed, removal-failed at least. + flag = ok, reinstreq + status = not-installed, config-files, half-installed, unpacked, + half-configured, triggers-awaited, triggers-pending, installed */ bool debListParser::ParseStatus(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver) @@ -401,15 +397,13 @@ bool debListParser::ParseStatus(pkgCache::PkgIterator &Pkg, // Process the flag field WordList StatusList[] = {{"not-installed",pkgCache::State::NotInstalled}, + {"config-files",pkgCache::State::ConfigFiles}, + {"half-installed",pkgCache::State::HalfInstalled}, {"unpacked",pkgCache::State::UnPacked}, {"half-configured",pkgCache::State::HalfConfigured}, - {"installed",pkgCache::State::Installed}, - {"half-installed",pkgCache::State::HalfInstalled}, - {"config-files",pkgCache::State::ConfigFiles}, {"triggers-awaited",pkgCache::State::TriggersAwaited}, {"triggers-pending",pkgCache::State::TriggersPending}, - {"post-inst-failed",pkgCache::State::HalfConfigured}, - {"removal-failed",pkgCache::State::HalfInstalled}, + {"installed",pkgCache::State::Installed}, {NULL, 0}}; if (GrabWord(string(Start,I-Start),StatusList,Pkg->CurrentState) == false) return _error->Error("Malformed 3rd word in the Status line"); -- cgit v1.2.3 From 862bafea48af2ceaf96345db237b461307a021f6 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 13 Oct 2014 08:05:57 +0200 Subject: do not inline virtual destructors with d-pointers Reimplementing an inline method is opening a can of worms we don't want to open if we ever want to us a d-pointer in those classes, so we do the only thing which can save us from hell: move the destructors into the cc sources and we are good. Technically not an ABI break as the methods inline or not do the same (nothing), so a program compiled against the old version still works with the new version (beside that this version is still in experimental, so nothing really has been build against this library anyway). Git-Dch: Ignore --- apt-pkg/deb/deblistparser.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 63414c944..502bd1a51 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -1015,5 +1015,4 @@ bool debDebFileParser::UsePackage(pkgCache::PkgIterator &Pkg, return res; } - - +debListParser::~debListParser() {} -- cgit v1.2.3 From ccf6bdb3efc54165c76b42aae94c498a36acbe1b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 7 Nov 2014 14:20:36 +0100 Subject: use a abi version check similar to the gcc check Git-Dch: Ignore --- apt-pkg/deb/deblistparser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 616d8296d..42db341b3 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -992,7 +992,7 @@ unsigned char debListParser::GetPrio(string Str) return Out; } /*}}}*/ -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) +#if APT_PKG_ABI >= 413 bool debListParser::SameVersion(unsigned short const Hash, /*{{{*/ pkgCache::VerIterator const &Ver) { -- cgit v1.2.3 From 765190e493645e13b5651625d87fd9c8db910a85 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 7 Nov 2014 16:45:18 +0100 Subject: guard ABI changes for SourcePkg/Ver in pkgCache Git-Dch: Ignore --- apt-pkg/deb/deblistparser.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 42db341b3..462818a03 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -141,6 +141,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) map_stringitem_t const idx = StoreString(pkgCacheGenerator::SECTION, Start, Stop - Start); Ver->Section = idx; } +#if APT_PKG_ABI >= 413 // Parse the source package name pkgCache::GrpIterator const G = Ver.ParentPkg().Group(); Ver->SourcePkgName = G->Name; @@ -192,6 +193,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) } } } +#endif Ver->MultiArch = ParseMultiArch(true); // Archive Size -- cgit v1.2.3 From b209edfa318e89df31a2dcae82c3d72b48c1e77f Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Mon, 9 Mar 2015 18:11:10 +0100 Subject: parse arch-qualified Provides correctly The underlying problem is that libapt-pkg does not correctly parse these provides. Internally, it creates a version named "baz:i386" with architecture amd64. Of course, such a package name is invalid and thus this version is completely inaccessible. Thus, this bug should not cause apt to accept a broken situation as valid. Nevertheless, it prevents using architecture qualified depends. Closes: 777071 --- apt-pkg/deb/deblistparser.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 462818a03..49bc3adfc 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -853,10 +853,16 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) while (1) { Start = ParseDepends(Start,Stop,Package,Version,Op); + const size_t archfound = Package.rfind(':'); if (Start == 0) return _error->Error("Problem parsing Provides line"); if (Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals) { _error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.c_str()); + } else if (archfound != string::npos) { + string OtherArch = Package.substr(archfound+1, string::npos); + Package = Package.substr(0, archfound); + if (NewProvides(Ver, Package, OtherArch, Version) == false) + return false; } else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) { if (NewProvidesAllArch(Ver, Package, Version) == false) return false; -- cgit v1.2.3 From 596ec43ce34421080a58b28299c1ed9cb0dbaa25 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 12 Apr 2015 19:16:01 +0200 Subject: parse specific-arch dependencies correctly on single-arch systems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On single-arch the parsing was creating groupnames like 'apt:amd64' even through it should be 'apt' and a package in it belonging to architecture amd64. The result for foreign architectures was as expected: The dependency isn't satisfiable, but for native architecture it means the wrong package (ala apt:amd64:amd64) is linked so this is also not satisfiable, which is very much not expected. No longer excluding single-arch from this codepath allows the generation of the correct links, which still link to non-exisiting packages for foreign dependencies, but natives link to the expected native package just as if no architecture was given. For negative arch-specific dependencies ala Conflicts this matter was worse as apt will believe there isn't a Conflict to resolve, tricking it into calculating a solution dpkg will refuse. Architecture specific positive dependencies are rare in jessie – the only one in amd64 main is foreign –, negative dependencies do not even exist. Neither class has a native specimen, so no package in jessie is effected by this bug, but it might be interesting for stretch upgrades. This also means the regression potential is very low. Closes: 777760 --- apt-pkg/deb/deblistparser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 4eef66c2b..213235c2b 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -770,7 +770,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver, if (NewDepends(Ver,Package,"none",Version,Op,Type) == false) return false; } - else if (MultiArchEnabled == true && found != string::npos && + else if (found != string::npos && strcmp(Package.c_str() + found, ":any") != 0) { string Arch = Package.substr(found+1, string::npos); -- cgit v1.2.3