[Debtags-commits] [svn] r1683 - in tagcoll/2.0: . tagcoll tests
tools
Enrico Zini
enrico at costa.debian.org
Tue May 2 00:54:41 UTC 2006
Author: enrico
Date: Tue May 2 00:54:37 2006
New Revision: 1683
Added:
tagcoll/2.0/tagcoll/Sink.h
tagcoll/2.0/tagcoll/TextFormat.tcc
Modified:
tagcoll/2.0/ (props changed)
tagcoll/2.0/Makefile.am
tagcoll/2.0/tagcoll/Consumer.h
tagcoll/2.0/tagcoll/Expression.cc
tagcoll/2.0/tagcoll/Expression.h
tagcoll/2.0/tagcoll/Filters.cc
tagcoll/2.0/tagcoll/Filters.h
tagcoll/2.0/tagcoll/Makefile.am
tagcoll/2.0/tagcoll/TextFormat.cc
tagcoll/2.0/tagcoll/TextFormat.h
tagcoll/2.0/tagcoll/test-utils.cc
tagcoll/2.0/tests/normalize.cc
tagcoll/2.0/tests/test-utils.h
tagcoll/2.0/tools/tagcoll.cc
Log:
r2538 at viaza: enrico | 2006-05-02 00:08:40 +0200
Started getting rid of Consumer
Modified: tagcoll/2.0/Makefile.am
==============================================================================
--- tagcoll/2.0/Makefile.am (original)
+++ tagcoll/2.0/Makefile.am Tue May 2 00:54:37 2006
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
-SUBDIRS = tagcoll tools tests bench doc .
+SUBDIRS = tagcoll tests tools bench doc .
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA=libtagcoll.pc
Modified: tagcoll/2.0/tagcoll/Consumer.h
==============================================================================
--- tagcoll/2.0/tagcoll/Consumer.h (original)
+++ tagcoll/2.0/tagcoll/Consumer.h Tue May 2 00:54:37 2006
@@ -24,6 +24,7 @@
*/
#include <tagcoll/OpSet.h>
+#include <wibble/empty.h>
namespace tagcoll
{
@@ -84,21 +85,37 @@
void consume(const OpSet<ITEM>& items, const OpSet<TAG>& tags) { consumeItems(items, tags); }
};
-
-/**
- * Consumer that discards its input
- */
template<class ITEM, class TAG>
-class Sink : public Consumer<ITEM, TAG>
+class ConsumerAdaptor
{
-protected:
- virtual void consumeItemUntagged(const ITEM& item) {}
- virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags) {}
- virtual void consumeItemsUntagged(const OpSet<ITEM>& items) {}
- virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tags) {}
+ Consumer<ITEM, TAG>& target;
+
public:
+ ConsumerAdaptor(Consumer<ITEM, TAG>& target) : target(target) {}
+
+ ConsumerAdaptor<ITEM, TAG>& operator++() { return *this; }
+
+ template<typename Items, typename Tags>
+ ConsumerAdaptor<ITEM, TAG>& operator=(const std::pair<Items, Tags>& data)
+ {
+ target.consume(data.first, data.second);
+ return *this;
+ }
+
+ template<typename Items, typename Tag>
+ ConsumerAdaptor<ITEM, TAG>& operator=(const std::pair<Items, wibble::Empty<Tag> >& data)
+ {
+ target.consume(data.first);
+ return *this;
+ }
};
+template<typename ITEM, typename TAG>
+ConsumerAdaptor<ITEM, TAG> consumer(Consumer<ITEM, TAG>& target)
+{
+ return ConsumerAdaptor<ITEM, TAG>(target);
+}
+
};
// vim:set ts=4 sw=4:
Modified: tagcoll/2.0/tagcoll/Expression.cc
==============================================================================
--- tagcoll/2.0/tagcoll/Expression.cc (original)
+++ tagcoll/2.0/tagcoll/Expression.cc Tue May 2 00:54:37 2006
@@ -36,7 +36,7 @@
virtual std::string format() const { return "*"; }
virtual bool eval(const TagexprContext& context) const { return true; }
- virtual bool eval(const OpSet<std::string>& tags) const { return true; }
+ virtual bool eval(const std::set<std::string>& tags) const { return true; }
};
class TagexprTag : public ExpressionImpl
@@ -54,12 +54,12 @@
{
return context.eval(_tag);
}
- virtual bool eval(const OpSet<std::string>& tags) const
+ virtual bool eval(const std::set<std::string>& tags) const
{
if (_tag[0] == '*')
{
string match = _tag.substr(1);
- for (OpSet<string>::const_iterator i = tags.begin();
+ for (std::set<string>::const_iterator i = tags.begin();
i != tags.end(); i++)
if (i->size() >= match.size() &&
i->substr(i->size() - match.size()) == match)
@@ -69,7 +69,7 @@
else if (_tag[_tag.size() - 1] == '*')
{
string match = _tag.substr(0, _tag.size() - 1);
- for (OpSet<string>::const_iterator i = tags.begin();
+ for (std::set<string>::const_iterator i = tags.begin();
i != tags.end(); i++)
if (i->size() >= match.size() &&
i->substr(0, match.size()) == match)
@@ -95,7 +95,7 @@
{
return ! _op(context);
}
- virtual bool eval(const OpSet<std::string>& tags) const
+ virtual bool eval(const std::set<std::string>& tags) const
{
return ! _op(tags);
}
@@ -120,7 +120,7 @@
{
return _op1(context) && _op2(context);
}
- virtual bool eval(const OpSet<std::string>& tags) const
+ virtual bool eval(const std::set<std::string>& tags) const
{
return _op1(tags) && _op2(tags);
}
@@ -145,7 +145,7 @@
{
return _op1(context) || _op2(context);
}
- virtual bool eval(const OpSet<std::string>& tags) const
+ virtual bool eval(const std::set<std::string>& tags) const
{
return _op1(tags) || _op2(tags);
}
@@ -187,12 +187,12 @@
{
std::map<std::string, Expression>::const_iterator i = derivedTags.find(tag);
if (i == derivedTags.end())
- return tags.contains(tag);
- else if (!seen.contains(tag))
+ return tags.find(tag) != tags.end();
+ else if (seen.find(tag) == seen.end())
{
- seen += tag;
+ seen.insert(tag);
bool res = i->second(*this);
- seen -= tag;
+ seen.erase(tag);
return res;
}
else
@@ -203,16 +203,6 @@
}
-#ifndef INSTANTIATING_TEMPLATES
-#include <string>
-
-namespace tagcoll {
- template class FilterItemsByExpression<std::string, std::string>;
- template class FilterTagsByExpression<std::string, std::string>;
-}
-#endif
-
-
#ifdef COMPILE_TESTSUITE
#include <tests/test-utils.h>
@@ -229,10 +219,10 @@
template<> template<>
void to::test<1>()
{
- OpSet<string> test;
- test += "coffee";
- test += "tea";
- test += "sugar";
+ std::set<string> test;
+ test.insert("coffee");
+ test.insert("tea");
+ test.insert("sugar");
Expression e1("coffee");
gen_ensure(e1(test));
@@ -258,9 +248,9 @@
e1 = Expression("!(coffee && milk) && (tea && sugar)");
gen_ensure(e1(test));
- OpSet<string> test1;
- test1 += "coffee";
- test1 += "milk";
+ std::set<string> test1;
+ test1.insert("coffee");
+ test1.insert("milk");
Expression e3("coffee && milk && !sugar");
gen_ensure(e3(test1));
}
@@ -279,8 +269,8 @@
"d: c::D, e::F, f::g\n"
);
InputMerger<string, string> result;
- FilterItemsByExpression<string, string> filter(result, "(*::D && e::F) || c");
- outputCollection(input_coll, filter);
+ parseCollection(input_coll, filterItemsByExpression(
+ "(*::D && e::F) || c", consumer(result)));
InputMerger<string, string> reference;
outputCollection(output_coll, reference);
@@ -303,8 +293,8 @@
"d: c::D, e::F\n"
);
InputMerger<string, string> result;
- FilterTagsByExpression<string, string> filter(result, "*::D || e::F || c");
- outputCollection(input_coll, filter);
+ parseCollection(input_coll, filterItemsByExpression(
+ "*::D || e::F || c", consumer(result)));
InputMerger<string, string> reference;
outputCollection(output_coll, reference);
Modified: tagcoll/2.0/tagcoll/Expression.h
==============================================================================
--- tagcoll/2.0/tagcoll/Expression.h (original)
+++ tagcoll/2.0/tagcoll/Expression.h Tue May 2 00:54:37 2006
@@ -4,7 +4,7 @@
/*
* Expression that can match tagsets
*
- * Copyright (C) 2003,2004,2005 Enrico Zini <enrico at debian.org>
+ * Copyright (C) 2003,2004,2005,2006 Enrico Zini <enrico at debian.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,9 +21,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <tagcoll/Filter.h>
#include <string>
+#include <set>
#include <map>
+#include <vector>
namespace tagcoll
{
@@ -67,7 +68,7 @@
* \return
* true if the expression matches the tags, false otherwise
*/
- virtual bool eval(const OpSet<std::string>& tags) const = 0;
+ virtual bool eval(const std::set<std::string>& tags) const = 0;
/**
* Return a clone of this tag expression
@@ -111,8 +112,8 @@
Expression operator or (const Expression& e);
Expression operator not ();
- template<typename M>
- bool operator()(const OpSet<M>& tags) const { return m_impl->eval(tags); }
+ template<typename Tags>
+ bool operator()(const Tags& tags) const { return m_impl->eval(tags); }
bool operator()(const TagexprContext& context) const { return m_impl->eval(context); }
@@ -136,10 +137,10 @@
class TagexprContext
{
protected:
- const OpSet<std::string>& tags;
+ const std::set<std::string>& tags;
const std::map<std::string, Expression>& derivedTags;
// Tags "visited" during tag evaluation: used to break circular loops
- mutable OpSet<std::string> seen;
+ mutable std::set<std::string> seen;
public:
/**
@@ -155,7 +156,7 @@
* \param derivedTags
* The table of derived tags to use in the evaluation
*/
- TagexprContext(const OpSet<std::string>& tags, const std::map<std::string, Expression>& derivedTags)
+ TagexprContext(const std::set<std::string>& tags, const std::map<std::string, Expression>& derivedTags)
: tags(tags), derivedTags(derivedTags) {}
/**
@@ -166,12 +167,7 @@
bool eval(const std::string& tag) const;
};
-
-/**
- * Remove the items that do not match a tag expression.
- */
-template<class ITEM, class TAG>
-class FilterItemsByExpression : public Filter<ITEM, TAG>
+class ExpressionFilter
{
public:
enum MatchType { PLAIN, INVERTED };
@@ -179,62 +175,21 @@
protected:
Expression expr;
MatchType matchType;
- int matched;
- bool match(const OpSet<TAG>& tags) const
+ template<typename Tags>
+ bool match(const Tags& tags)
{
if (matchType == PLAIN)
return expr(tags);
else
return !expr(tags);
-
}
- virtual void consumeItemUntagged(const ITEM& item)
- {
- if (match(OpSet<TAG>()))
- {
- matched++;
- this->consumer->consume(item);
- }
- }
- virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags)
- {
- if (match(tags))
- {
- matched++;
- this->consumer->consume(item, tags);
- }
- }
- virtual void consumeItemsUntagged(const OpSet<ITEM>& items)
- {
- if (match(OpSet<TAG>()))
- {
- matched += items.size();
- this->consumer->consume(items);
- }
- }
- virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tags)
- {
- if (match(tags))
- {
- matched += items.size();
- this->consumer->consume(items, tags);
- }
- }
-
-public:
- FilterItemsByExpression(const Expression& expression) :
- expr(expression), matchType(PLAIN), matched(0) {}
- FilterItemsByExpression(const std::string& expression) :
- expr(expression), matchType(PLAIN), matched(0) {}
- FilterItemsByExpression(Consumer<ITEM, TAG>&cons, const Expression& expression) :
- Filter<ITEM, TAG>(cons),
- expr(expression), matchType(PLAIN), matched(0) {}
- FilterItemsByExpression(Consumer<ITEM, TAG>&cons, const std::string& expression) :
- Filter<ITEM, TAG>(cons),
- expr(expression), matchType(PLAIN), matched(0) {}
- virtual ~FilterItemsByExpression() {}
+public:
+ ExpressionFilter(const std::string& expr)
+ : expr(expr), matchType(PLAIN) {}
+ ExpressionFilter(const Expression& expr)
+ : expr(expr), matchType(PLAIN) {}
/**
* Set the expression to use for this filter
@@ -266,20 +221,45 @@
* INVERTED: only keep the items that do not match the expression
*/
void setMatchType(MatchType type) { matchType = type; }
+};
- /**
- * Return the number of items that matched the expression.
- *
- * It returns the number of items that did not match if INVERTED match is
- * used.
- *
- * @returns
- * The match count
- */
- int countMatched() const { return matched; }
+/**
+ * Remove the items that do not match a tag expression.
+ */
+template<class OUT>
+class FilterItemsByExpression : public ExpressionFilter
+{
+protected:
+ OUT out;
+public:
+ FilterItemsByExpression(const std::string& expr, const OUT& out)
+ : ExpressionFilter(expr), out(out) {}
+ FilterItemsByExpression(const Expression& expr, const OUT& out)
+ : ExpressionFilter(expr), out(out) {}
+
+ // output iterator interface
+
+ FilterItemsByExpression& operator++() const { return *this; }
+
+ template<typename Items, typename Tags>
+ FilterItemsByExpression& operator=(const std::pair<Items, Tags>& data)
+ {
+ if (match(data.second))
+ {
+ out = data;
+ ++out;
+ }
+ return *this;
+ }
};
+template<typename EXPR, typename OUT>
+inline FilterItemsByExpression<OUT> filterItemsByExpression(const EXPR& expr, const OUT& out)
+{
+ return FilterItemsByExpression<OUT>(expr, out);
+}
+
/**
* Remove the tags that do not singularly match a tag expression.
*
@@ -287,118 +267,53 @@
* tags matching, for example, "special::not-yet-tagged*" or
* "!(use::gaming || game::*)".
*/
-template<class ITEM, class TAG>
-class FilterTagsByExpression : public Filter<ITEM, TAG>
+template<class OUT>
+class FilterTagsByExpression : public ExpressionFilter
{
-public:
- enum MatchType { PLAIN, INVERTED };
-
protected:
- Expression expr;
- MatchType matchType;
- int matched;
+ OUT out;
- bool match(const TAG& tag) const
- {
- OpSet<TAG> tags;
- tags += tag;
- if (matchType == PLAIN)
- return expr(tags);
- else
- return !expr(tags);
- }
+public:
+ FilterTagsByExpression(const std::string& expression, const OUT& out) :
+ ExpressionFilter(expression), out(out) {}
+ FilterTagsByExpression(const Expression& expression, const OUT& out) :
+ ExpressionFilter(expression), out(out) {}
- virtual void consumeItemUntagged(const ITEM& item)
- {
- this->consumer->consume(item);
- }
+ // output iterator interface
- virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags)
- {
- OpSet<TAG> outTags;
- for (typename OpSet<TAG>::const_iterator i = tags.begin(); i != tags.end(); i++)
- if (match(*i))
- {
- matched++;
- outTags += *i;
- }
- this->consumer->consume(item, outTags);
- }
+ FilterTagsByExpression& operator++() const { return *this; }
- virtual void consumeItemsUntagged(const OpSet<ITEM>& items)
+ template<typename Items, typename Tags>
+ FilterTagsByExpression& operator=(const std::pair<Items, Tags>& data)
{
- this->consumer->consume(items);
- }
+ // We can use a vector since we know the input is sorted, and we
+ // remove elements without altering the order of the remaining ones
+ std::vector<typename Tags::value_type> filtered;
+ bool changed = false;
- virtual void consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tags)
- {
- OpSet<TAG> outTags;
- for (typename OpSet<TAG>::const_iterator i = tags.begin();
- i != tags.end(); i++)
+ for (typename Tags::iterator i = data.second.begin();
+ i != data.second.end(); ++i)
+ {
if (match(*i))
- {
- matched += items.size();
- outTags += *i;
- }
- this->consumer->consume(items, outTags);
- }
-
-public:
- FilterTagsByExpression(const Expression& expression) :
- expr(expression), matchType(PLAIN), matched(0) {}
- FilterTagsByExpression(const std::string& expression) :
- expr(expression), matchType(PLAIN), matched(0) {}
- FilterTagsByExpression(Consumer<ITEM, TAG>&cons, const Expression& expression) :
- Filter<ITEM, TAG>(cons),
- expr(expression), matchType(PLAIN), matched(0) {}
- FilterTagsByExpression(Consumer<ITEM, TAG>&cons, const std::string& expression) :
- Filter<ITEM, TAG>(cons),
- expr(expression), matchType(PLAIN), matched(0) {}
- virtual ~FilterTagsByExpression() {}
-
- /**
- * Set the expression to use for this filter
- *
- * @param expression
- * The expression to use for matching
- */
- void setExpression(const Expression& expression)
- {
- expr = expression;
- }
-
- /**
- * Set the expression to use for this filter
- *
- * @param expression
- * The expression to use for matching
- */
- void setExpression(const std::string& expression)
- {
- expr = Expression(expression);
+ filtered.push_back(*i);
+ else
+ changed = true;
+ }
+ if (!changed)
+ out = data;
+ else
+ out = std::make_pair(data.first, filtered);
+ ++out;
+ return *this;
}
-
- /**
- * Set the type of match
- *
- * @param type
- * PLAIN: only keep the tags that match the expression
- * INVERTED: only keep the tags that do not match the expression
- */
- void setMatchType(MatchType type) { matchType = type; }
-
- /**
- * Return the number of tags that matched the expression.
- *
- * It returns the number oftags that did not match if INVERTED match is
- * used.
- *
- * @returns
- * The match count
- */
- int countMatched() const { return matched; }
};
+template<typename EXPR, typename OUT>
+inline FilterTagsByExpression<OUT> filterTagsByExpression(const EXPR& expr, const OUT& out)
+{
+ return FilterTagsByExpression<OUT>(expr, out);
+}
+
};
// vim:set ts=4 sw=4:
Modified: tagcoll/2.0/tagcoll/Filters.cc
==============================================================================
--- tagcoll/2.0/tagcoll/Filters.cc (original)
+++ tagcoll/2.0/tagcoll/Filters.cc Tue May 2 00:54:37 2006
@@ -68,17 +68,6 @@
}
-#ifndef INSTANTIATING_TEMPLATES
-#include <string>
-
-namespace tagcoll {
-template class Substitutions<std::string>;
-template class Substitute<std::string, std::string>;
-template class UnfacetedRemover<std::string>;
-}
-#endif
-
-
#ifdef COMPILE_TESTSUITE
#include <tests/test-utils.h>
@@ -112,10 +101,10 @@
"d: c::D, f::g\n"
);
InputMerger<string, string> result;
- Substitute<string, string> filter(result);
+ Substitutions<string> changes;
- outputCollection(input_subst, filter.substitutions());
- outputCollection(input_coll, filter);
+ parseCollection(input_subst, changes.inserter());
+ parseCollection(input_coll, substitute(changes, consumer(result)));
InputMerger<string, string> reference;
outputCollection(output_coll, reference);
Modified: tagcoll/2.0/tagcoll/Filters.h
==============================================================================
--- tagcoll/2.0/tagcoll/Filters.h (original)
+++ tagcoll/2.0/tagcoll/Filters.h Tue May 2 00:54:37 2006
@@ -39,23 +39,44 @@
* collections such as TextFormat.
*/
template<typename T>
-class Substitutions : public Consumer<T, T>
+class Substitutions
{
protected:
typedef std::map<T, T> changes_t;
changes_t changes;
- virtual void consumeItemUntagged(const T& item) {}
- virtual void consumeItem(const T& item, const OpSet<T>& tags)
+public:
+ template<typename IT>
+ class SubstitutionsInserter
{
- for (typename OpSet<T>::const_iterator i = tags.begin();
- i != tags.end(); i++)
- changes.insert(make_pair(*i, item));
- }
- virtual void consumeItemsUntagged(const OpSet<T>& items) {}
+ Substitutions<IT>& out;
-public:
- virtual ~Substitutions() {}
+ public:
+ SubstitutionsInserter(Substitutions<IT>& out)
+ : out(out) {}
+ SubstitutionsInserter& operator++() const { return *this; }
+
+ template<typename NewItems, typename OldItems>
+ SubstitutionsInserter& operator=(const std::pair<NewItems, OldItems>& data)
+ {
+ for (typename NewItems::const_iterator i = data.first.begin();
+ i != data.first.end(); ++i)
+ for (typename OldItems::const_iterator j = data.second.begin();
+ j != data.second.end(); ++j)
+ out.add(*j, *i);
+ }
+ };
+
+ /// Change all the items in a set
+ template<typename Items>
+ std::set<T> change(const Items& values) const
+ {
+ std::set<T> res;
+ for (typename Items::const_iterator t = values.begin();
+ t != values.end(); ++t)
+ res.insert(change(*t));
+ return res;
+ }
/// Change a single value
T change(const T& v) const
@@ -65,14 +86,16 @@
return (i == changes.end()) ? v : i->second;
}
- /// Change all the items in a set
- OpSet<T> change(const OpSet<T>& values) const
+ /// Add one substitution to the list
+ void add(const T& oldItem, const T& newItem)
{
- OpSet<T> res;
- for (typename OpSet<T>::const_iterator t = values.begin();
- t != values.end(); t++)
- res += change(*t);
- return res;
+ changes.insert(make_pair(oldItem, newItem));
+ }
+
+ /// Create an inserter for this class
+ SubstitutionsInserter<T> inserter()
+ {
+ return SubstitutionsInserter<T>(*this);
}
};
@@ -91,47 +114,43 @@
* coll.output(filter);
* \endcode
*/
-template<typename ITEM, typename TAG>
-class Substitute : public Filter<ITEM, TAG>
+template<typename T, typename OUT>
+class Substitute
{
protected:
- Substitutions<TAG> changes;
+ Substitutions<T> changes;
+ OUT out;
- virtual void consumeItemUntagged(const ITEM& item)
- {
- this->consumer->consume(item);
- }
- virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags)
- {
- this->consumer->consume(item, changes.change(tags));
- }
- virtual void consumeItemsUntagged(const OpSet<ITEM>& items)
- {
- this->consumer->consume(items);
- }
- virtual void consumeItem(const OpSet<ITEM>& items, const OpSet<TAG>& tags)
- {
- this->consumer->consume(items, changes.change(tags));
- }
-
public:
- Substitute() {}
- Substitute(Consumer<ITEM, TAG>& cons) : Filter<ITEM, TAG>(cons) {}
- Substitute(const Substitutions<TAG>& changes) : changes(changes) {}
- Substitute(Consumer<ITEM, TAG>& cons, const Substitutions<TAG>& changes) :
- Filter<ITEM, TAG>(cons), changes(changes) {}
+ Substitute(const OUT& out) : out(out) {}
+ Substitute(const Substitutions<T>& changes, const OUT& out) : changes(changes), out(out) {}
/**
* Access the internal Substitution list
*/
- Substitutions<TAG>& substitutions() { return changes; }
+ Substitutions<T>& substitutions() { return changes; }
/**
* Access the internal Substitution list (const version)
*/
- const Substitutions<TAG>& substitutions() const { return changes; }
+ const Substitutions<T>& substitutions() const { return changes; }
+
+ Substitute<T, OUT>& operator++() const { return *this; }
+
+ template<typename Items, typename Tags>
+ Substitute<T, OUT>& operator=(const std::pair<Items, Tags>& data)
+ {
+ out = make_pair(data.first, changes.change(data.second));
+ ++out;
+ }
};
+template<typename T, typename OUT>
+Substitute<T, OUT> substitute(const Substitutions<T>& changes, const OUT& out)
+{
+ return Substitute<T, OUT>(changes, out);
+}
+
/**
* Remove packages with no tags.
*
Modified: tagcoll/2.0/tagcoll/Makefile.am
==============================================================================
--- tagcoll/2.0/tagcoll/Makefile.am (original)
+++ tagcoll/2.0/tagcoll/Makefile.am Tue May 2 00:54:37 2006
@@ -15,6 +15,7 @@
StdioParserInput.h \
\
Consumer.h \
+ Sink.h \
Filter.h \
ReadonlyCollection.h \
Collection.h \
@@ -28,7 +29,7 @@
Serializer.h \
Serializer.cc \
TextFormat.h \
- TextFormat.cc \
+ TextFormat.tcc \
\
TDBIndexer.h \
TDBIndexer.cc \
@@ -64,6 +65,7 @@
\
Consumer.cc \
Filter.cc \
+ Filters.cc \
Patches.cc \
InputMerger.cc \
PatchCollection.cc \
@@ -79,7 +81,6 @@
IntDiskIndex.cc \
BasicStringDiskIndex.cc \
\
- Filters.cc \
Implications.cc \
\
Expression.cc \
Modified: tagcoll/2.0/tagcoll/TextFormat.cc
==============================================================================
--- tagcoll/2.0/tagcoll/TextFormat.cc (original)
+++ tagcoll/2.0/tagcoll/TextFormat.cc Tue May 2 00:54:37 2006
@@ -30,372 +30,6 @@
using namespace stringf;
using namespace tagcoll;
-static void printTagset(const OpSet<string>& ts, FILE* out)
-{
- for (OpSet<string>::const_iterator i = ts.begin();
- i != ts.end(); i++)
- if (i == ts.begin())
- {
- if (fprintf(out, "%.*s", PFSTR(*i)) < 0)
- throw wibble::exception::System("writing tagset");
- }
- else
- {
- if (fprintf(out, ", %.*s", PFSTR(*i)) < 0)
- throw wibble::exception::System("writing tagset");
- }
-}
-
-template<class ITEM, class TAG>
-void TextFormat<ITEM, TAG>::consumeItemUntagged(const ITEM& item)
-{
- string sitem = itemconv(item);
- if (fprintf(out, "%.*s\n", PFSTR(sitem)) < 0)
- throw wibble::exception::System("writing item");
-}
-
-template<class ITEM, class TAG>
-void TextFormat<ITEM, TAG>::consumeItem(const ITEM& item, const OpSet<TAG>& tags)
-{
- string sitem = itemconv(item);
- if (fprintf(out, "%.*s: ", PFSTR(sitem)) < 0)
- throw wibble::exception::System("writing item");
- printTagset(tagconv(tags), out);
- if (fprintf(out, "\n") < 0)
- throw wibble::exception::System("writing newline after tagset");
-}
-
-template<class ITEM, class TAG>
-void TextFormat<ITEM, TAG>::consumeItemsUntagged(const OpSet<ITEM>& items)
-{
- printTagset(itemconv(items), out);
- if (fprintf(out, "\n") < 0)
- throw wibble::exception::System("writing newline after items");
-}
-
-template<class ITEM, class TAG>
-void TextFormat<ITEM, TAG>::consumeItems(const OpSet<ITEM>& items, const OpSet<TAG>& tags)
-{
- printTagset(itemconv(items), out);
- if (fprintf(out, ": ") < 0)
- throw wibble::exception::System("writing colon after items");
- printTagset(tagconv(tags), out);
- if (fprintf(out, "\n") < 0)
- throw wibble::exception::System("writing newline after tagset");
-}
-
-
-template<class ITEM, class TAG>
-void TextFormat<ITEM, TAG>::outputPatch(
- Converter<ITEM, std::string>& itemconv,
- Converter<TAG, std::string>& tagconv,
- const PatchList<ITEM, TAG>& patch,
- FILE* out)
-{
- for (typename PatchList<ITEM, TAG>::const_iterator i = patch.begin();
- i != patch.end(); i++)
- {
- string sitem = itemconv(i->first);
- if (fprintf(out, "%.*s: ", PFSTR(sitem)) < 0)
- throw wibble::exception::System("writing item");
-
- OpSet<string> stags;
- for (typename OpSet<TAG>::const_iterator j = i->second.getAdded().begin();
- j != i->second.getAdded().end(); j++)
- stags += "+"+tagconv(*j);
- for (typename OpSet<TAG>::const_iterator j = i->second.getRemoved().begin();
- j != i->second.getRemoved().end(); j++)
- stags += "-"+tagconv(*j);
-
- printTagset(stags, out);
- if (fprintf(out, "\n") < 0)
- throw wibble::exception::System("writing newline after tagset");
- }
-}
-
-
-// Parse an element
-// Return the trailing separating char, that can be:
-// ParserInput::Eof
-// '\n'
-// ':'
-// ','
-// Return the item in `item'
-
-// element: \s*[^ \t,:]\s*([.:])\s*
-// or
-// element: \s*[^ \t,:].*?[^ \t,:]\s*([.:])\s+
-static int parseElement(ParserInput& in, string& item) throw (tagcoll::exception::Parser)
-{
- item = string();
- string sep;
- int c;
- char sepchar = 0;
- enum {LSPACE, ITEM, ISPACE, ISEP, TSPACE} state = LSPACE;
- while ((c = in.nextChar()) != ParserInput::Eof)
- {
- if (c == '\n')
- {
- if (sepchar && sepchar != ':')
- throw tagcoll::exception::Parser("separator character ends the line");
- else
- return '\n';
- }
- switch (state)
- {
- // Optional leading space
- case LSPACE:
- switch (c)
- {
- case ' ':
- case '\t':
- break;
- case ':':
- case ',':
- throw tagcoll::exception::Parser("element cannot start with a separation character");
- break;
- default:
- item += c;
- state = ITEM;
- break;
- }
- break;
- // Non-separating characters
- case ITEM:
- switch (c)
- {
- case ' ':
- case '\t':
- sep += c;
- state = ISPACE;
- break;
- case ':':
- case ',':
- sepchar = c;
- sep += c;
- state = ISEP;
- break;
- default:
- item += c;
- break;
- }
- break;
- // Space inside item or at the end of item
- case ISPACE:
- switch (c)
- {
- case ' ':
- case '\t':
- sep += c;
- break;
- case ':':
- case ',':
- sepchar = c;
- state = TSPACE;
- break;
- default:
- item += sep;
- item += c;
- sep = string();
- state = ITEM;
- break;
- }
- break;
- // Separator inside item or at the end of item
- case ISEP:
- switch (c)
- {
- case ' ':
- case '\t':
- if (sep.size() > 1)
- throw tagcoll::exception::Parser("item is followed by more than one separator characters");
- state = TSPACE;
- break;
- case ':':
- case ',':
- sep += c;
- break;
- default:
- item += sep;
- item += c;
- sepchar = 0;
- sep = string();
- state = ITEM;
- break;
- }
- break;
- case TSPACE:
- switch (c)
- {
- case ' ':
- case '\t':
- break;
- default:
- in.pushChar(c);
- return sepchar;
- }
- break;
- }
- }
- return ParserInput::Eof;
-}
-
-// item1, item2, item3: tag1, tag2, tag3
-
-//#define TRACE_PARSE
-static void parseTextFormat(
- ParserInput& in,
- Consumer<string, string>& consumer)
-{
- string item;
-
- OpSet<string> itemset;
- OpSet<string> tagset;
- int sep;
- enum {ITEMS, TAGS} state = ITEMS;
- int line = 1;
- do
- {
- try {
- sep = parseElement(in, item);
- } catch (tagcoll::exception::Parser& e) {
- // Add the line number and propagate
- e.line(line);
- throw e;
- }
-
- if (item.size() != 0)
- if (state == ITEMS)
- itemset += item;
- else
- tagset += item;
-
- switch (sep)
- {
- case '\n':
- line++;
- case ParserInput::Eof:
- if (!(itemset.empty() && tagset.empty()))
- {
- if (itemset.empty())
- throw tagcoll::exception::Parser(line, "no elements before `:' separator");
- if (tagset.empty())
- consumer.consume(itemset);
- else
- consumer.consume(itemset, tagset);
- }
- itemset.clear();
- tagset.clear();
- state = ITEMS;
- break;
- case ':':
- if (state == TAGS)
- throw tagcoll::exception::Parser(line, "separator `:' appears twice");
- state = TAGS;
- break;
- default:
- break;
- }
- } while (sep != ParserInput::Eof);
-}
-
-
-template<class ITEM, class TAG>
-void TextFormat<ITEM, TAG>::parse(
- Converter<std::string, ITEM>& itemconv,
- Converter<std::string, TAG>& tagconv,
- ParserInput& in,
- Consumer<ITEM, TAG>& consumer)
-{
- ConversionFilter<string, string, ITEM, TAG> conv(itemconv, tagconv, consumer);
- parseTextFormat(in, conv);
-}
-
-template<class ITEM, class TAG>
-class PatchBuilder : public Consumer<string, string>
-{
-protected:
- PatchList<ITEM, TAG> patch;
- const Converter<std::string, ITEM>& itemconv;
- const Converter<std::string, TAG>& tagconv;
-
- virtual void consumeItemUntagged(const string&) {}
-
- virtual void consumeItem(const string& item, const OpSet<string>& tags)
- {
- ITEM it = itemconv(item);
- if (it == ITEM())
- return;
-
- Patch<ITEM, TAG> p(it);
- for (OpSet<string>::const_iterator i = tags.begin(); i != tags.end(); i++)
- {
- TAG tag = tagconv(i->substr(1));
- if (tag != TAG())
- if ((*i)[0] == '-')
- p.remove(tag);
- else if ((*i)[0] == '+')
- p.add(tag);
- }
- patch.addPatch(p);
- }
-
- virtual void consumeItemsUntagged(const OpSet<string>&) {}
-
- virtual void consumeItems(const OpSet<string>& items, const OpSet<string>& tags)
- {
- OpSet<TAG> added;
- OpSet<TAG> removed;
-
- for (OpSet<string>::const_iterator i = tags.begin(); i != tags.end(); i++)
- {
- TAG tag = tagconv(i->substr(1));
- if (tag != TAG())
- if ((*i)[0] == '-')
- removed += tag;
- else if ((*i)[0] == '+')
- added += tag;
- }
-
- for (OpSet<string>::const_iterator i = items.begin(); i != items.end(); i++)
- {
- ITEM it = itemconv(*i);
- if (it != ITEM())
- patch.addPatch(Patch<ITEM, TAG>(it, added, removed));
- }
- }
-
-
-public:
- PatchBuilder(
- const Converter<std::string, ITEM>& itemconv,
- const Converter<std::string, TAG>& tagconv)
- : itemconv(itemconv), tagconv(tagconv) {}
- virtual ~PatchBuilder() {}
-
- const PatchList<ITEM, TAG>& getPatch() const throw () { return patch; }
-};
-
-template<class ITEM, class TAG>
-PatchList<ITEM, TAG> TextFormat<ITEM, TAG>::parsePatch(
- Converter<std::string, ITEM>& itemconv,
- Converter<std::string, TAG>& tagconv,
- ParserInput& in)
-{
- PatchBuilder<ITEM, TAG> builder(itemconv, tagconv);
- parseTextFormat(in, builder);
- return builder.getPatch();
-}
-
-#ifndef INSTANTIATING_TEMPLATES
-#include <string>
-
-namespace tagcoll {
- template class TextFormat<std::string, std::string>;
-}
-#endif
-
-
#ifdef COMPILE_TESTSUITE
#include <tests/test-utils.h>
@@ -419,9 +53,7 @@
);
TestConsumer<string, string> cons;
-
- TrivialConverter<string, string> a;
- TextFormat<string, string>::parse(a, a, coll, cons);
+ TextFormat<string, string>::parse(coll, consumer(cons));
gen_ensure_equals(cons.items, 4);
gen_ensure_equals(cons.tags, 5);
Modified: tagcoll/2.0/tagcoll/TextFormat.h
==============================================================================
--- tagcoll/2.0/tagcoll/TextFormat.h (original)
+++ tagcoll/2.0/tagcoll/TextFormat.h Tue May 2 00:54:37 2006
@@ -57,6 +57,8 @@
const Converter<TAG, std::string>& tagconv;
FILE* out;
+ static int parseElement(ParserInput& in, std::string& item) throw (tagcoll::exception::Parser);
+
virtual void consumeItemUntagged(const ITEM& item);
virtual void consumeItem(const ITEM& item, const OpSet<TAG>& tags);
virtual void consumeItemsUntagged(const OpSet<ITEM>& items);
@@ -80,6 +82,16 @@
FILE* out);
/**
+ * Parse a tagged collection, sending the results to out.
+ *
+ * @param out
+ * An output iterator accepting a std::pair<string, string>
+ */
+ template<typename OUT>
+ static void parse(ParserInput& in, OUT out);
+
+#if 0
+ /**
* Parse a tagged collection, sending the data to `consumer'
*/
static void parse(
@@ -87,6 +99,7 @@
Converter<std::string, TAG>& tagconv,
ParserInput& in,
Consumer<ITEM, TAG>& consumer);
+#endif
/**
* Parse a tagcoll patch
Modified: tagcoll/2.0/tagcoll/test-utils.cc
==============================================================================
--- tagcoll/2.0/tagcoll/test-utils.cc (original)
+++ tagcoll/2.0/tagcoll/test-utils.cc Tue May 2 00:54:37 2006
@@ -50,8 +50,7 @@
void outputCollection(const std::string& str, tagcoll::Consumer<string, string>& cons)
{
StringParserInput input(str);
- TrivialConverter<string, string> a;
- TextFormat<string, string>::parse(a, a, input, cons);
+ TextFormat<string, string>::parse(input, consumer(cons));
}
void __tc_ensure_coll_equals(const Location& loc,
Modified: tagcoll/2.0/tests/normalize.cc
==============================================================================
--- tagcoll/2.0/tests/normalize.cc (original)
+++ tagcoll/2.0/tests/normalize.cc Tue May 2 00:54:37 2006
@@ -22,7 +22,7 @@
scores.add("implemented-in::*", 0.3);
scores.add("*::TODO", 0.1);
- TextFormat<string, string>::parse(conv, conv, in, norm);
+ TextFormat<string, string>::parse(in, consumer(norm));
norm.buildGraph(scores);
norm.normalize();
@@ -37,4 +37,6 @@
}
}
+#include <tagcoll/TextFormat.tcc>
+
// vim:set ts=4 sw=4:
Modified: tagcoll/2.0/tests/test-utils.h
==============================================================================
--- tagcoll/2.0/tests/test-utils.h (original)
+++ tagcoll/2.0/tests/test-utils.h Tue May 2 00:54:37 2006
@@ -12,6 +12,8 @@
#ifdef TEST_TAGCOLL
#include <tagcoll/Collection.h>
+#include <tagcoll/StringParserInput.h>
+#include <tagcoll/TextFormat.h>
#endif
/*
#include <apt-front/cache.h>
@@ -85,6 +87,13 @@
void outputCollection(const std::string& str, tagcoll::Consumer<string, string>& cons);
+template<typename OUT>
+void parseCollection(const std::string& str, const OUT& out)
+{
+ StringParserInput input(str);
+ TextFormat<string, string>::parse(input, out);
+}
+
#define gen_ensure(x) _gen_ensure(Location(__FILE__, __LINE__, #x), (x))
#define inner_ensure(x) _gen_ensure(Location(loc, __FILE__, __LINE__, #x), (x))
void _gen_ensure(const Location& loc, bool res);
Modified: tagcoll/2.0/tools/tagcoll.cc
==============================================================================
--- tagcoll/2.0/tools/tagcoll.cc (original)
+++ tagcoll/2.0/tools/tagcoll.cc Tue May 2 00:54:37 2006
@@ -49,7 +49,6 @@
#include <tagcoll/Filters.h>
#include <tagcoll/Patches.h>
#include <tagcoll/DerivedTags.h>
-#include <tagcoll/ItemGrouper.h>
#include <tagcoll/StdioParserInput.h>
#include <tagcoll/TextFormat.h>
@@ -115,17 +114,15 @@
void readCollection(const string& file, Consumer<string, string>& builder)
{
- TrivialConverter<string, string> conv;
-
if (file == "-")
{
StdioParserInput input(stdin, "<stdin>");
- TextFormat<string, string>::parse(conv, conv, input, builder);
+ TextFormat<string, string>::parse(input, consumer(builder));
}
else
{
StdioParserInput input(file);
- TextFormat<string, string>::parse(conv, conv, input, builder);
+ TextFormat<string, string>::parse(input, consumer(builder));
}
}
More information about the Debtags-commits
mailing list