r170 - in libdebtags/trunk: src tests

Enrico Zini deb-usability-list@lists.alioth.debian.org
Wed, 21 Jul 2004 16:30:33 -0600


Author: enrico
Date: Wed Jul 21 16:30:33 2004
New Revision: 170

Added:
   libdebtags/trunk/src/DebtagsMaintainerSet.cc
      - copied, changed from r168, libdebtags/trunk/src/DebtagsMaintainerGroup.cc
   libdebtags/trunk/src/DebtagsMaintainerSet.h
      - copied, changed from r168, libdebtags/trunk/src/DebtagsMaintainerGroup.h
   libdebtags/trunk/src/DebtagsPackageDataFilter.cc
      - copied unchanged from r168, libdebtags/trunk/src/DebtagsFilter.cc
   libdebtags/trunk/src/DebtagsPackageDataFilter.h
      - copied unchanged from r168, libdebtags/trunk/src/DebtagsFilter.h
   libdebtags/trunk/src/DebtagsPackageFilter.cc
   libdebtags/trunk/src/DebtagsPackageFilter.h
   libdebtags/trunk/src/DebtagsPackageSet.cc
      - copied, changed from r168, libdebtags/trunk/src/DebtagsPackageGroup.cc
   libdebtags/trunk/src/DebtagsPackageSet.h
      - copied, changed from r168, libdebtags/trunk/src/DebtagsPackageGroup.h
   libdebtags/trunk/src/DebtagsTagFilter.cc
   libdebtags/trunk/src/DebtagsTagFilter.h
   libdebtags/trunk/src/DebtagsTagSet.cc
      - copied, changed from r168, libdebtags/trunk/src/DebtagsTagGroup.cc
   libdebtags/trunk/src/DebtagsTagSet.h
      - copied, changed from r168, libdebtags/trunk/src/DebtagsTagGroup.h
Removed:
   libdebtags/trunk/src/DebtagsFilter.cc
   libdebtags/trunk/src/DebtagsFilter.h
   libdebtags/trunk/src/DebtagsMaintainerGroup.cc
   libdebtags/trunk/src/DebtagsMaintainerGroup.h
   libdebtags/trunk/src/DebtagsPackageGroup.cc
   libdebtags/trunk/src/DebtagsPackageGroup.h
   libdebtags/trunk/src/DebtagsTagGroup.cc
   libdebtags/trunk/src/DebtagsTagGroup.h
Modified:
   libdebtags/trunk/src/DebtagsConsumer.h
   libdebtags/trunk/src/DebtagsEnvironment.cc
   libdebtags/trunk/src/DebtagsEnvironment.h
   libdebtags/trunk/src/DebtagsMaintainer.cc
   libdebtags/trunk/src/DebtagsMaintainer.h
   libdebtags/trunk/src/DebtagsPackage.cc
   libdebtags/trunk/src/DebtagsPackage.h
   libdebtags/trunk/src/DebtagsTag.cc
   libdebtags/trunk/src/DebtagsTag.h
   libdebtags/trunk/src/DebtagsTagDB.cc
   libdebtags/trunk/src/DebtagsTagDB.h
   libdebtags/trunk/src/DebtagsVocabulary.cc
   libdebtags/trunk/src/DebtagsVocabulary.h
   libdebtags/trunk/src/Makefile.am
   libdebtags/trunk/src/instantiations.cc
   libdebtags/trunk/tests/Makefile.am
   libdebtags/trunk/tests/test-packages.cc
Log:
Included Package::tags() tests in test-packages
Implemented filters for various kind of objects, and renamed Filter into PackageFilter
Renamed *Group in *Set, as they are sets with set operations implemented
Implemented Debtags::Vocabulary as a FacetSet
Improved Facet and Tag interfaces


Modified: libdebtags/trunk/src/DebtagsConsumer.h
==============================================================================
--- libdebtags/trunk/src/DebtagsConsumer.h	(original)
+++ libdebtags/trunk/src/DebtagsConsumer.h	Wed Jul 21 16:30:33 2004
@@ -27,6 +27,9 @@
 {
 
 class Package;
+class Facet;
+class Tag;
+class Maintainer;
 
 class PackageConsumer
 {
@@ -34,12 +37,30 @@
 	virtual void consume(const Package&) throw () = 0;
 };
 
-class PackageFilter : public PackageConsumer
+class FacetConsumer
+{
+public:
+	virtual void consume(const Facet&) throw () = 0;
+};
+
+class TagConsumer
+{
+public:
+	virtual void consume(const Tag&) throw () = 0;
+};
+
+class MaintainerConsumer
+{
+public:
+	virtual void consume(const Maintainer&) throw () = 0;
+};
+
+class PackageStreamFilter : public PackageConsumer
 {
 protected:
 	PackageConsumer& next;
 public:
-	PackageFilter(PackageConsumer& next) throw () : next(next) {}
+	PackageStreamFilter(PackageConsumer& next) throw () : next(next) {}
 
 	virtual void consume(const Package& pkg) throw ()
 	{
@@ -47,6 +68,45 @@
 	}
 };
 
+class FacetStreamFilter : public FacetConsumer
+{
+protected:
+	FacetConsumer& next;
+public:
+	FacetStreamFilter(FacetConsumer& next) throw () : next(next) {}
+
+	virtual void consume(const Facet& pkg) throw ()
+	{
+		next.consume(pkg);
+	}
+};
+
+class TagStreamFilter : public TagConsumer
+{
+protected:
+	TagConsumer& next;
+public:
+	TagStreamFilter(TagConsumer& next) throw () : next(next) {}
+
+	virtual void consume(const Tag& pkg) throw ()
+	{
+		next.consume(pkg);
+	}
+};
+
+class MaintainerStreamFilter : public MaintainerConsumer
+{
+protected:
+	MaintainerConsumer& next;
+public:
+	MaintainerStreamFilter(MaintainerConsumer& next) throw () : next(next) {}
+
+	virtual void consume(const Maintainer& pkg) throw ()
+	{
+		next.consume(pkg);
+	}
+};
+
 };
 
 // vim:set ts=4 sw=4:

Modified: libdebtags/trunk/src/DebtagsEnvironment.cc
==============================================================================
--- libdebtags/trunk/src/DebtagsEnvironment.cc	(original)
+++ libdebtags/trunk/src/DebtagsEnvironment.cc	Wed Jul 21 16:30:33 2004
@@ -4,9 +4,9 @@
 
 #include "DebtagsEnvironment.h"
 #include "DebtagsConsumer.h"
-#include "DebtagsPackageGroup.h"
-#include "DebtagsMaintainerGroup.h"
-#include "DebtagsFilter.h"
+#include "DebtagsPackageSet.h"
+#include "DebtagsMaintainerSet.h"
+#include "DebtagsPackageFilter.h"
 #include "DebtagsVocabulary.h"
 #include "PackageDB.h"
 #include "DebtagsTagDB.h"
@@ -56,9 +56,9 @@
 	void loadVocabulary() const throw ();
 
 	// Packages repository
-	mutable PackageGroup _packages;
+	mutable PackageSet _packages;
 	// Maintainers repository
-	mutable MaintainerGroup _maintainers;
+	mutable MaintainerSet _maintainers;
 
 	mutable bool availableLoaded;
 	void loadAvailable() const throw ();
@@ -76,7 +76,7 @@
 	bool hasTagDatabase() throw ();
 
 	// Return the main package search class
-	const PackageGroup& packages() const throw ()
+	const PackageSet& packages() const throw ()
 	{
 		if (!availableLoaded)
 			loadAvailable();
@@ -84,7 +84,7 @@
 	}
 
 	// Return the main package search class
-	const MaintainerGroup& maintainers() const throw ()
+	const MaintainerSet& maintainers() const throw ()
 	{
 		if (!availableLoaded)
 			loadAvailable();
@@ -126,13 +126,13 @@
 	void output(PackageConsumer& cons) const throw ();
 
 	// Output the filtered package list to `cons'
-	void output(PackageConsumer& cons, Filter& filter) const throw ();
+	void output(PackageConsumer& cons, PackageFilter& filter) const throw ();
 
 
 	// Output list of packages related to `pivot' to `cons'
 	void outputRelated(PackageConsumer& cons, const Package& pivot, int distance = 1) const throw ();
 	// Output list of packages related to the specific tagset to `cons'
-	void outputRelated(PackageConsumer& cons, const TagGroup& ts, int distance = 1) const throw ();
+	void outputRelated(PackageConsumer& cons, const TagSet& ts, int distance = 1) const throw ();
 
 
 	// Update the Debtags database
@@ -348,8 +348,14 @@
 	if (!_packagedb.hasPackage(name))
 		return Package();
 
+	// Create the package in the repository
+	p = Package(name);
+	_packages += p;
+
 	// Load package info from the APT database
-	return fillPackageData(name);
+	//return fillPackageData(name);
+
+	return p;
 }
 
 Maintainer StandardEnvironment::getMaintainer(const std::string& name) const throw ()
@@ -378,7 +384,7 @@
 	}
 }
 
