diff options
Diffstat (limited to 'apt-private')
-rw-r--r-- | apt-private/private-cacheset.h | 15 | ||||
-rw-r--r-- | apt-private/private-list.cc | 2 | ||||
-rw-r--r-- | apt-private/private-show.cc | 69 |
3 files changed, 69 insertions, 17 deletions
diff --git a/apt-private/private-cacheset.h b/apt-private/private-cacheset.h index d20d00b68..3370bd03a 100644 --- a/apt-private/private-cacheset.h +++ b/apt-private/private-cacheset.h @@ -26,6 +26,7 @@ public: {} const pkgCache::DescFile * CachedDescFile() const { return descFile; } operator pkgCache::VerIterator() const { return iter; } + map_id_t ID() const { return iter->ID; } }; struct VersionSortDescriptionLocality /*{{{*/ @@ -36,17 +37,21 @@ struct VersionSortDescriptionLocality /*{{{*/ pkgCache::DescFile const *A = v_lhs.CachedDescFile(); pkgCache::DescFile const *B = v_rhs.CachedDescFile(); - if (A == nullptr && B == nullptr) - return false; - if (A == nullptr) + { + if (B == nullptr) + return v_lhs.ID() < v_rhs.ID(); return true; - - if (B == nullptr) + } + else if (B == nullptr) return false; if (A->File == B->File) + { + if (A->Offset == B->Offset) + return v_lhs.ID() < v_rhs.ID(); return A->Offset < B->Offset; + } return A->File < B->File; } diff --git a/apt-private/private-list.cc b/apt-private/private-list.cc index 2c9b349a3..7c8c89777 100644 --- a/apt-private/private-list.cc +++ b/apt-private/private-list.cc @@ -129,7 +129,7 @@ bool DoList(CommandLine &Cmd) else ListSingleVersion(CacheFile, records, V, outs, format); output_map.insert(std::make_pair<std::string, std::string>( - V.ParentPkg().Name(), outs.str())); + V.ParentPkg().FullName(), outs.str())); } // FIXME: SORT! and make sorting flexible (alphabetic, by pkg status) diff --git a/apt-private/private-show.cc b/apt-private/private-show.cc index 15c05d420..b69008ec9 100644 --- a/apt-private/private-show.cc +++ b/apt-private/private-show.cc @@ -42,7 +42,7 @@ pkgRecords::Parser &LookupParser(pkgRecords &Recs, pkgCache::VerIterator const & return Recs.Lookup(Vf); } /*}}}*/ -static APT_PURE char const *skipDescriptionFields(char const *DescP, size_t const Length) /*{{{*/ +static APT_PURE char const *skipDescription(char const *DescP, size_t const Length, bool fields) /*{{{*/ { auto const backup = DescP; char const * const TagName = "\nDescription"; @@ -51,7 +51,7 @@ static APT_PURE char const *skipDescriptionFields(char const *DescP, size_t cons { if (DescP[1] == ' ') DescP += 2; - else if (strncmp((char*)DescP, TagName, TagLen) == 0) + else if (fields && strncmp((char *)DescP, TagName, TagLen) == 0) DescP += TagLen; else break; @@ -78,19 +78,43 @@ static APT_PURE char const *findDescriptionField(char const *DescP, size_t const return DescP; } /*}}}*/ +static APT_PURE char const *skipColonSpaces(char const *Buffer, size_t const Length) /*{{{*/ +{ + // skipping withspace before and after the field-value separating colon + char const *const Start = Buffer; + for (; isspace(*Buffer) != 0 && Length - (Buffer - Start) > 0; ++Buffer) + ; + if (*Buffer != ':') + return nullptr; + ++Buffer; + for (; isspace(*Buffer) != 0 && Length - (Buffer - Start) > 0; ++Buffer) + ; + if (Length - (Buffer - Start) <= 0) + return nullptr; + return Buffer; +} + /*}}}*/ bool DisplayRecordV1(pkgCacheFile &, pkgRecords &Recs, /*{{{*/ - pkgCache::VerIterator const &V, pkgCache::VerFileIterator const &, + pkgCache::VerIterator const &V, pkgCache::VerFileIterator const &Vf, char const *Buffer, size_t Length, std::ostream &out) { - if (unlikely(Length == 0)) + if (unlikely(Length < 4)) return false; auto const Desc = V.TranslatedDescription(); if (Desc.end()) { - // we have no translation output whatever we have got - return FileFd::Write(STDOUT_FILENO, Buffer, Length); + /* This handles the unusual case that we have no description whatsoever. + The slightly more common case of only having a short-description embedded + in the record could be handled here, but apt supports also having multiple + descriptions embedded in the record, so we deal with that case later */ + if (FileFd::Write(STDOUT_FILENO, Buffer, Length) == false) + return false; + if (strncmp((Buffer + Length - 4), "\r\n\r\n", 4) != 0 && + strncmp((Buffer + Length - 2), "\n\n", 2) != 0) + out << std::endl; + return true; } // Get a pointer to start of Description field @@ -111,18 +135,41 @@ bool DisplayRecordV1(pkgCacheFile &, pkgRecords &Recs, /*{{{*/ else snprintf(desctag, sizeof(desctag), "\nDescription-%s", langcode); - out << desctag + 1 << ": "; + out << desctag + 1 << ": " << std::flush; auto const Df = Desc.FileList(); if (Df.end() == false) { - pkgRecords::Parser &P = Recs.Lookup(Df); - out << P.LongDesc(); + if (Desc.FileList()->File == Vf->File) + { + /* If we have the file already open look in the buffer for the + description we want to display. Note that this might not be the + only one we can encounter in this record */ + char const *Start = DescP; + do + { + if (strncmp(Start, desctag + 1, strlen(desctag) - 1) != 0) + continue; + Start += strlen(desctag) - 1; + Start = skipColonSpaces(Start, Length - (Start - Buffer)); + if (Start == nullptr) + continue; + char const *End = skipDescription(Start, Length - (Start - Buffer), false); + if (likely(End != nullptr)) + FileFd::Write(STDOUT_FILENO, Start, End - (Start + 1)); + break; + } while ((Start = findDescriptionField(Start, Length - (Start - Buffer))) != nullptr); + } + else + { + pkgRecords::Parser &P = Recs.Lookup(Df); + out << P.LongDesc(); + } } out << std::endl << "Description-md5: " << Desc.md5() << std::endl; // Find the first field after the description (if there is any) - DescP = skipDescriptionFields(DescP, Length - (DescP - Buffer)); + DescP = skipDescription(DescP, Length - (DescP - Buffer), true); // write the rest of the buffer, but skip mixed in Descriptions* fields while (DescP != nullptr) @@ -150,7 +197,7 @@ bool DisplayRecordV1(pkgCacheFile &, pkgRecords &Recs, /*{{{*/ ++End; } else - DescP = skipDescriptionFields(End + strlen("Description"), Length - (End - Buffer)); + DescP = skipDescription(End + strlen("Description"), Length - (End - Buffer), true); size_t const length = End - Start; if (length != 0 && FileFd::Write(STDOUT_FILENO, Start, length) == false) |