summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hartwig <mandyke@gmail.com>2012-06-30 18:59:05 +0800
committerDaniel Hartwig <mandyke@gmail.com>2012-06-30 18:59:05 +0800
commit7bffef4700d3ceb864cc2c05c9ecbc8731388997 (patch)
treebe922521b8aa504dd7cd0183ee573c6eba12ba23
parentb6855eaa5128fee88b31a0d67f41f1a745a9afcf (diff)
downloadaptitude-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--NEWS4
-rw-r--r--src/generic/apt/tags.cc83
2 files changed, 80 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 1e0e2bac..653557a1 100644
--- a/NEWS
+++ b/NEWS
@@ -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();