-void StandardEnvironment::output(PackageConsumer& cons, Filter& filter) const throw ()
+void StandardEnvironment::output(PackageConsumer& cons, PackageFilter& filter) const throw ()
 {
 	if (filter.hasNonDebtags() && !availableLoaded)
 		loadAvailable();
@@ -386,7 +392,7 @@
 	if (filter.hasOnlyMaintainer() && filter.isMaintainerSignificant())
 	{
 		fprintf(stderr, "Strategy0\n");
-		for (MaintainerGroup::const_iterator i = _maintainers.begin();
+		for (MaintainerSet::const_iterator i = _maintainers.begin();
 				i != _maintainers.end(); i++)
 			if (filter.matchMaintainer(i->fullname()))
 				i->packages().output(cons);
@@ -394,7 +400,7 @@
 	else if (filter.isMaintainerSignificant())
 	{
 		fprintf(stderr, "Strategy1\n");
-		for (MaintainerGroup::const_iterator i = _maintainers.begin();
+		for (MaintainerSet::const_iterator i = _maintainers.begin();
 				i != _maintainers.end(); i++)
 			if (filter.matchMaintainer(i->fullname()))
 				i->packages().output(cons, filter);
@@ -402,7 +408,7 @@
 	else if (filter.hasOnlyName())
 	{
 		fprintf(stderr, "Strategy2\n");
-		for (PackageGroup::const_iterator i = _packages.begin();
+		for (PackageSet::const_iterator i = _packages.begin();
 				i != _packages.end(); i++)
 			if (filter.matchName(i->name()))
 				cons.consume(*i);
@@ -410,12 +416,12 @@
 	else if (filter.hasOnlyDebtags())
 	{
 		fprintf(stderr, "Strategy3\n");
-		PackageGroup(_tagDB.getItemsContaining(filter.debtagsTagset())).output(cons);
+		PackageSet(_tagDB.getItemsContaining(filter.debtagsTagset())).output(cons);
 	}
 	else if (filter.hasDebtags())
 	{
 		fprintf(stderr, "Strategy4\n");
-		PackageGroup(_tagDB.getItemsContaining(filter.debtagsTagset())).output(cons, filter);
+		PackageSet(_tagDB.getItemsContaining(filter.debtagsTagset())).output(cons, filter);
 	}
 	else
 	{
@@ -430,14 +436,14 @@
 {
 	if (!debtagsLoaded)
 		loadDebtags();
-	PackageGroup(_tagDB.getRelatedItems(pivot, distance)).output(cons);
+	PackageSet(_tagDB.getRelatedItems(pivot, distance)).output(cons);
 }
 
-void StandardEnvironment::outputRelated(PackageConsumer& cons, const TagGroup& ts, int distance) const throw ()
+void StandardEnvironment::outputRelated(PackageConsumer& cons, const TagSet& ts, int distance) const throw ()
 {
 	if (!debtagsLoaded)
 		loadDebtags();
-	PackageGroup(_tagDB.getRelatedItems(ts, distance)).output(cons);
+	PackageSet(_tagDB.getRelatedItems(ts, distance)).output(cons);
 }
 
 // vim:set ts=4 sw=4:

Modified: libdebtags/trunk/src/DebtagsEnvironment.h
==============================================================================
--- libdebtags/trunk/src/DebtagsEnvironment.h	(original)
+++ libdebtags/trunk/src/DebtagsEnvironment.h	Wed Jul 21 16:30:33 2004
@@ -12,15 +12,15 @@
 
 class PackageDB;
 class PackageConsumer;
-class Filter;
+class PackageFilter;
 class Tag;
-class TagGroup;
+class TagSet;
 class TagDB;
 class Package;
 class PackageImpl;
-class PackageGroup;
+class PackageSet;
 class Maintainer;
-class MaintainerGroup;
+class MaintainerSet;
 class Vocabulary;
 
 class Environment
@@ -43,11 +43,11 @@
 	// Check if the tag database has been created (i.e. if debtags update has been run)
 	virtual bool hasTagDatabase() throw () = 0;
 
-	// Return a PackageGroup with all packages
-	virtual const PackageGroup& packages() const throw () = 0;
+	// Return a PackageSet with all packages
+	virtual const PackageSet& packages() const throw () = 0;
 
-	// Return a MaintainerGroup with all maintainers
-	virtual const MaintainerGroup& maintainers() const throw () = 0;
+	// Return a MaintainerSet with all maintainers
+	virtual const MaintainerSet& maintainers() const throw () = 0;
 
 	// Return the APT Package Database access class
 	virtual const PackageDB& packageDB() const throw () = 0;
@@ -71,14 +71,14 @@
 	virtual void output(PackageConsumer& cons) const throw () = 0;
 
 	// Output the filtered package list to `cons'
-	virtual void output(PackageConsumer& cons, Filter& filter) const throw () = 0;
+	virtual void output(PackageConsumer& cons, PackageFilter& filter) const throw () = 0;
 
 
 	// Output list of packages related to `pivot' to `cons'
 	virtual void outputRelated(PackageConsumer& cons, const Package& pivot, int distance = 1) const throw () = 0;
 
 	// Output list of packages related to the specific tagset to `cons'
-	virtual void outputRelated(PackageConsumer& cons, const TagGroup& ts, int distance = 1) const throw () = 0;
+	virtual void outputRelated(PackageConsumer& cons, const TagSet& ts, int distance = 1) const throw () = 0;
 
 
 	// Update the Debtags database

Modified: libdebtags/trunk/src/DebtagsMaintainer.cc
==============================================================================
--- libdebtags/trunk/src/DebtagsMaintainer.cc	(original)
+++ libdebtags/trunk/src/DebtagsMaintainer.cc	Wed Jul 21 16:30:33 2004
@@ -3,7 +3,7 @@
 #include "DebtagsMaintainer.h"
 #include "DebtagsEnvironment.h"
 #include "DebtagsPackage.h"
-#include "DebtagsPackageGroup.h"
+#include "DebtagsPackageSet.h"
 
 using namespace std;
 using namespace Debtags;
@@ -17,7 +17,7 @@
 	
 	std::string _email;
 	std::string _fullname;
-	PackageGroup _packages;
+	PackageSet _packages;
 
 public:
 	MaintainerImpl(const std::string& email) throw ();
@@ -88,7 +88,7 @@
 	impl->_packages += pkg;
 }
 
-const PackageGroup& Maintainer::packages() const throw ()
+const PackageSet& Maintainer::packages() const throw ()
 {
 	return impl->_packages;
 }

Modified: libdebtags/trunk/src/DebtagsMaintainer.h
==============================================================================
--- libdebtags/trunk/src/DebtagsMaintainer.h	(original)
+++ libdebtags/trunk/src/DebtagsMaintainer.h	Wed Jul 21 16:30:33 2004
@@ -4,15 +4,14 @@
 #pragma interface
 
 #include <string>
-#include <vector>
 
 namespace Debtags
 {
 
 class AvailableReader;
 class Package;
-class PackageGroup;
-class MaintainerGroup;
+class PackageSet;
+class MaintainerSet;
 class MaintainerImpl;
 
 class Maintainer
@@ -35,10 +34,10 @@
 	const std::string& email() const throw ();
 	const std::string& fullname() const throw ();
 
-	const PackageGroup& packages() const throw ();
+	const PackageSet& packages() const throw ();
 
 	friend class AvailableReader;
-	friend class MaintainerGroup;
+	friend class MaintainerSet;
 };
 
 };

Copied: libdebtags/trunk/src/DebtagsMaintainerSet.cc (from r168, libdebtags/trunk/src/DebtagsMaintainerGroup.cc)
==============================================================================
--- libdebtags/trunk/src/DebtagsMaintainerGroup.cc	(original)
+++ libdebtags/trunk/src/DebtagsMaintainerSet.cc	Wed Jul 21 16:30:33 2004
@@ -20,28 +20,28 @@
 
 #pragma implementation
 
-#include "DebtagsMaintainerGroup.h"
-#include "DebtagsPackageGroup.h"
-#include "DebtagsTagGroup.h"
+#include "DebtagsMaintainerSet.h"
+#include "DebtagsPackageSet.h"
+#include "DebtagsTagSet.h"
 
 using namespace std;
 using namespace Debtags;
 
 
-MaintainerGroup::MaintainerGroup() throw ()
+MaintainerSet::MaintainerSet() throw ()
 {
 }
 
-MaintainerGroup::MaintainerGroup(const OpSet<Debtags::Maintainer>& p) throw ()
+MaintainerSet::MaintainerSet(const OpSet<Debtags::Maintainer>& p) throw ()
 	: OpSet<Debtags::Maintainer>(p)
 {
 }
 
-MaintainerGroup::~MaintainerGroup() throw ()
+MaintainerSet::~MaintainerSet() throw ()
 {
 }
 
-Maintainer MaintainerGroup::find(const std::string& name) const throw ()
+Maintainer MaintainerSet::find(const std::string& name) const throw ()
 {
 	Maintainer sample(name);
 	const_iterator found = find(sample);
@@ -51,20 +51,20 @@
 		return Maintainer();
 }
 
-PackageGroup MaintainerGroup::getPackages() const throw ()
+PackageSet MaintainerSet::getPackages() const throw ()
 {
-	PackageGroup res;
+	PackageSet res;
 	for (const_iterator i = begin(); i != end(); i++)
 		res += i->packages();
 	return res;
 }
 
-FacetGroup MaintainerGroup::getFacets() const throw ()
+FacetSet MaintainerSet::getFacets() const throw ()
 {
 	return getPackages().getFacets();
 }
 
-TagGroup MaintainerGroup::getTags() const throw ()
+TagSet MaintainerSet::getTags() const throw ()
 {
 	return getPackages().getTags();
 }

Copied: libdebtags/trunk/src/DebtagsMaintainerSet.h (from r168, libdebtags/trunk/src/DebtagsMaintainerGroup.h)
==============================================================================
--- libdebtags/trunk/src/DebtagsMaintainerGroup.h	(original)
+++ libdebtags/trunk/src/DebtagsMaintainerSet.h	Wed Jul 21 16:30:33 2004
@@ -1,5 +1,5 @@
-#ifndef DEBTAGS_MAINTAINER_GROUP_H
-#define DEBTAGS_MAINTAINER_GROUP_H
+#ifndef DEBTAGS_MAINTAINER_SET_H
+#define DEBTAGS_MAINTAINER_SET_H
 
 /*
  * Central class to perform package searches
@@ -29,30 +29,30 @@
 namespace Debtags
 {
 
-class PackageGroup;
-class FacetGroup;
-class TagGroup;
+class PackageSet;
+class FacetSet;
+class TagSet;
 
-class MaintainerGroup : public OpSet<Debtags::Maintainer>
+class MaintainerSet : public OpSet<Debtags::Maintainer>
 {
 public:
 	using OpSet<Debtags::Maintainer>::find;
 
-	MaintainerGroup() throw ();
-	MaintainerGroup(const OpSet<Debtags::Maintainer>&) throw ();
-	~MaintainerGroup() throw ();
+	MaintainerSet() throw ();
+	MaintainerSet(const OpSet<Debtags::Maintainer>&) throw ();
+	~MaintainerSet() throw ();
 
 	// Get the Maintainer object given the package name
 	Maintainer find(const std::string& name) const throw ();
 
 	// Get all the packages maintained by these maintainers
-	PackageGroup getPackages() const throw ();
+	PackageSet getPackages() const throw ();
 
 	// Get all the facets of the tags of the packages maintained by these maintainers
-	FacetGroup getFacets() const throw ();
+	FacetSet getFacets() const throw ();
 
 	// Get all the tags of the packages maintained by these maintainers
-	TagGroup getTags() const throw ();
+	TagSet getTags() const throw ();
 };
 
 };

Modified: libdebtags/trunk/src/DebtagsPackage.cc
==============================================================================
--- libdebtags/trunk/src/DebtagsPackage.cc	(original)
+++ libdebtags/trunk/src/DebtagsPackage.cc	Wed Jul 21 16:30:33 2004
@@ -3,7 +3,7 @@
 #include "DebtagsPackage.h"
 #include "DebtagsMaintainer.h"
 #include "DebtagsEnvironment.h"
-#include "DebtagsTagGroup.h"
+#include "DebtagsTagSet.h"
 #include "DebDBParser.h"
 #include "PackageDB.h"
 #include "DebtagsTagDB.h"
@@ -159,7 +159,7 @@
 	return Environment::get().packageDB().getState(name());
 }
 
-const TagGroup Package::tags() const throw ()
+const TagSet Package::tags() const throw ()
 {
 	return Environment::get().tagDB().getTagsetForItem(*this);
 }

Modified: libdebtags/trunk/src/DebtagsPackage.h
==============================================================================
--- libdebtags/trunk/src/DebtagsPackage.h	(original)
+++ libdebtags/trunk/src/DebtagsPackage.h	Wed Jul 21 16:30:33 2004
@@ -3,21 +3,18 @@
 
 #pragma interface
 
-//#include "DebtagsMaintainer.h"
-
 #include "PackageDB.h"
 
-#include <OpSet.h>
-
 #include <string>
 
 namespace Debtags
 {
 
 class AvailableReader;
+class StandardEnvironment;
 class PackageImpl;
-class PackageGroup;
-class TagGroup;
+class PackageSet;
+class TagSet;
 class Maintainer;
 class Tag;
 
@@ -50,12 +47,12 @@
 	const std::string& ldesc(const std::string& ldesc) throw ();
 	const Maintainer& maint(const Maintainer& maint) throw ();
 
-	const TagGroup tags() const throw ();
+	const TagSet tags() const throw ();
 	const std::string& fulldata() const throw ();
 
-	friend class Packages;
-	friend class PackageGroup;
+	friend class PackageSet;
 	friend class AvailableReader;
+	friend class StandardEnvironment;
 };
 
 };

Added: libdebtags/trunk/src/DebtagsPackageFilter.cc
==============================================================================
--- (empty file)
+++ libdebtags/trunk/src/DebtagsPackageFilter.cc	Wed Jul 21 16:30:33 2004
@@ -0,0 +1,105 @@
+#pragma implementation
+
+#include "DebtagsPackageFilter.h"
+#include "DebtagsPackage.h"
+#include "DebtagsTag.h"
+#include "DebtagsTagSet.h"
+#include "DebtagsMaintainer.h"
+
+#include "Regexp.h"
+
+using namespace std;
+using namespace Debtags;
+
+PackageFilter::~PackageFilter() throw ()
+{
+	if (name) delete name;
+	if (str) delete str;
+}
+
+void PackageFilter::setName(const std::string _name) throw ()
+{
+	try {
+		if (_name.empty())
+		{
+			if (name) delete name;
+			name = 0;
+		} else
+			name = new Regexp(_name);
+	} catch (RegexpException& e) {
+		fprintf(stderr, "%s: %.*s\n", e.type(), PFSTR(e.desc()));
+		name = 0;
+	}
+}
+
+void PackageFilter::setString(const std::string _str) throw ()
+{
+	try {
+		if (_str.empty())
+		{
+			if (str) delete str;
+			str = 0;
+		} else
+			str = new Regexp(_str);
+	} catch (RegexpException& e) {
+		fprintf(stderr, "%s: %.*s\n", e.type(), PFSTR(e.desc()));
+		str = 0;
+	}
+}
+
+bool PackageFilter::matchName(const std::string& text) const throw ()
+{
+	if (name == 0)
+		return true;
+	return name->match(text);
+}
+bool PackageFilter::matchMaintainer(const std::string& text) const throw ()
+{
+	if (maint.empty())
+		return true;
+	return text.find(maint) != string::npos;
+}
+bool PackageFilter::matchString(const std::string& text) const throw ()
+{
+	if (str == 0)
+		return true;
+	return str->match(text);
+}
+bool PackageFilter::matchInstalled(int status) const throw ()
+{
+	if (installed == ANY)
+		return true;
+	if (installed == YES && status != 0 && status != 5)
+		return true;
+	if (installed == NO && (status == 0 || status == 5))
+		return true;
+	return false;
+}
+bool PackageFilter::matchDebtags(const TagSet& ptags) const throw ()
+{
+	if (tags.empty())
+		return true;
+	return ptags.contains(tags);
+}
+
+bool PackageFilter::match(const Package& pkg) const throw ()
+{
+	bool got = true;
+	if (hasMaintainer() && pkg.maint() && !matchMaintainer(pkg.maint().fullname()))
+		got = false;
+	if (hasName() && !matchName(pkg.name()))
+		got = false;
+	if (hasString() && !matchString(pkg.name()) && !matchString(pkg.desc()) && !matchString(pkg.ldesc()))
+		got = false;
+	try {
+		if (hasInstalled() && !matchInstalled(pkg.state()))
+			got = false;
+	} catch (PackageDBException& e) {
+		fprintf(stderr, "%s: %.*s. Skipping check for package status\n", e.type(), PFSTR(e.desc()));
+	}
+	if (hasDebtags() && !matchDebtags(pkg.tags()))
+		got = false;
+	return got;
+}
+
+// vim:set ts=4 sw=4:

Added: libdebtags/trunk/src/DebtagsPackageFilter.h
==============================================================================
--- (empty file)
+++ libdebtags/trunk/src/DebtagsPackageFilter.h	Wed Jul 21 16:30:33 2004
@@ -0,0 +1,70 @@
+#ifndef DEBTAGS_PACKAGE_FILTER_H
+#define DEBTAGS_PACKAGE_FILTER_H
+
+#pragma interface
+
+#include <string>
+#include <DebtagsTag.h>
+#include <DebtagsTagSet.h>
+
+namespace Debtags
+{
+
+class Package;
+class Regexp;
+
+class PackageFilter
+{
+public:
+	typedef enum { YES, NO, ANY } InstalledStatus;
+protected:
+	std::string maint;
+	Regexp* name;
+	Regexp* str;
+	InstalledStatus installed;
+	Debtags::TagSet tags;
+
+public:
+	PackageFilter() throw ()
+		: name(0), str(0), installed(ANY) {}
+	~PackageFilter() throw ();
+
+	void setName(const std::string _name) throw ();
+	void setMaintainer(const std::string _maint) throw () { maint = _maint; }
+	void setString(const std::string _str) throw ();
+	void setInstalled(InstalledStatus val) throw ()
+	{
+		installed = val;
+	}
+	void setDebtags(const Debtags::TagSet& ptags) throw ()
+	{
+		tags = ptags;
+	}
+
+	bool hasName() const throw () { return name != 0; }
+	bool hasMaintainer() const throw () { return !maint.empty(); }
+	bool hasString() const throw () { return str != 0; }
+	bool hasInstalled() const throw () { return installed != ANY; }
+	bool hasDebtags() const throw () { return !tags.empty(); }
+
+	// Compute values useful in deciding search strategies
+	bool hasOnlyName() const throw () { return name != 0 && str == 0 && maint.empty() && installed == ANY && tags.empty(); }
+	bool hasOnlyMaintainer() const throw () { return name == 0 && str == 0 && !maint.empty() && installed == ANY && tags.empty(); }
+	bool isMaintainerSignificant() const throw () { return maint.size() > 1; }
+	bool hasOnlyDebtags() const throw () { return name == 0 && str == 0 && maint.empty() && installed == ANY && !tags.empty(); }
+	bool hasNonDebtags() const throw () { return name != 0 || str != 0 || !maint.empty() || installed != ANY; }
+
+	bool matchName(const std::string& text) const throw ();
+	bool matchMaintainer(const std::string& text) const throw ();
+	bool matchString(const std::string& text) const throw ();
+	bool matchInstalled(int status) const throw ();
+	bool matchDebtags(const Debtags::TagSet& ptags) const throw ();
+	const Debtags::TagSet& debtagsTagset() const throw () { return tags; }
+
+	bool match(const Package& pkg) const throw ();
+};
+
+};
+
+// vim:set ts=3 sw=3:
+#endif

Copied: libdebtags/trunk/src/DebtagsPackageSet.cc (from r168, libdebtags/trunk/src/DebtagsPackageGroup.cc)
==============================================================================
--- libdebtags/trunk/src/DebtagsPackageGroup.cc	(original)
+++ libdebtags/trunk/src/DebtagsPackageSet.cc	Wed Jul 21 16:30:33 2004
@@ -20,55 +20,55 @@
 
 #pragma implementation
 
-#include "DebtagsPackageGroup.h"
-#include "DebtagsTagGroup.h"
-#include "DebtagsMaintainerGroup.h"
+#include "DebtagsPackageSet.h"
+#include "DebtagsTagSet.h"
+#include "DebtagsMaintainerSet.h"
 #include "DebtagsEnvironment.h"
-#include "DebtagsFilter.h"
+#include "DebtagsPackageFilter.h"
 #include "DebtagsConsumer.h"
 
 using namespace std;
 using namespace Debtags;
 
 
-PackageGroup::PackageGroup() throw ()
+PackageSet::PackageSet() throw ()
 {
 }
 
-PackageGroup::PackageGroup(const OpSet<Debtags::Package>& p) throw ()
+PackageSet::PackageSet(const OpSet<Debtags::Package>& p) throw ()
 	: OpSet<Debtags::Package>(p)
 {
 }
 
-PackageGroup::~PackageGroup() throw ()
+PackageSet::~PackageSet() throw ()
 {
 }
 
-void PackageGroup::consume(const Package& pkg) throw ()
+void PackageSet::consume(const Package& pkg) throw ()
 {
 	*this += pkg;
 }
 
 
-FacetGroup PackageGroup::getFacets() const throw ()
+FacetSet PackageSet::getFacets() const throw ()
 {
-	FacetGroup res;
+	FacetSet res;
 	for (const_iterator i = begin(); i != end(); i++)
 		res += i->tags().getFacets();
 	return res;
 }
 
-TagGroup PackageGroup::getTags() const throw ()
+TagSet PackageSet::getTags() const throw ()
 {
-	TagGroup res;
+	TagSet res;
 	for (const_iterator i = begin(); i != end(); i++)
 		res += i->tags();
 	return res;
 }
 
-MaintainerGroup PackageGroup::getMaintainers() const throw ()
+MaintainerSet PackageSet::getMaintainers() const throw ()
 {
-	MaintainerGroup res;
+	MaintainerSet res;
 	for (const_iterator i = begin(); i != end(); i++)
 		res += i->maint();
 	return res;
@@ -76,9 +76,9 @@
 
 // Get the set of all tags in this collection that appear in tagsets
 // containing `ts'
-OpSet<Debtags::Tag> PackageGroup::getCompanionTags(const OpSet<Debtags::Tag>& ts) const throw ()
+TagSet PackageSet::getCompanionTags(const TagSet& ts) const throw ()
 {
-	OpSet<Tag> tags;
+	TagSet tags;
 
 	for (const_iterator i = begin(); i != end(); i++)
 		if (i->tags().contains(ts))
@@ -87,7 +87,7 @@
 	return tags;
 }
 
-Package PackageGroup::find(const std::string& name) const throw ()
+Package PackageSet::find(const std::string& name) const throw ()
 {
 	Package sample(name);
 	const_iterator found = find(sample);
@@ -97,7 +97,7 @@
 		return Package();
 }
 
-Maintainer PackageGroup::findMaintainer(const std::string& email) const throw ()
+Maintainer PackageSet::findMaintainer(const std::string& email) const throw ()
 {
 	for (const_iterator i = begin(); i != end(); i++)
 		if (i->maint().email() == email)
@@ -105,38 +105,38 @@
 	return Maintainer();
 }
 
-void PackageGroup::output(PackageConsumer& cons) const throw ()
+void PackageSet::output(PackageConsumer& cons) const throw ()
 {
 	for (iterator i = begin(); i != end(); i++)
 		cons.consume(*i);
 }
 
-void PackageGroup::output(PackageConsumer& cons, Filter& filter) const throw ()
+void PackageSet::output(PackageConsumer& cons, PackageFilter& filter) const throw ()
 {
 	for (iterator i = begin(); i != end(); i++)
 		if (filter.match(*i))
 			cons.consume(*i);
 }
 
-PackageGroup PackageGroup::getFiltered(Filter& filter) const throw ()
+PackageSet PackageSet::getFiltered(PackageFilter& filter) const throw ()
 {
-	PackageGroup res;
+	PackageSet res;
 	for (iterator i = begin(); i != end(); i++)
 		if (filter.match(*i))
 			res += *i;
 	return res;
 }
 
-// Get the PackageGroup of packages related to `pivot'
-PackageGroup PackageGroup::getRelated(const Package& pivot, int distance) const throw ()
+// Get the PackageSet of packages related to `pivot'
+PackageSet PackageSet::getRelated(const Package& pivot, int distance) const throw ()
 {
 	return getRelated(pivot.tags(), distance) - pivot;
 }
 
-// Get the PackageGroup of packages related to the specific tagset
-PackageGroup PackageGroup::getRelated(const OpSet<Debtags::Tag>& ts, int distance) const throw ()
+// Get the PackageSet of packages related to the specific tagset
+PackageSet PackageSet::getRelated(const TagSet& ts, int distance) const throw ()
 {
-	PackageGroup res;
+	PackageSet res;
 
 	for (const_iterator i = begin(); i != end(); i++)
 	{
@@ -149,18 +149,18 @@
 
 }
 
-void PackageGroup::outputRelated(PackageConsumer& cons, const Package& pivot, int distance) const throw ()
+void PackageSet::outputRelated(PackageConsumer& cons, const Package& pivot, int distance) const throw ()
 {
-	PackageGroup res = getRelated(pivot, distance);
+	PackageSet res = getRelated(pivot, distance);
 	//fprintf(stderr, "%d related to %.*s, distance %d\n", res.size(), PFSTR(pivot.name()), distance);
-	for (PackageGroup::const_iterator i = res.begin(); i != res.end(); i++)
+	for (PackageSet::const_iterator i = res.begin(); i != res.end(); i++)
 		cons.consume(*i);
 }
 
-void PackageGroup::outputRelated(PackageConsumer& cons, const OpSet<Debtags::Tag>& ts, int distance) const throw ()
+void PackageSet::outputRelated(PackageConsumer& cons, const TagSet& ts, int distance) const throw ()
 {
-	PackageGroup res = getRelated(ts, distance);
-	for (PackageGroup::const_iterator i = res.begin(); i != res.end(); i++)
+	PackageSet res = getRelated(ts, distance);
+	for (PackageSet::const_iterator i = res.begin(); i != res.end(); i++)
 		cons.consume(*i);
 }
 

Copied: libdebtags/trunk/src/DebtagsPackageSet.h (from r168, libdebtags/trunk/src/DebtagsPackageGroup.h)
==============================================================================
--- libdebtags/trunk/src/DebtagsPackageGroup.h	(original)
+++ libdebtags/trunk/src/DebtagsPackageSet.h	Wed Jul 21 16:30:33 2004
@@ -1,5 +1,5 @@
-#ifndef DEBTAGS_PACKAGE_GROUP_H
-#define DEBTAGS_PACKAGE_GROUP_H
+#ifndef DEBTAGS_PACKAGE_SET_H
+#define DEBTAGS_PACKAGE_SET_H
 
 /*
  * Central class to perform package searches
@@ -26,38 +26,40 @@
 #include "DebtagsPackage.h"
 #include "DebtagsConsumer.h"
 
+#include <OpSet.h>
+
 namespace Debtags
 {
 
 class Maintainer;
-class MaintainerGroup;
-class FacetGroup;
-class TagGroup;
-class Filter;
+class MaintainerSet;
+class FacetSet;
+class TagSet;
+class PackageFilter;
 
-class PackageGroup : public OpSet<Debtags::Package>, PackageConsumer
+class PackageSet : public OpSet<Debtags::Package>, public PackageConsumer
 {
 public:
 	using OpSet<Debtags::Package>::find;
 
-	PackageGroup() throw ();
-	PackageGroup(const OpSet<Debtags::Package>&) throw ();
-	virtual ~PackageGroup() throw ();
+	PackageSet() throw ();
+	PackageSet(const OpSet<Debtags::Package>&) throw ();
+	virtual ~PackageSet() throw ();
 
 	virtual void consume(const Package& pkg) throw ();
 
 	// Get a list of all facets in these packages
-	FacetGroup getFacets() const throw ();
+	FacetSet getFacets() const throw ();
 
 	// Get a list of all tags in these packages
-	TagGroup getTags() const throw ();
+	TagSet getTags() const throw ();
 
 	// Get a list of all the maintainers of these packages
-	MaintainerGroup getMaintainers() const throw ();
+	MaintainerSet getMaintainers() const throw ();
 
 	// Get the set of all tags in this collection that appear in tagsets
 	// containing `ts'
-	OpSet<Debtags::Tag> getCompanionTags(const OpSet<Debtags::Tag>& ts) const throw ();
+	Debtags::TagSet getCompanionTags(const Debtags::TagSet& ts) const throw ();
 
 	// Get the Package object given the package name
 	Package find(const std::string& name) const throw ();
@@ -69,21 +71,22 @@
 	void output(PackageConsumer& cons) const throw ();
 
 	// Output the filtered package list to `cons'
-	void output(PackageConsumer& cons, Filter& filter) const throw ();
+	void output(PackageConsumer& cons, PackageFilter& filter) const throw ();
 
-	PackageGroup getFiltered(Filter& filter) const throw ();
+	// Get the packages that are matched by `filter'
+	PackageSet getFiltered(PackageFilter& filter) const throw ();
 
-	// Get the PackageGroup of packages related to `pivot'
-	PackageGroup getRelated(const Package& pivot, int distance = 1) const throw ();
+	// Get the PackageSet of packages related to `pivot'
+	PackageSet getRelated(const Package& pivot, int distance = 1) const throw ();
 
-	// Get the PackageGroup of packages related to the specific tagset
-	PackageGroup getRelated(const OpSet<Debtags::Tag>& ts, int distance = 1) const throw ();
+	// Get the PackageSet of packages related to the specific tagset
+	PackageSet getRelated(const Debtags::TagSet& ts, int distance = 1) const throw ();
 
 	// Output list of packages related to `pivot' to `cons'
 	void outputRelated(PackageConsumer& cons, const Package& pivot, int distance = 1) const throw ();
 
 	// Output list of packages related to the specific tagset to `cons'
-	void outputRelated(PackageConsumer& cons, const OpSet<Debtags::Tag>& ts, int distance = 1) const throw ();
+	void outputRelated(PackageConsumer& cons, const Debtags::TagSet& ts, int distance = 1) const throw ();
 };
 
 };

Modified: libdebtags/trunk/src/DebtagsTag.cc
==============================================================================
--- libdebtags/trunk/src/DebtagsTag.cc	(original)
+++ libdebtags/trunk/src/DebtagsTag.cc	Wed Jul 21 16:30:33 2004
@@ -1,6 +1,7 @@
 #pragma implementation
 
 #include "DebtagsTag.h"
+#include "DebtagsTagSet.h"
 #include "DebtagsEnvironment.h"
 
 using namespace std;
@@ -14,7 +15,7 @@
 	
 	std::string _name;
 	//std::map<string, Tag> _tags;
-	OpSet<Tag> _tags;
+	TagSet _tags;
 	
 public:
 	FacetImpl(const std::string& name) throw ();
@@ -27,7 +28,8 @@
 	bool unref() throw () { return --_ref == 0; }
 
 	bool hasTag(const std::string& name) const throw ();
-	Tag getTag(const std::string& name) throw ();
+	Tag obtainTag(const std::string& name) throw ();
+	Tag getTag(const std::string& name) const throw ();
 
 	friend class Facet;
 	friend class Tag;
@@ -69,20 +71,10 @@
 	return _tags.find(sample) != _tags.end();
 }
 
-Tag FacetImpl::getTag(const std::string& name) throw ()
+Tag FacetImpl::obtainTag(const std::string& name) throw ()
 {
-	/*
-	map<string, Tag>::iterator i = _tags.find(name);
-	if (i == _tags.end())
-	{
-		pair<map<string, Tag>::iterator, bool> res =
-			_tags.insert(pair<std::string, Tag>(name, Tag(this, name)));
-		i = res.first;
-	}
-	return i->second;
-	*/
 	Tag sample(this, name);
-	OpSet<Tag>::iterator i = _tags.find(sample);
+	TagSet::iterator i = _tags.find(sample);
 	if (i == _tags.end())
 	{
 		_tags.insert(sample);
@@ -91,6 +83,16 @@
 		return *i;
 }
 
+Tag FacetImpl::getTag(const std::string& name) const throw ()
+{
+	Tag sample(const_cast<FacetImpl*>(this), name);
+	TagSet::iterator i = _tags.find(sample);
+	if (i == _tags.end())
+		return Tag();
+	else
+		return *i;
+}
+
 
 TagImpl::TagImpl(FacetImpl* facet, const std::string& name) throw ()
 	: _facet(facet), _name(name) {}
@@ -152,19 +154,27 @@
 }
 
 const std::string& Facet::name() const throw () { return impl->_name; }
+// TODO: implement more data in facets
+const std::string& Facet::sdesc() const throw () { return impl->_name; }
+const std::string& Facet::ldesc() const throw () { return impl->_name; }
 
 bool Facet::hasTag(const std::string& name) const throw ()
 {
 	return impl->hasTag(name);
 }
 
-Tag Facet::getTag(const std::string& name) throw ()
+Tag Facet::obtainTag(const std::string& name) throw ()
+{
+	return impl->getTag(name);
+}
+
+Tag Facet::getTag(const std::string& name) const throw ()
 {
 	return impl->getTag(name);
 }
 
 
-const OpSet<Tag>& Facet::tags() const throw ()
+const TagSet& Facet::tags() const throw ()
 {
 	return impl->_tags;
 }

Modified: libdebtags/trunk/src/DebtagsTag.h
==============================================================================
--- libdebtags/trunk/src/DebtagsTag.h	(original)
+++ libdebtags/trunk/src/DebtagsTag.h	Wed Jul 21 16:30:33 2004
@@ -3,11 +3,6 @@
 
 #pragma interface
 
-//#include "DebtagsMaintainer.h"
-
-#include <OpSet.h>
-//#include <DebtagsIterators.h>
-
 #include <string>
 
 namespace Debtags
@@ -17,8 +12,8 @@
 class FacetImpl;
 class TagImpl;
 class Vocabulary;
-class TagGroup;
-class FacetGroup;
+class TagSet;
+class FacetSet;
 
 class Tag
 {
@@ -49,7 +44,7 @@
 	const std::string& ldesc() const throw ();
 
 	friend class FacetImpl;
-	friend class TagGroup;
+	friend class TagSet;
 	friend class Debtags::Vocabulary;
 };
 
@@ -60,6 +55,7 @@
 
 	explicit Facet(const std::string& name) throw ();
 	Facet(FacetImpl* impl) throw ();
+	Tag obtainTag(const std::string& name) throw ();
 
 public:
 	Facet() throw ();
@@ -73,44 +69,18 @@
 	operator bool() const throw ();
 
 	const std::string& name() const throw ();
+	const std::string& sdesc() const throw ();
+	const std::string& ldesc() const throw ();
 
 	bool hasTag(const std::string& name) const throw ();
-	Tag getTag(const std::string& name) throw ();
-	const OpSet<Tag>& tags() const throw ();
+	Tag getTag(const std::string& name) const throw ();
+	const TagSet& tags() const throw ();
 
 	friend class Tag;
-	friend class FacetGroup;
+	friend class FacetSet;
 	friend class Debtags::Vocabulary;
 };
 
-/*
-class FacetGroup
-{
-public:
-	typedef Debtags::const_iterator<Debtags::Facet> const_iterator;
-	typedef Debtags::iterator<Debtags::Facet> iterator;
-	
-	virtual iterator begin() throw () = 0;
-	virtual iterator end() throw () = 0;
-
-	virtual const_iterator begin() const throw () = 0;
-	virtual const_iterator end() const throw () = 0;
-};
-
-class TagGroup
-{
-public:
-	typedef Debtags::const_iterator<Debtags::Tag> const_iterator;
-	typedef Debtags::iterator<Debtags::Tag> iterator;
-	
-	virtual iterator begin() throw () = 0;
-	virtual iterator end() throw () = 0;
-
-	virtual const_iterator begin() const throw () = 0;
-	virtual const_iterator end() const throw () = 0;
-};
-*/
-
 };
 
 // vim:set ts=3 sw=3:

Modified: libdebtags/trunk/src/DebtagsTagDB.cc
==============================================================================
--- libdebtags/trunk/src/DebtagsTagDB.cc	(original)
+++ libdebtags/trunk/src/DebtagsTagDB.cc	Wed Jul 21 16:30:33 2004
@@ -103,10 +103,11 @@
 {
 protected:
 	TagcollConsumer<Debtags::Package, Debtags::Tag>& target;
+	Debtags::Vocabulary& voc;
 	
 public:
 	ItemsToPackages(TagcollConsumer<Debtags::Package, Debtags::Tag>& target) throw ()
-		: target(target) {}
+		: target(target), voc(Debtags::Environment::get().vocabulary()) {}
 
 	virtual void consume(const string& item) throw ()
 	{
@@ -114,14 +115,10 @@
 	}
 	virtual void consume(const string& item, const OpSet<string>& tags) throw ()
 	{
-		Debtags::Vocabulary& voc = Debtags::Environment::get().vocabulary();
-		OpSet<Tag> outTags;
+		TagSet outTags;
 		for (OpSet<string>::const_iterator i = tags.begin(); i != tags.end(); i++)
-		{
-			Tag t = voc.getTag(*i);
-			if (t)
+			if (Tag t = voc.findTag(*i))
 				outTags += t;
-		}
 		target.consume(Environment::get().getPackage(item), outTags);
 	}
 };
@@ -228,6 +225,11 @@
 	return true;
 }
 
+Debtags::TagSet TagDB::getTags() const throw ()
+{
+	return getAllTags();
+}
+
 void TagDB::load(bool facet_only) throw (FileException, ParserException)
 {
 	outputPatched(*this, facet_only);

Modified: libdebtags/trunk/src/DebtagsTagDB.h
==============================================================================
--- libdebtags/trunk/src/DebtagsTagDB.h	(original)
+++ libdebtags/trunk/src/DebtagsTagDB.h	Wed Jul 21 16:30:33 2004
@@ -32,6 +32,8 @@
 namespace Debtags
 {
 
+class TagSet;
+
 class TagDB : public InputMerger<Debtags::Package, Debtags::Tag>
 {
 public:
@@ -47,6 +49,8 @@
 	// Check if the tag database has been created (i.e. if debtags update has been run)
 	static bool hasTagDatabase() throw ();
 
+	Debtags::TagSet getTags() const throw ();
+
 	// Apply a tag change to the package DB
 	//TagcollChange<Debtags::Package, Debtags::Tag> applyTagcollChange(const TagcollChange<Debtags::Package, Debtags::Tag>& change) throw ();
 

Added: libdebtags/trunk/src/DebtagsTagFilter.cc
==============================================================================
--- (empty file)
+++ libdebtags/trunk/src/DebtagsTagFilter.cc	Wed Jul 21 16:30:33 2004
@@ -0,0 +1,131 @@
+#pragma implementation
+
+#include "DebtagsTagFilter.h"
+#include "DebtagsTag.h"
+#include "DebtagsTagSet.h"
+
+#include "Regexp.h"
+
+using namespace std;
+using namespace Debtags;
+
+BasicFacetFilter::~BasicFacetFilter() throw ()
+{
+	if (name) delete name;
+	if (str) delete str;
+}
+
+void BasicFacetFilter::setName(const std::string _name) throw ()
+{
+	try {
+		if (_name.empty())
+		{
+			if (name) delete name;
+			name = 0;
+		} else
+			name = new Regexp(_name);
+	} catch (RegexpException& e) {
+		fprintf(stderr, "%s: %.*s\n", e.type(), PFSTR(e.desc()));
+		name = 0;
+	}
+}
+
+void BasicFacetFilter::setString(const std::string _str) throw ()
+{
+	try {
+		if (_str.empty())
+		{
+			if (str) delete str;
+			str = 0;
+		} else
+			str = new Regexp(_str);
+	} catch (RegexpException& e) {
+		fprintf(stderr, "%s: %.*s\n", e.type(), PFSTR(e.desc()));
+		str = 0;
+	}
+}
+
+bool BasicFacetFilter::matchName(const std::string& text) const throw ()
+{
+	if (name == 0)
+		return true;
+	return name->match(text);
+}
+bool BasicFacetFilter::matchString(const std::string& text) const throw ()
+{
+	if (str == 0)
+		return true;
+	return str->match(text);
+}
+
+bool BasicFacetFilter::match(const Facet& tag) const throw ()
+{
+	bool got = true;
+	if (hasName() && !matchName(tag.name()))
+		got = false;
+	if (hasString() && !matchString(tag.name()) && !matchString(tag.sdesc()) && !matchString(tag.ldesc()))
+		got = false;
+	return got;
+}
+
+
+BasicTagFilter::~BasicTagFilter() throw ()
+{
+	if (name) delete name;
+	if (str) delete str;
+}
+
+void BasicTagFilter::setName(const std::string _name) throw ()
+{
+	try {
+		if (_name.empty())
+		{
+			if (name) delete name;
+			name = 0;
+		} else
+			name = new Regexp(_name);
+	} catch (RegexpException& e) {
+		fprintf(stderr, "%s: %.*s\n", e.type(), PFSTR(e.desc()));
+		name = 0;
+	}
+}
+
+void BasicTagFilter::setString(const std::string _str) throw ()
+{
+	try {
+		if (_str.empty())
+		{
+			if (str) delete str;
+			str = 0;
+		} else
+			str = new Regexp(_str);
+	} catch (RegexpException& e) {
+		fprintf(stderr, "%s: %.*s\n", e.type(), PFSTR(e.desc()));
+		str = 0;
+	}
+}
+
+bool BasicTagFilter::matchName(const std::string& text) const throw ()
+{
+	if (name == 0)
+		return true;
+	return name->match(text);
+}
+bool BasicTagFilter::matchString(const std::string& text) const throw ()
+{
+	if (str == 0)
+		return true;
+	return str->match(text);
+}
+
+bool BasicTagFilter::match(const Tag& tag) const throw ()
+{
+	bool got = true;
+	if (hasName() && !matchName(tag.name()))
+		got = false;
+	if (hasString() && !matchString(tag.name()) && !matchString(tag.sdesc()) && !matchString(tag.ldesc()))
+		got = false;
+	return got;
+}
+
+// vim:set ts=4 sw=4:

Added: libdebtags/trunk/src/DebtagsTagFilter.h
==============================================================================
--- (empty file)
+++ libdebtags/trunk/src/DebtagsTagFilter.h	Wed Jul 21 16:30:33 2004
@@ -0,0 +1,76 @@
+#ifndef DEBTAGS_TAG_FILTER_H
+#define DEBTAGS_TAG_FILTER_H
+
+#pragma interface
+
+#include <string>
+
+namespace Debtags
+{
+
+class Tag;
+class Facet;
+class Regexp;
+
+class FacetFilter
+{
+public:
+	virtual bool match(const Facet& facet) const throw () = 0;
+};
+
+class BasicFacetFilter : public FacetFilter
+{
+protected:
+	Regexp* name;
+	Regexp* str;
+
+public:
+	BasicFacetFilter() throw ()
+		: name(0), str(0) {}
+	virtual ~BasicFacetFilter() throw ();
+
+	void setName(const std::string _name) throw ();
+	void setString(const std::string _str) throw ();
+
+	bool hasName() const throw () { return name != 0; }
+	bool hasString() const throw () { return str != 0; }
+
+	bool matchName(const std::string& text) const throw ();
+	bool matchString(const std::string& text) const throw ();
+
+	bool match(const Facet& facet) const throw ();
+};
+
+class TagFilter
+{
+public:
+	virtual bool match(const Tag& tag) const throw () = 0;
+};
+
+class BasicTagFilter : public TagFilter
+{
+protected:
+	Regexp* name;
+	Regexp* str;
+
+public:
+	BasicTagFilter() throw ()
+		: name(0), str(0) {}
+	virtual ~BasicTagFilter() throw ();
+
+	void setName(const std::string _name) throw ();
+	void setString(const std::string _str) throw ();
+
+	bool hasName() const throw () { return name != 0; }
+	bool hasString() const throw () { return str != 0; }
+
+	bool matchName(const std::string& text) const throw ();
+	bool matchString(const std::string& text) const throw ();
+
+	virtual bool match(const Tag& tag) const throw ();
+};
+
+};
+
+// vim:set ts=3 sw=3:
+#endif

Copied: libdebtags/trunk/src/DebtagsTagSet.cc (from r168, libdebtags/trunk/src/DebtagsTagGroup.cc)
==============================================================================
--- libdebtags/trunk/src/DebtagsTagGroup.cc	(original)
+++ libdebtags/trunk/src/DebtagsTagSet.cc	Wed Jul 21 16:30:33 2004
@@ -1,5 +1,5 @@
 /*
- * Central class to perform package searches
+ * Set of tags and set of facets
  *
  * Copyright (C) 2003  Enrico Zini <enrico@debian.org>
  *
@@ -20,26 +20,31 @@
 
 #pragma implementation
 
-#include "DebtagsTagGroup.h"
+#include "DebtagsTagSet.h"
+#include "DebtagsTagFilter.h"
+#include "DebtagsConsumer.h"
+
+// Only for debugging
+#include <stringf.h>
 
 using namespace std;
 using namespace Debtags;
 
 
-TagGroup::TagGroup() throw ()
+TagSet::TagSet() throw ()
 {
 }
 
-TagGroup::TagGroup(const OpSet<Debtags::Tag>& p) throw ()
+TagSet::TagSet(const OpSet<Debtags::Tag>& p) throw ()
 	: OpSet<Debtags::Tag>(p)
 {
 }
 
-TagGroup::~TagGroup() throw ()
+TagSet::~TagSet() throw ()
 {
 }
 
-Tag TagGroup::find(const std::string& name) const throw ()
+Tag TagSet::find(const std::string& name) const throw ()
 {
 	Tag sample(0, name);
 	const_iterator found = find(sample);
@@ -49,29 +54,88 @@
 		return Tag();
 }
 
-FacetGroup TagGroup::getFacets() const throw ()
+FacetSet TagSet::getFacets() const throw ()
 {
-	FacetGroup res;
+	FacetSet res;
 	for (const_iterator i = begin(); i != end(); i++)
 		res += i->facet();
 	return res;
 }
 
+bool TagSet::has(const std::string& tag) const throw ()
+{
+	return find(tag);
+}
 
-FacetGroup::FacetGroup() throw ()
+TagSet TagSet::getFiltered(const TagFilter& filter) const throw ()
 {
+	TagSet res;
+	for (const_iterator i = begin(); i != end(); i++)
+		if (filter.match(*i))
+			res += *i;
+	return res;
 }
 
-FacetGroup::FacetGroup(const OpSet<Debtags::Facet>& p) throw ()
+void TagSet::output(TagConsumer& cons) const throw ()
+{
+	for (const_iterator i = begin(); i != end(); i++)
+		cons.consume(*i);
+}
+
+void TagSet::output(TagConsumer& cons, TagFilter& filter) const throw ()
+{
+	for (const_iterator i = begin(); i != end(); i++)
+		if (filter.match(*i))
+			cons.consume(*i);
+}
+
+
+
+
+FacetSet::FacetSet() throw ()
+{
+}
+
+FacetSet::FacetSet(const OpSet<Debtags::Facet>& p) throw ()
 	: OpSet<Debtags::Facet>(p)
 {
 }
 
-FacetGroup::~FacetGroup() throw ()
+FacetSet::~FacetSet() throw ()
+{
+}
+
+TagSet FacetSet::getTags() const throw ()
 {
+	TagSet res;
+	for (const_iterator i = begin(); i != end(); i++)
+		res += i->tags();
+	return res;
 }
 
-Facet FacetGroup::find(const std::string& name) const throw ()
+bool FacetSet::has(const std::string& facet) const throw ()
+{
+	return find(facet);
+}
+
+bool FacetSet::hasTag(const std::string& tag) const throw ()
+{
+	unsigned int p = tag.find("::");
+	if (p == string::npos)
+	{
+		Facet f = find("");
+		if (!f)
+			return false;
+		return f.hasTag(tag);
+	} else {
+		Facet f = find(tag.substr(0, p));
+		if (!f)
+			return false;
+		return f.hasTag(tag.substr(p + 2));
+	}
+}
+
+Facet FacetSet::find(const std::string& name) const throw ()
 {
 	Facet sample(name);
 	const_iterator found = find(sample);
@@ -81,12 +145,72 @@
 		return Facet();
 }
 
-TagGroup FacetGroup::getTags() const throw ()
+Tag FacetSet::findTag(const std::string& tag) const throw ()
 {
-	TagGroup res;
+	fprintf(stderr, "FT [%.*s]\n", PFSTR(tag));
+	unsigned int p = tag.find("::");
+	if (p == string::npos)
+	{
+		fprintf(stderr, "FT unf [%.*s]\n", PFSTR(tag));
+		Facet facet = find("");
+		if (!facet)
+			return Tag();
+		return facet.getTag(tag);
+	} else {
+		fprintf(stderr, "FT fac [%.*s -- %.*s]\n", PFSTR(tag.substr(0, p)), PFSTR(tag.substr(p + 2)));
+		Facet facet = find(tag.substr(0, p));
+		if (!facet)
+			return Tag();
+		Tag res = facet.getTag(tag.substr(p + 2));
+		fprintf(stderr, "FT res [%.*s]\n", PFSTR(res.fullname()));
+		if (res.fullname() != tag)
+			fprintf(stderr, "FT ERROR\n");
+		return res;
+	}
+}
+
+FacetSet FacetSet::getFiltered(const FacetFilter& filter) const throw ()
+{
+	FacetSet res;
 	for (const_iterator i = begin(); i != end(); i++)
-		res += i->tags();
+		if (filter.match(*i))
+			res += *i;
+	return res;
+}
+
+void FacetSet::output(FacetConsumer& cons) const throw ()
+{
+	for (const_iterator i = begin(); i != end(); i++)
+		cons.consume(*i);
+}
+
+void FacetSet::output(FacetConsumer& cons, FacetFilter& filter) const throw ()
+{
+	for (const_iterator i = begin(); i != end(); i++)
+		if (filter.match(*i))
+			cons.consume(*i);
+}
+
+// Output all the tags contained in these facetes to cons
+TagSet FacetSet::getFiltered(const TagFilter& filter) const throw ()
+{
+	TagSet res;
+	for (const_iterator i = begin(); i != end(); i++)
+		res += i->tags().getFiltered(filter);
 	return res;
 }
 
+void FacetSet::output(TagConsumer& cons) const throw ()
+{
+	for (const_iterator i = begin(); i != end(); i++)
+		i->tags().output(cons);
+}
+
+void FacetSet::output(TagConsumer& cons, TagFilter& filter) const throw ()
+{
+	for (const_iterator i = begin(); i != end(); i++)
+		i->tags().output(cons, filter);
+}
+
+
 // vim:set ts=4 sw=4:

Copied: libdebtags/trunk/src/DebtagsTagSet.h (from r168, libdebtags/trunk/src/DebtagsTagGroup.h)
==============================================================================
--- libdebtags/trunk/src/DebtagsTagGroup.h	(original)
+++ libdebtags/trunk/src/DebtagsTagSet.h	Wed Jul 21 16:30:33 2004
@@ -1,8 +1,8 @@
-#ifndef DEBTAGS_TAG_GROUP_H
-#define DEBTAGS_TAG_GROUP_H
+#ifndef DEBTAGS_TAG_SET_H
+#define DEBTAGS_TAG_SET_H
 
 /*
- * Central class to perform package searches
+ * Set of tags and set of facets
  *
  * Copyright (C) 2003  Enrico Zini <enrico@debian.org>
  *
@@ -25,39 +25,72 @@
 
 #include "DebtagsTag.h"
 
+#include <OpSet.h>
+
 namespace Debtags
 {
 
-class FacetGroup;
+class FacetSet;
+class TagFilter;
+class TagConsumer;
+class FacetFilter;
+class FacetConsumer;
 
-class TagGroup : public OpSet<Debtags::Tag>
+class TagSet : public OpSet<Debtags::Tag>
 {
 public:
 	using OpSet<Debtags::Tag>::find;
 
-	TagGroup() throw ();
-	TagGroup(const OpSet<Debtags::Tag>&) throw ();
-	~TagGroup() throw ();
+	TagSet() throw ();
+	TagSet(const OpSet<Debtags::Tag>&) throw ();
+	~TagSet() throw ();
+
+	FacetSet getFacets() const throw ();
 
-	FacetGroup getFacets() const throw ();
+	// Returns true if the set contains the tag named `tag'
+	bool has(const std::string& tag) const throw ();
 
 	// Get the Tag object given the package name
 	Tag find(const std::string& name) const throw ();
+
+	TagSet getFiltered(const TagFilter& filter) const throw ();
+	void output(TagConsumer& cons) const throw ();
+	void output(TagConsumer& cons, TagFilter& filter) const throw ();
 };
 
-class FacetGroup : public OpSet<Debtags::Facet>
+class FacetSet : public OpSet<Debtags::Facet>
 {
 public:
 	using OpSet<Debtags::Facet>::find;
 
-	FacetGroup() throw ();
-	FacetGroup(const OpSet<Debtags::Facet>&) throw ();
-	~FacetGroup() throw ();
-
-	TagGroup getTags() const throw ();
+	FacetSet() throw ();
+	FacetSet(const OpSet<Debtags::Facet>&) throw ();
+	~FacetSet() throw ();
+
+	// Get all the tags contained in these facets
+	TagSet getTags() const throw ();
+
+	// Returns true if the set contains the facet named `facet'
+	bool has(const std::string& facet) const throw ();
+
+	// Returns true if one of the facets in the set contains the tag named
+	// `tag'
+	bool hasTag(const std::string& tag) const throw ();
 
 	// Get the Facet object given the package name
 	Facet find(const std::string& name) const throw ();
+
+	// Get the tag with the given name, if contained in one of these facets
+	Tag findTag(const std::string& tag) const throw ();
+	
+	FacetSet getFiltered(const FacetFilter& filter) const throw ();
+	void output(FacetConsumer& cons) const throw ();
+	void output(FacetConsumer& cons, FacetFilter& filter) const throw ();
+
+	// Output all the tags contained in these facetes to cons
+	TagSet getFiltered(const TagFilter& filter) const throw ();
+	void output(TagConsumer& cons) const throw ();
+	void output(TagConsumer& cons, TagFilter& filter) const throw ();
 };
 
 };

Modified: libdebtags/trunk/src/DebtagsVocabulary.cc
==============================================================================
--- libdebtags/trunk/src/DebtagsVocabulary.cc	(original)
+++ libdebtags/trunk/src/DebtagsVocabulary.cc	Wed Jul 21 16:30:33 2004
@@ -83,87 +83,19 @@
 	fputc('\n', out);
 }
 
-/*
-void Vocabulary::Record::parseImplies(const string& impls) throw (ParserException)
-{
-	StringParserInput in(impls);
-	string item;
-	int sep;
-	do
-	{
-		sep = TagcollParser::parseElement(in, item);
-		if (item.size())
-			implies.push_back(item);
-	}
-	while (sep != ParserInput::Eof);
-}
-
-string Vocabulary::Record::formatImplies() const throw ()
-{
-	string res;
-
-	for (list<string>::const_iterator i = implies.begin();
-			i != implies.end(); i++)
-		if (i == implies.begin())
-			res += *i;
-		else
-			res += ", " + *i;
-
-	return res;
-}
-*/
-
-Facet Vocabulary::getFacet(const std::string& name) throw ()
+Facet Vocabulary::obtainFacet(const std::string& name) throw ()
 {
 	Facet sample(name);
-	OpSet<Facet>::iterator i = _facets.find(sample);
-	if (i == _facets.end())
+	Vocabulary::iterator i = find(sample);
+	if (i == end())
 	{
-		_facets.insert(sample);
+		(*this) += sample;
 		return sample;
 	} else {
 		return *i;
 	}
 }
 
-Tag Vocabulary::getTag(const std::string& name) throw ()
-{
-	unsigned int p = name.find("::");
-	if (p == string::npos)
-	{
-		Facet facet = getFacet("");
-		return facet.getTag(name);
-	} else {
-		Facet facet = getFacet(name.substr(0, p));
-		return facet.getTag(name.substr(p + 2));
-	}
-}
-
-bool Vocabulary::hasFacet(const std::string& facet) const throw ()
-{
-	return _facets.find(facet);
-}
-
-bool Vocabulary::hasTag(const std::string& tag) const throw ()
-{
-	unsigned int p = tag.find("::");
-	if (p == string::npos)
-	{
-		Facet sample("");
-		OpSet<Facet>::const_iterator i = _facets.find(sample);
-		if (i == _facets.end())
-			return false;
-		return i->hasTag(tag);
-	} else {
-		Facet sample(tag.substr(0, p));
-		OpSet<Facet>::const_iterator i = _facets.find(sample);
-		if (i == _facets.end())
-			return false;
-		return i->hasTag(tag.substr(p + 2));
-	}
-}
-
-
 void Vocabulary::read(ParserInput& input) throw (ParserException)
 {
 	DebDBParser parser(input);
@@ -181,11 +113,19 @@
 			unsigned int p = name.find("::");
 			if (p == string::npos)
 			{
-				facet = getFacet("");
-				tag = facet.getTag(name);
+				facet = obtainFacet("");
+				tag = facet.obtainTag(name);
+				if (!tag)
+					fprintf(stderr, "Bug loading vocabulary! obtained tag is false\n");
+				if (tag.fullname() != name)
+					fprintf(stderr, "Bug loading vocabulary! [%.*s] became [%.*s]\n", PFSTR(name), PFSTR(tag.fullname()));
 			} else {
-				facet = getFacet(name.substr(0, p));
-				tag = facet.getTag(name.substr(p + 2));
+				facet = obtainFacet(name.substr(0, p));
+				tag = facet.obtainTag(name.substr(p + 2));
+				if (!tag)
+					fprintf(stderr, "Bug loading vocabulary! obtained tag is false\n");
+				if (tag.fullname() != name)
+					fprintf(stderr, "Bug loading vocabulary! [%.*s] became [%.*s]\n", PFSTR(name), PFSTR(tag.fullname()));
 			}
 
 			for (DebDBParser::Record::const_iterator i = rec.begin();
@@ -265,7 +205,7 @@
 	FILE* out = fopen(fn.c_str(), "wt");
 	if (!out) throw FileException(errno, "creating file " + fn);
 
-	for (OpSet<Facet>::const_iterator i = _facets.begin(); i != _facets.end(); i++)
+	for (FacetSet::const_iterator i = begin(); i != end(); i++)
 	{
 		writeDebStyleField(out, "Facet", i->name());
 		/*
@@ -276,7 +216,7 @@
 		*/
 		fputc('\n', out);
 
-		for (OpSet<Tag>::const_iterator j = i->tags().begin(); j != i->tags().end(); j++)
+		for (TagSet::const_iterator j = i->tags().begin(); j != i->tags().end(); j++)
 		{
 			writeDebStyleField(out, "Tag", j->name());
 			if (!j->sdesc().empty())

Modified: libdebtags/trunk/src/DebtagsVocabulary.h
==============================================================================
--- libdebtags/trunk/src/DebtagsVocabulary.h	(original)
+++ libdebtags/trunk/src/DebtagsVocabulary.h	Wed Jul 21 16:30:33 2004
@@ -25,73 +25,30 @@
 #include <list>
 #include <map>
 
-#include <DebtagsTag.h>
-#include <DebtagsTagGroup.h>
+#include <DebtagsTagSet.h>
 
 #include <ParserBase.h>
-#include <TagcollConsumer.h>
-#include <DerivedTags.h>
-
-class Tagexpr;
 
 namespace Debtags
 {
 
-class Vocabulary
-{
-public:
-	/*
-	struct Record
-	{
-		std::list<std::string> implies;
-		Tagexpr* derived;
-		std::string description;
-		std::list< std::pair<std::string, std::string> > others;
-
-		Record() throw () : derived(0) {}
-		void parseImplies(const std::string& impls) throw (ParserException);
-		std::string formatImplies() const throw ();
-	};
-	*/
+class FacetConsumer;
+class FacetFilter;
+class TagConsumer;
+class TagFilter;
 
+class Vocabulary : public FacetSet
+{
 protected:
-	//std::map<std::string, Record> contents;
-	FacetGroup _facets;
+	Facet obtainFacet(const std::string& name) throw ();
 
 public:
-	/*
-	typedef std::map<std::string, Record>::iterator iterator;
-	typedef std::map<std::string, Record>::const_iterator const_iterator;
-
-	const_iterator begin() const throw () { return contents.begin(); }
-	const_iterator end() const throw () { return contents.end(); }
-	const_iterator find(const std::string& key) const throw () { return contents.find(key); }
-
-	iterator begin() throw () { return contents.begin(); }
-	iterator end() throw () { return contents.end(); }
-	iterator find(const std::string& key) throw () { return contents.find(key); }
-	*/
+	bool hasFacet(const std::string& facet) const throw () { return has(facet); }
 
-	Facet getFacet(const std::string& name) throw ();
-	Tag getTag(const std::string& name) throw ();
+	Facet findFacet(const std::string& facet) const throw () { return find(facet); }
 
-	const FacetGroup& getFacets() const throw () { return _facets; }
-	TagGroup getTags() const throw () { return _facets.getTags(); }
-	
-	bool hasFacet(const std::string& facet) const throw ();
-	bool hasTag(const std::string& tag) const throw ();
-
-	/*
-	const Record& operator[](const std::string tag) throw ()
-	{
-		return contents[tag];
-	}
-
-	bool has(const std::string& tag) const throw ()
-	{
-		return contents.find(tag) != contents.end();
-	}
-	*/
+	const FacetSet& getFacets() const throw () { return *this; }
+	FacetSet getFacets(const FacetFilter& filter) const throw () { return getFiltered(filter); }
 
 	void read(ParserInput& input) throw (ParserException);
 	void read() throw (FileException, ParserException);

Modified: libdebtags/trunk/src/Makefile.am
==============================================================================
--- libdebtags/trunk/src/Makefile.am	(original)
+++ libdebtags/trunk/src/Makefile.am	Wed Jul 21 16:30:33 2004
@@ -8,12 +8,13 @@
 	DebtagsEnvironment.h \
 	DebtagsConsumer.h \
 	DebtagsTag.h \
-	DebtagsTagGroup.h \
+	DebtagsTagSet.h \
 	DebtagsPackage.h \
-	DebtagsPackageGroup.h \
+	DebtagsPackageSet.h \
 	DebtagsMaintainer.h \
-	DebtagsMaintainerGroup.h \
-	DebtagsFilter.h \
+	DebtagsMaintainerSet.h \
+	DebtagsPackageFilter.h \
+	DebtagsTagFilter.h \
 	DebtagsTagDB.h \
 	DebtagsVocabulary.h
 
@@ -26,13 +27,14 @@
 	ZlibParserInput.cc \
 	DebDBParser.cc \
 	PackageDB.cc \
-	DebtagsFilter.cc \
+	DebtagsPackageFilter.cc \
+	DebtagsTagFilter.cc \
 	DebtagsTag.cc \
-	DebtagsTagGroup.cc \
+	DebtagsTagSet.cc \
 	DebtagsMaintainer.cc \
-	DebtagsMaintainerGroup.cc \
+	DebtagsMaintainerSet.cc \
 	DebtagsPackage.cc \
-	DebtagsPackageGroup.cc \
+	DebtagsPackageSet.cc \
 	DebtagsVocabulary.cc \
 	DebtagsTagDB.cc \
 	DebtagsEnvironment.cc \

Modified: libdebtags/trunk/src/instantiations.cc
==============================================================================
--- libdebtags/trunk/src/instantiations.cc	(original)
+++ libdebtags/trunk/src/instantiations.cc	Wed Jul 21 16:30:33 2004
@@ -1,5 +1,6 @@
 #include <DebtagsPackage.h>
 #include <DebtagsTag.h>
+#include <DebtagsMaintainer.h>
 
 #include <FilterChain.cc>
 #include <InputMerger.cc>
@@ -9,6 +10,7 @@
 #include <TagcollConsumer.cc>
 #include <TagCollection.cc>
 #include <TagcollFilter.cc>
+#include <UnfacetedRemover.cc>
 
 // Instantiate tagcoll template for Debtags::Package items
 
@@ -17,10 +19,13 @@
 template class ItemGrouper<Debtags::Package>;
 template class OpSet<Debtags::Package>;
 template class OpSet<Debtags::Tag>;
+template class OpSet<Debtags::Facet>;
+template class OpSet<Debtags::Maintainer>;
 template class SmartHierarchyNode<Debtags::Package>;
 template class CleanSmartHierarchyNode<Debtags::Package>;
 template class TagcollConsumer<Debtags::Package, Debtags::Tag>;
 template class TagCollection<Debtags::Package, string>;
 template class TagcollFilter<Debtags::Package>;
+template class UnfacetedRemover<std::string>;
 
 // vim:set ts=4 sw=4:

Modified: libdebtags/trunk/tests/Makefile.am
==============================================================================
--- libdebtags/trunk/tests/Makefile.am	(original)
+++ libdebtags/trunk/tests/Makefile.am	Wed Jul 21 16:30:33 2004
@@ -3,35 +3,11 @@
 test_update_SOURCES = \
 	test-update.cc
 test_update_LDADD = @LIBTAGCOLL_LIBS@ -lapt-pkg \
-	../src/DebtagsEnvironment.o \
-	../src/DebtagsUpdate.o \
-	../src/DebtagsTag.o \
-	../src/DebtagsPackage.o \
-	../src/DebtagsMaintainer.o \
-	../src/DebtagsVocabulary.o \
-	../src/DebtagsPackages.o \
-	../src/DebtagsFilter.o \
-	../src/ZlibParserInput.o \
-	../src/DebDBParser.o \
-	../src/PackageDB.o \
-	../src/Regexp.o \
-	../src/instantiations.o
+	../src/libdebtags.la
 
 test_packages_SOURCES = \
 	test-packages.cc
 test_packages_LDADD = @LIBTAGCOLL_LIBS@ -lapt-pkg \
-	../src/DebtagsEnvironment.o \
-	../src/DebtagsUpdate.o \
-	../src/DebtagsTag.o \
-	../src/DebtagsPackage.o \
-	../src/DebtagsMaintainer.o \
-	../src/DebtagsVocabulary.o \
-	../src/DebtagsPackages.o \
-	../src/DebtagsFilter.o \
-	../src/ZlibParserInput.o \
-	../src/DebDBParser.o \
-	../src/PackageDB.o \
-	../src/Regexp.o \
-	../src/instantiations.o
+	../src/libdebtags.la
 
 INCLUDES=@LIBTAGCOLL_CFLAGS@ -I ../src

Modified: libdebtags/trunk/tests/test-packages.cc
==============================================================================
--- libdebtags/trunk/tests/test-packages.cc	(original)
+++ libdebtags/trunk/tests/test-packages.cc	Wed Jul 21 16:30:33 2004
@@ -1,10 +1,33 @@
 #include <DebtagsEnvironment.h>
+#include <DebtagsPackageSet.h>
+#include <DebtagsTagDB.h>
+#include <DebtagsTagSet.h>
+
+#include <InputMerger.h>
 
 #include <set>
 
 using namespace std;
 using namespace Debtags;
 
+class PackageGatherer : public TagcollConsumer<Package, Tag>
+{
+protected:
+	PackageSet coll;
+public:
+	virtual ~PackageGatherer() throw () {}
+	virtual void consume(const Package& item) throw ()
+	{
+		coll += item;
+	}
+	virtual void consume(const Package& item, const OpSet<Tag>& tags) throw ()
+	{
+		coll += item;
+	}
+	PackageSet& getColl() throw () { return coll; }
+};
+
+
 int main (int argc, char *argv[])
 {
 	try {
@@ -12,25 +35,65 @@
 		InstallUnexpected installUnexpected;
 
 		Debtags::Environment::init(false);
-		
-		set<Debtags::Package> test;
 
-		Debtags::Packages pkgs = Debtags::Environment::get().packages();
-		test.insert(pkgs.find("apt"));
-		test.insert(pkgs.find("apt"));
-		test.insert(pkgs.find("debtags"));
-		Package p = pkgs.find("debtags");
+		int result = 0;
+		
+		// Test set operations on items of type Package
+		PackageSet test;
+		test.insert(Debtags::Environment::get().getPackage("apt"));
+		test.insert(Debtags::Environment::get().getPackage("apt"));
+		test.insert(Debtags::Environment::get().getPackage("debtags"));
+		Package p = Debtags::Environment::get().getPackage("debtags");
 		test.insert(p);
-
 		if (test.size() != 2)
+		{
 			fprintf(stderr, "%d items (I want 2)\n", test.size());
-
+			result = 1;
+		}
 		test.erase(p);
-
 		if (test.size() != 1)
+		{
 			fprintf(stderr, "%d items (I want 1)\n", test.size());
+			result = 1;
+		}
+
+		// Compare two methods of getting tags
+		TagDB first = Debtags::Environment::get().tagDB();
+		InputMerger<string, string> second;
+		TagDB::outputPatched(second);
+		PackageGatherer pg;
+		TagDB::outputPatched(pg);
+		for (PackageSet::const_iterator i = pg.getColl().begin(); i != pg.getColl().end(); i++)
+		{
+			TagSet tsfirst = i->tags();
+			OpSet<string> tssecond = second.getTagsetForItem(i->name());
+			
+			TagSet::const_iterator fi = tsfirst.begin();
+			OpSet<string>::const_iterator si = tssecond.begin();
+			for ( ; fi != tsfirst.end() && si != tssecond.end(); fi++, si++)
+			{
+				if (fi->fullname() != *si)
+				{
+					fprintf(stderr, "%.*s: tag differ [debtags]%.*s != [tagcoll]%.*s\n",
+							PFSTR(i->name()), PFSTR(fi->fullname()), PFSTR(*si));
+					result = 1;
+				}
+			}
+			for (; fi != tsfirst.end(); fi++)
+			{
+				fprintf(stderr, "%.*s: tag only in debtags: %.*s\n",
+						PFSTR(i->name()), PFSTR(fi->fullname()));
+				result = 1;
+			}
+			for (; si != tssecond.end(); si++)
+			{
+				fprintf(stderr, "%.*s: tag only in tagcoll: %.*s\n",
+						PFSTR(i->name()), PFSTR(*si));
+				result = 1;
+			}
+		}
 
-		return 0;
+		return result;
 	} catch (Exception& e) {
 		fprintf(stderr, "%s: %.*s\n", e.type(), PFSTR(e.desc()));
 	}