[Debtags-commits] [svn] r1711 - in tagcoll/2.0: . tagcoll tools

Enrico Zini enrico at costa.debian.org
Tue May 9 00:07:43 UTC 2006


Author: enrico
Date: Tue May  9 00:07:38 2006
New Revision: 1711

Modified:
   tagcoll/2.0/   (props changed)
   tagcoll/2.0/tagcoll/Implications.h
   tagcoll/2.0/tagcoll/TDBIndexer.h
   tagcoll/2.0/tagcoll/filters.h
   tagcoll/2.0/tools/tagcoll.cc
Log:
 r2598 at viaza:  enrico | 2006-05-07 02:46:29 -0500
 Added NullFilter and UngroupItems filter.
 Updated some of the tagcoll.cc code


Modified: tagcoll/2.0/tagcoll/Implications.h
==============================================================================
--- tagcoll/2.0/tagcoll/Implications.h	(original)
+++ tagcoll/2.0/tagcoll/Implications.h	Tue May  9 00:07:38 2006
@@ -58,6 +58,8 @@
 
 public:
 	virtual ~Implications() {}
+
+	bool empty() const { return implications.empty(); }
 	
 	/// Expand a single tag
 	std::set<TAG> expand(const TAG& tag) const

Modified: tagcoll/2.0/tagcoll/TDBIndexer.h
==============================================================================
--- tagcoll/2.0/tagcoll/TDBIndexer.h	(original)
+++ tagcoll/2.0/tagcoll/TDBIndexer.h	Tue May  9 00:07:38 2006
@@ -55,30 +55,14 @@
 public:
 	virtual ~TDBIndexer() {}
 
+	virtual bool empty() const { return items.empty(); }
+
     virtual bool hasItem(const ITEM& item) const { return items.find(item) != items.end(); }
     virtual bool hasTag(const TAG& tag) const { return tags.find(tag) != tags.end(); }
 	virtual std::set<ITEM> getTaggedItems() const;
 	virtual std::set<TAG> getAllTags() const;
 	virtual void output(Consumer<ITEM, TAG>& consumer) const;
 	virtual void applyChange(const PatchList<ITEM, TAG>& change);
-
-	/**
-	 * Write all collected informations to a disk index
-	 *
-	 * \param itemconv
-	 *   Converter than can convert an ITEM to a string
-	 * \param tagconv
-	 *   Converter than can convert a TAG to a string
-	 * \param pkgidx
-	 *   File name for the package index to write
-	 * \param tagidx
-	 *   File name for the tag index to write
-	 */
-	void writeIndex(
-			Converter<ITEM, std::string>& itemconv,
-			Converter<TAG, std::string>& tagconv,
-			const std::string& pkgidx,
-			const std::string& tagidx) const;
 };
 
 };

Modified: tagcoll/2.0/tagcoll/filters.h
==============================================================================
--- tagcoll/2.0/tagcoll/filters.h	(original)
+++ tagcoll/2.0/tagcoll/filters.h	Tue May  9 00:07:38 2006
@@ -24,6 +24,7 @@
  */
 
 #include <wibble/mixin.h>
+#include <wibble/singleton.h>
 #include <wibble/empty.h>
 #include <set>
 #include <map>
