diff options
author | Daniel Hartwig <mandyke@gmail.com> | 2012-06-30 18:59:05 +0800 |
---|---|---|
committer | Daniel Hartwig <mandyke@gmail.com> | 2012-06-30 18:59:05 +0800 |
commit | 7bffef4700d3ceb864cc2c05c9ecbc8731388997 (patch) | |
tree | be922521b8aa504dd7cd0183ee573c6eba12ba23 | |
parent | b6855eaa5128fee88b31a0d67f41f1a745a9afcf (diff) | |
download | aptitude-7bffef4700d3ceb864cc2c05c9ecbc8731388997.tar.gz |
Read tags from debtags database even when libept is disabled
.. but fall back to Packages files if the database is not available.
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | src/generic/apt/tags.cc | 83 |
2 files changed, 80 insertions, 7 deletions
@@ -165,6 +165,10 @@ ii. to make the program more atomic and reliable when used * Use standard apt-xapian-index location, rather than libept. + * Read tags from debtags database even when libept is + disabled, but fall back to Packages files if the database + is not available. + - Cosmetic and UI bugs: * [cmdline]: Use arch-qualified names for virtual packages in diff --git a/src/generic/apt/tags.cc b/src/generic/apt/tags.cc index 57cf54e2..f0d482b0 100644 --- a/src/generic/apt/tags.cc +++ b/src/generic/apt/tags.cc @@ -149,10 +149,20 @@ typedef set<tag> db_entry; // to provide a progress bar to the user. db_entry *tagDB; +static void insert_tags(std::set<tag> &tags, + const char *start, + const char *finish) +{ + const tag_list lst(start, finish); + + for(tag_list::const_iterator t=lst.begin(); t!=lst.end(); ++t) + tags.insert(*t); +} + static void insert_tags(const pkgCache::VerIterator &ver, const pkgCache::VerFileIterator &vf) { - set<tag> *tags = tagDB + ver.ParentPkg()->ID; + set<tag> *tags = tagDB + ver.ParentPkg().Group()->ID; const char *recstart=0, *recend=0; const char *tagstart, *tagend; @@ -170,10 +180,7 @@ static void insert_tags(const pkgCache::VerIterator &ver, if(!sec.Find("Tag", tagstart, tagend)) return; - tag_list lst(tagstart, tagend); - - for(tag_list::const_iterator t=lst.begin(); t!=lst.end(); ++t) - tags->insert(*t); + insert_tags((*tags), tagstart, tagend); } static void reset_tags() @@ -187,7 +194,60 @@ const std::set<tag> aptitude::apt::get_tags(const pkgCache::PkgIterator &pkg) if(!apt_cache_file || !tagDB) return std::set<tag>(); - return tagDB[pkg->ID]; + return tagDB[pkg.Group()->ID]; +} + +static bool read_debtags_package_tags(OpProgress *progress, + const std::string &filename) +{ + FileFd F(filename, FileFd::ReadOnly); + + if(!F.IsOpen()) + { + // _error->Warning(_("Unable to load debtags package tags, perhaps" + // " debtags is not installed?")); + // Fail silently; debtags need not be installed. + return false; + } + + const unsigned long m = (*apt_cache_file)->Head().GroupCount; + unsigned long n = 0; + + if(progress != NULL) + progress->OverallProgress(0, m, 1, + _("Building tag database")); + + const unsigned long long buf_size = 4096; + char buf[buf_size]; + while(F.ReadLine(buf, buf_size) != NULL) + { + if(progress != NULL) + progress->OverallProgress(++n, m, 1, + _("Building tag database")); + + const char *sep = strstr(buf, ": "); + if(sep == NULL) + continue; + + const string pkg_name(buf, sep - buf); + const pkgCache::GrpIterator grp((*apt_cache_file)->FindGrp(pkg_name)); + if(grp.end() == true) + continue; + + set<tag> *tags = tagDB + grp->ID; + + const char *tagstart = sep + 2; + const char *tagend = tagstart; + while((*tagend) != '\0') + ++tagend; + + insert_tags((*tags), tagstart, tagend); + } + + if(progress != NULL) + progress->Done(); + + return true; } bool initialized_reset_signal; @@ -202,8 +262,17 @@ void aptitude::apt::load_tags(OpProgress *progress) initialized_reset_signal = true; } - tagDB = new db_entry[(*apt_cache_file)->Head().PackageCount]; + tagDB = new db_entry[(*apt_cache_file)->Head().GroupCount]; + + // Try to load from the debtags database + { + const string filename(aptcfg->FindFile("Debtags::Package-Tags", + "/var/lib/debtags/package-tags")); + if(read_debtags_package_tags(progress, filename) == true) + return; + } + // Otherwise fall back to reading the Packages files directly std::vector<loc_pair> verfiles; for(pkgCache::PkgIterator p = (*apt_cache_file)->PkgBegin(); |