@@ -33,6 +34,26 @@
 {
 
 /**
+ * Filter that does nothing and just passes on the data
+ */
+template<typename OUT>
+class NullFilter : public wibble::mixin::OutputIterator< NullFilter<OUT> >
+{
+	OUT out;
+	
+public:
+	NullFilter(const OUT& out) : out(out) {}
+
+	template<typename ITEMS, typename TAGS>
+	NullFilter<OUT>& operator=(const std::pair<ITEMS, TAGS>& data)
+	{
+		*out = data;
+		++out;
+		return *this;
+	}
+};
+
+/**
  * Store a list of substitutions to operate on std::set
  *
  * It uses a Consumer interface to allow to be populated using a decoder for
@@ -296,6 +317,33 @@
 	return Reverser<OUT, TAG>(out, reversedNull);
 }
 
+template<typename OUT>
+class UngroupItems : public wibble::mixin::OutputIterator< UngroupItems<OUT> >
+{
+	OUT out;
+
+public:
+	UngroupItems(const OUT& out) : out(out) {}
+
+	template<typename ITEMS, typename TAGS>
+	UngroupItems<OUT>& operator=(const std::pair<ITEMS, TAGS>& data)
+	{
+		for (typename ITEMS::const_iterator i = data.first.begin();
+				i != data.first.end(); ++i)
+		{
+			*out = make_pair(wibble::singleton(*i), data.second);
+			++out;
+		}
+		return *this;
+	}
+};
+
+template<typename OUT>
+UngroupItems<OUT> ungroupItems(const OUT& out)
+{
+	return UngroupItems<OUT>(out);
+}
+
 };
 
 // vim:set ts=4 sw=4:

Modified: tagcoll/2.0/tools/tagcoll.cc
==============================================================================
--- tagcoll/2.0/tools/tagcoll.cc	(original)
+++ tagcoll/2.0/tools/tagcoll.cc	Tue May  9 00:07:38 2006
@@ -49,6 +49,7 @@
 #include <tagcoll/Implications.h>
 #include <tagcoll/Patches.h>
 #include <tagcoll/DerivedTags.h>
+#include <tagcoll/TDBIndexer.h>
 
 #include <tagcoll/StdioParserInput.h>
 #include <tagcoll/TextFormat.h>
@@ -111,20 +112,22 @@
 	return items;
 }
 
-void readCollection(const string& file, Consumer<string, string>& builder)
+template<typename OUT>
+void readCollection(const string& file, const OUT& out)
 {
 	if (file == "-")
 	{
 		StdioParserInput input(stdin, "<stdin>");
-		textformat::parse(input, consumer(builder));
+		textformat::parse(input, out);
 	}
 	else
 	{
 		StdioParserInput input(file);
-		textformat::parse(input, consumer(builder));
+		textformat::parse(input, out);
 	}
 }
 
+
 PatchList<string, string> readPatches(const string& file)
 {
 	TrivialConverter<string, string> conv;
@@ -245,166 +248,275 @@
 	}
 }
 
-class Reader
+// Break filtering into generic steps that are abstracted by a virtual function
+
+class FilterStep : public wibble::mixin::OutputIterator<FilterStep>
 {
-	// Prepare the input filter chain
-	FilterChain<string, string> filters;
-	Substitute<string, string> substitutions;
-	PatchList<string, string> patches;
-	Implications<string> implications;
-	DerivedTags derivedTags;
+public:
+	virtual ~FilterStep() {}
+	virtual FilterStep& operator=(const pair< set<string>, set<string> >& data) = 0;
+	virtual FilterStep& operator=(const pair< wibble::Singleton<string>, set<string> >& data) = 0;
+	virtual FilterStep& operator=(const pair< set<string>, wibble::Empty<string> >& data) = 0;
+	virtual FilterStep& operator=(const pair< wibble::Singleton<string>, wibble::Empty<string> >& data) = 0;
+};
 
-	AddImplied<string, string> addImplied;
-	RemoveImplied<string, string> removeImplied;
-	AddDerived<string> addDerived;
-	RemoveDerived<string> removeDerived;
-	UnfacetedRemover<string> unfacetedRemover;
-	FilterTagsByExpression<string, string> filterByExpression;
+template<typename OUT>
+class StringFilterStep : public FilterStep
+{
+	OUT out;
 
 public:
-	Reader(wibble::commandline::TagcollParser& opts)
-		: addImplied(implications), removeImplied(implications),
-		  addDerived(derivedTags), removeDerived(derivedTags),
-		  unfacetedRemover("::"), filterByExpression("")
+	StringFilterStep(const OUT& out) : out(out) {}
+	virtual ~StringFilterStep() {}
+
+	virtual FilterStep& operator=(const pair< set<string>, set<string> >& data)
 	{
-		if (opts.in_rename->boolValue())
-		{
-			readCollection(opts.in_rename->stringValue(), substitutions.substitutions());
-			filters.appendFilter(substitutions);
-		}
-		if (opts.in_patch->boolValue())
-		{
-			patches = readPatches(opts.in_patch->stringValue());
-			filters.appendFilter(patches);
-		}
+		*out = data;
+		++out;
+		return *this;
+	}
+	virtual FilterStep& operator=(const pair< wibble::Singleton<string>, set<string> >& data)
+	{
+		*out = data;
+		++out;
+		return *this;
+	}
+	virtual FilterStep& operator=(const pair< set<string>, wibble::Empty<string> >& data)
+	{
+		*out = data;
+		++out;
+		return *this;
+	}
+	virtual FilterStep& operator=(const pair< wibble::Singleton<string>, wibble::Empty<string> >& data)
+	{
+		*out = data;
+		++out;
+		return *this;
+	}
+};
 
-		if (opts.in_extimpl->boolValue())
-		{
-			readCollection(opts.in_extimpl->stringValue(), implications);
-			// Pack the structure for faster expansions
-			implications.pack();
-		}
-		if (opts.in_derived->boolValue())
-			readDerivedTags(opts.in_derived->stringValue(), derivedTags);
+template<typename OUT>
+FilterStep* filterStep(const OUT& out)
+{
+	return new StringFilterStep<OUT>(out);
+}
 
-		// Intermix implications and derived tags as seems best
-		bool compressOutput = (opts.foundCommand() == opts.copy && !opts.out_redundant->boolValue());
-		bool hasImpl = opts.in_extimpl->boolValue();
-		bool hasDerv = opts.in_derived->boolValue();
+class FilterForwarder : public wibble::mixin::OutputIterator<FilterForwarder>
+{
+	FilterStep* out;
 
-		if (compressOutput)
-		{
-			if (hasDerv)
-			{
-				// Expand implications
-				if (hasImpl) filters.appendFilter(addImplied);
+public:
+	FilterForwarder(FilterStep* out) : out(out) {}
 
-				// Remove derived tags computing them using the expanded tag set
-				filters.appendFilter(removeDerived);
-			}
+	template<typename ITEMS, typename TAGS>
+	FilterForwarder& operator=(const pair<ITEMS, TAGS>& data)
+	{
+		**out = data;
+		++out;
+		return *this;
+	}
+};
 
-			// Compress implications
-			if (hasImpl) filters.appendFilter(removeImplied);
-		} else {
-			// Expand implications
-			if (hasImpl) filters.appendFilter(addImplied);
+class FilterStepManager
+{
+	std::set<FilterStep*> m_managed;
+public:
+	~FilterStepManager()
+	{
+		for (std::set<FilterStep*>::const_iterator i = m_managed.begin();
+				i != m_managed.end(); ++i)
+			if (*i)
+				delete *i;
+	}
 
-			// Add derived tags computing them using the expanded tag set
-			if (hasDerv)
-			{
-				filters.appendFilter(addDerived);
+	FilterStep* manage(FilterStep* fs)
+	{
+		m_managed.insert(fs);
+		return fs;
+	}
+};
 
-				// Add further tags implicated by the derived tags
-				if (hasImpl) filters.appendFilter(addImplied);
-			}
-		}
+// Construct the elaborate readers and writers by chunks, to avoid having a
+// virtual layer among each and every filtering step
+class Tagcoll
+{
+	wibble::commandline::TagcollParser& opts;
+	TDBIndexer<string, string> grouper;
 
-		if (opts.in_rmunfaceted->boolValue())
-			filters.appendFilter(unfacetedRemover);
+	FilterStepManager wman;
+	FilterStep* m_writer;
 
-		if (opts.in_rmtags->boolValue())
-		{
-			filterByExpression.setExpression(not Expression(opts.in_rmtags->stringValue())); 
-			filters.appendFilter(filterByExpression);
-		}
-	}
-	void output(const string& file, Consumer<string, string>& cons)
+	// Support structures for the input filter chain
+	Implications<string> implications;
+	DerivedTags derivedTags;
+	Substitutions<string> substitutions;
+	PatchList<string, string> patches;
+
+	FilterStep* makeReaderHead(FilterStep* out)
 	{
-		filters.setConsumer(cons);
-		readCollection(file, filters);
+		if (opts.in_patch->boolValue())
+			if (opts.in_rename->boolValue())
+				return filterStep(
+						patcher(patches,
+							substitute(substitutions,
+								FilterForwarder(out))));
+			else
+				return filterStep(
+						patcher(patches,
+							FilterForwarder(out)));
+		else
+			if (opts.in_rename->boolValue())
+				return filterStep(
+							substitute(substitutions,
+								FilterForwarder(out)));
+			else
+				return out;
 	}
-	void output(wibble::commandline::TagcollParser& opts, Consumer<string, string>& cons)
+
+	FilterStep* makeReaderMain(FilterStep* out)
 	{
-		if (opts.hasNext())
-			while (opts.hasNext())
-				output(opts.next(), cons);
+		bool hasImpl = opts.in_extimpl->boolValue();
+		bool hasDerv = opts.in_derived->boolValue();
+
+		if (hasImpl)
+			if (hasDerv)
+				// Add derived tags computing them using the expanded tag set,
+				// then adding further tags implicated by the derived tags
+				return filterStep(
+						addImplied(implications,
+							addDerived(derivedTags,
+								addImplied(implications, FilterForwarder(out)))));
+			else
+				return filterStep(addImplied(implications, FilterForwarder(out)));
 		else
-			output("-", cons);
+			if (hasDerv)
+				return filterStep(addDerived(derivedTags, FilterForwarder(out)));
+			else
+				return out;
 	}
-};
 
-class Writer : public Consumer<string, string>
-{
-	TrivialConverter<string, string> conv;
-	TextFormat<string, string> output;
-	ItemGrouper<string, string>* grouper;
-	bool itemsOnly;
-
-protected:
-	/// Process an untagged item
-	virtual void consumeItemUntagged(const string& item)
+	template<typename OUT>
+	FilterStep* makeReaderTail(const OUT& out)
 	{
-		if (grouper)
-			grouper->consume(item);
+		if (opts.in_rmunfaceted->boolValue())
+			if (opts.in_rmtags->boolValue())
+				return filterStep(
+						unfacetedRemover(
+							filterTagsByExpression(
+								not Expression(opts.in_rmtags->stringValue()), out)));
+			else
+				return filterStep(unfacetedRemover(out));
 		else
-			output.consume(item);
+			if (opts.in_rmtags->boolValue())
+				return filterStep(
+						filterTagsByExpression(
+							not Expression(opts.in_rmtags->stringValue()), out));
+			else
+				return filterStep(out);
 	}
 
-	/// Process a tagged item, with its tags
-	virtual void consumeItem(const string& item, const std::set<string>& tags)
+	FilterStep* makeWriterHead(FilterStep* out)
 	{
-		if (itemsOnly)
-			consumeItemUntagged(item);
-		else if (grouper)
-			grouper->consume(item, tags);
+		// Intermix implications and derived tags as seems best
+		if (!opts.out_redundant->boolValue())
+			if (derivedTags.empty())
+				if (implications.empty())
+					return out;
+				else
+					return filterStep(removeImplied(implications, FilterForwarder(out)));
+			else
+				if (implications.empty())
+					return filterStep(removeDerived(derivedTags, FilterForwarder(out)));
+				else
+					// Expand implications, then remove derived tags computing
+					// them using the expanded tag set
+					return filterStep(
+							addImplied(implications,
+								removeDerived(derivedTags,
+									removeImplied(implications,
+										FilterForwarder(out)))));
+	}
+
+	FilterStep* makeWriterTail()
+	{
+		if (opts.out_itemsOnly->boolValue())
+			if (opts.out_group->boolValue())
+				return filterStep(itemsOnly(consumer(grouper)));
+			else
+				return filterStep(itemsOnly(ungroupItems(textformat::StdioWriter(stdout))));
 		else
-			output.consume(item, tags);
+			if (opts.out_group->boolValue())
+				return filterStep(consumer(grouper));
+			else
+				return filterStep(ungroupItems(textformat::StdioWriter(stdout)));
 	}
 
-	/// Process a set of items, all with no tags
-	virtual void consumeItemsUntagged(const std::set<string>& items)
+public:
+	Tagcoll(wibble::commandline::TagcollParser& opts)
+		: opts(opts), m_writer(0)
 	{
-		if (grouper)
-			grouper->consume(items);
-		else
-			// Explicitly split groups
-			for (std::set<string>::const_iterator i = items.begin();
-					i != items.end(); i++)
-				output.consume(*i);
+		if (opts.in_extimpl->boolValue())
+		{
+			readCollection(opts.in_extimpl->stringValue(), consumer(implications));
+			// Pack the structure for faster expansions
+			implications.pack();
+		}
+		if (opts.in_derived->boolValue())
+			readDerivedTags(opts.in_derived->stringValue(), derivedTags);
+		if (opts.in_rename->boolValue())
+			readCollection(opts.in_rename->stringValue(), substitutions.inserter());
+		if (opts.in_patch->boolValue())
+			patches = readPatches(opts.in_patch->stringValue());
 	}
+	~Tagcoll()
+	{
+		if (!grouper.empty())
+			grouper.output(forwarder(textformat::StdioWriter(stdout)));
+	}
+
+	template<typename OUT>
+	void outputFile(const string& file, const OUT& out)
+	{
+		FilterStepManager m;
+		FilterStep* reader =
+			m.manage(makeReaderHead(
+						m.manage(makeReaderMain(
+								m.manage(makeReaderTail(out))))));
 
-	/// Process a set of items identically tagged, with their tags
-	virtual void consumeItems(const std::set<string>& items, const std::set<string>& tags)
-	{
-		if (itemsOnly)
-			consumeItemsUntagged(items);
-		else if (grouper)
-			grouper->consume(items, tags);
+		readCollection(file, FilterForwarder(reader));
+	}
+
+	template<typename OUT>
+	void outputAll(const OUT& out)
+	{
+		FilterStepManager m;
+		FilterStep* reader =
+			m.manage(makeReaderHead(
+						m.manage(makeReaderMain(
+								m.manage(makeReaderTail(out))))));
+		
+		if (opts.hasNext())
+			while (opts.hasNext())
+				readCollection(opts.next(), FilterForwarder(reader));
 		else
-			// Explicitly split groups
-			for (std::set<string>::const_iterator i = items.begin();
-					i != items.end(); i++)
-				output.consume(*i, tags);
+			readCollection("-", FilterForwarder(reader));
 	}
 
-public:
-	Writer(wibble::commandline::TagcollParser& opts)
-		: output(conv, conv, stdout), grouper(0)
+	FilterForwarder writer()
 	{
-		if (opts.out_group->boolValue())
-			grouper = new ItemGrouper<string, string>;
-		itemsOnly = opts.out_itemsOnly->boolValue();
+		if (!m_writer)
+			m_writer =
+				wman.manage(makeWriterHead(
+					wman.manage(makeWriterTail())));
+		return FilterForwarder(m_writer);
 	}
+};
+
+#if 0
+TODO:
+ - output the grouped data
+
+public:
 	~Writer()
 	{
 		// Flush output if needed
@@ -415,6 +527,7 @@
 		}
 	}
 };
+#endif
 
 int main(int argc, const char* argv[])
 {



More information about the Debtags-commits mailing list