summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--news/pan/Makefile4
-rw-r--r--news/pan/distinfo13
-rw-r--r--news/pan/patches/patch-pan_data-impl_article-filter.cc32
-rw-r--r--news/pan/patches/patch-pan_data-impl_groups.cc13
-rw-r--r--news/pan/patches/patch-pan_data-impl_rules-filter.cc26
-rw-r--r--news/pan/patches/patch-pan_general_log.cc17
-rw-r--r--news/pan/patches/patch-pan_general_log.h34
-rw-r--r--news/pan/patches/patch-pan_gui_header-pane.cc179
-rw-r--r--news/pan/patches/patch-pan_gui_log-ui.cc40
-rw-r--r--news/pan/patches/patch-pan_usenet-utils_filter-info.cc51
-rw-r--r--news/pan/patches/patch-pan_usenet-utils_filter-info.h30
-rw-r--r--news/pan/patches/patch-pan_usenet-utils_rules-info.h18
-rw-r--r--news/pan/patches/patch-pan_usenet-utils_scorefile.cc96
13 files changed, 550 insertions, 3 deletions
diff --git a/news/pan/Makefile b/news/pan/Makefile
index ab9a55a5b24..086ea1bad50 100644
--- a/news/pan/Makefile
+++ b/news/pan/Makefile
@@ -1,7 +1,7 @@
-# $NetBSD: Makefile,v 1.82 2013/10/10 14:42:29 ryoon Exp $
+# $NetBSD: Makefile,v 1.83 2014/01/01 12:10:00 wiz Exp $
DISTNAME= pan-0.139
-PKGREVISION= 12
+PKGREVISION= 13
CATEGORIES= news
MASTER_SITES= http://pan.rebelbase.com/download/releases/${DISTNAME:C/pan-//}/source/
EXTRACT_SUFX= .tar.bz2
diff --git a/news/pan/distinfo b/news/pan/distinfo
index de3be05eac4..b8faba6c5c2 100644
--- a/news/pan/distinfo
+++ b/news/pan/distinfo
@@ -1,6 +1,17 @@
-$NetBSD: distinfo,v 1.26 2013/07/17 07:41:44 wiz Exp $
+$NetBSD: distinfo,v 1.27 2014/01/01 12:10:00 wiz Exp $
SHA1 (pan-0.139.tar.bz2) = 01ea0361a6d81489888e6abb075fd552999c3c60
RMD160 (pan-0.139.tar.bz2) = e0e2963b2d11b362201639ca755ad9ae43581c2f
Size (pan-0.139.tar.bz2) = 1523907 bytes
+SHA1 (patch-pan_data-impl_article-filter.cc) = 8d395673700dc10e0fca556fb6058b10de95ea9d
+SHA1 (patch-pan_data-impl_groups.cc) = 21da9a139bbc37d76f8364bc1d6003702c9f3ff9
+SHA1 (patch-pan_data-impl_rules-filter.cc) = 4d10677b204bb419b42ec369b2fbef6541572c1d
+SHA1 (patch-pan_general_log.cc) = ef37ec3af99236ff68328a60a1f2f7eaed232070
+SHA1 (patch-pan_general_log.h) = 981e7036c30ed56c554d501d625016499a559935
+SHA1 (patch-pan_gui_header-pane.cc) = f8e2b04d53c8c6495b14f826f95b1b3b74d2aebd
+SHA1 (patch-pan_gui_log-ui.cc) = e455ea6d165c315e0969a8199d0e4549958280bb
+SHA1 (patch-pan_usenet-utils_filter-info.cc) = 6049d198a3a5029429a8d4f9f0fd3fed0896ebfb
+SHA1 (patch-pan_usenet-utils_filter-info.h) = 23a2d86ee09cb36c805ca1b7c7c777e6daedb918
SHA1 (patch-pan_usenet-utils_mime-utils.cc) = fb3703e8e5ddd24b337b583e3f4348358a0098f5
+SHA1 (patch-pan_usenet-utils_rules-info.h) = 8b150a171c69b434187535bd0b2f837938f40636
+SHA1 (patch-pan_usenet-utils_scorefile.cc) = 9cb7d4c9cf593beedebdf4972058bcdee51ee349
diff --git a/news/pan/patches/patch-pan_data-impl_article-filter.cc b/news/pan/patches/patch-pan_data-impl_article-filter.cc
new file mode 100644
index 00000000000..03514397cbf
--- /dev/null
+++ b/news/pan/patches/patch-pan_data-impl_article-filter.cc
@@ -0,0 +1,32 @@
+$NetBSD: patch-pan_data-impl_article-filter.cc,v 1.3 2014/01/01 12:10:00 wiz Exp $
+
+--- pan/data-impl/article-filter.cc.orig 2013-12-21 12:38:33.000000000 +0000
++++ pan/data-impl/article-filter.cc
+@@ -62,10 +62,10 @@ ArticleFilter :: test_article (const Dat
+ {
+ case FilterInfo::AGGREGATE_AND:
+ pass = true;
+- foreach_const (FilterInfo::aggregates_t, criteria._aggregates, it) {
++ foreach_const (FilterInfo::aggregatesp_t, criteria._aggregates, it) {
+ // assume test passes if test needs body but article not cached
+- if (!it->_needs_body || cache.contains(article.message_id) )
+- if (!test_article (data, *it, group, article)) {
++ if (!(*it)->_needs_body || cache.contains(article.message_id) )
++ if (!test_article (data, **it, group, article)) {
+ pass = false;
+ break;
+ }
+@@ -77,10 +77,10 @@ ArticleFilter :: test_article (const Dat
+ pass = true;
+ else {
+ pass = false;
+- foreach_const (FilterInfo::aggregates_t, criteria._aggregates, it) {
++ foreach_const (FilterInfo::aggregatesp_t, criteria._aggregates, it) {
+ // assume test fails if test needs body but article not cached
+- if (!it->_needs_body || cache.contains(article.message_id) )
+- if (test_article (data, *it, group, article)) {
++ if (!(*it)->_needs_body || cache.contains(article.message_id) )
++ if (test_article (data, **it, group, article)) {
+ pass = true;
+ break;
+ }
diff --git a/news/pan/patches/patch-pan_data-impl_groups.cc b/news/pan/patches/patch-pan_data-impl_groups.cc
new file mode 100644
index 00000000000..4278598ed56
--- /dev/null
+++ b/news/pan/patches/patch-pan_data-impl_groups.cc
@@ -0,0 +1,13 @@
+$NetBSD: patch-pan_data-impl_groups.cc,v 1.3 2014/01/01 12:10:00 wiz Exp $
+
+--- pan/data-impl/groups.cc.orig 2013-12-21 12:39:52.000000000 +0000
++++ pan/data-impl/groups.cc
+@@ -81,7 +81,7 @@ namespace
+ }
+ }
+
+-#include <ext/algorithm>
++#include <algorithm>
+
+ void
+ DataImpl :: load_newsrc (const Quark & server,
diff --git a/news/pan/patches/patch-pan_data-impl_rules-filter.cc b/news/pan/patches/patch-pan_data-impl_rules-filter.cc
new file mode 100644
index 00000000000..22153ffd046
--- /dev/null
+++ b/news/pan/patches/patch-pan_data-impl_rules-filter.cc
@@ -0,0 +1,26 @@
+$NetBSD: patch-pan_data-impl_rules-filter.cc,v 1.3 2014/01/01 12:10:00 wiz Exp $
+
+--- pan/data-impl/rules-filter.cc.orig 2013-12-21 12:39:24.000000000 +0000
++++ pan/data-impl/rules-filter.cc
+@@ -62,8 +62,8 @@ RulesFilter :: test_article ( Data
+ {
+ case RulesInfo::AGGREGATE__AND:
+ pass = true;
+- foreach (RulesInfo::aggregates_t, rules._aggregates, it)
+- test_article (data, *it, group, article);
++ foreach (RulesInfo::aggregatesp_t, rules._aggregates, it)
++ test_article (data, **it, group, article);
+ break;
+
+ case RulesInfo::AGGREGATE__OR:
+@@ -71,8 +71,8 @@ RulesFilter :: test_article ( Data
+ pass = true;
+ else {
+ pass = false;
+- foreach (RulesInfo::aggregates_t, rules._aggregates, it) {
+- if (test_article (data, *it, group, article)) {
++ foreach (RulesInfo::aggregatesp_t, rules._aggregates, it) {
++ if (test_article (data, **it, group, article)) {
+ pass = true;
+ break;
+ }
diff --git a/news/pan/patches/patch-pan_general_log.cc b/news/pan/patches/patch-pan_general_log.cc
new file mode 100644
index 00000000000..d02c3b91202
--- /dev/null
+++ b/news/pan/patches/patch-pan_general_log.cc
@@ -0,0 +1,17 @@
+$NetBSD: patch-pan_general_log.cc,v 1.3 2014/01/01 12:10:00 wiz Exp $
+
+--- pan/general/log.cc.orig 2012-06-29 22:24:54.000000000 +0000
++++ pan/general/log.cc
+@@ -68,7 +68,11 @@ Log :: add_entry(Entry& e, std::deque<En
+ a.date = time(NULL);
+ a.severity = e.severity;
+ a.message = e.message;
+- a.messages = list;
++ foreach (std::deque<Entry>, list, it)
++ {
++ Entry* new_entry = new Entry(*it);
++ a.messages.push_back(new_entry);
++ }
+ fire_entry_added (a);
+ }
+
diff --git a/news/pan/patches/patch-pan_general_log.h b/news/pan/patches/patch-pan_general_log.h
new file mode 100644
index 00000000000..3a1220cf098
--- /dev/null
+++ b/news/pan/patches/patch-pan_general_log.h
@@ -0,0 +1,34 @@
+$NetBSD: patch-pan_general_log.h,v 1.3 2014/01/01 12:10:00 wiz Exp $
+
+--- pan/general/log.h.orig 2012-06-29 22:24:54.000000000 +0000
++++ pan/general/log.h
+@@ -24,6 +24,7 @@
+ #include <set>
+ #include <string>
+ #include <deque>
++#include <pan/general/macros.h>
+
+ namespace pan
+ {
+@@ -49,10 +50,11 @@ namespace pan
+ struct Entry {
+ time_t date;
+ Severity severity;
+- std::deque<Entry> messages;
++ std::deque<Entry*> messages;
+ std::string message;
+ bool is_child;
+- Entry() : is_child(false) { }
++ Entry() : is_child(false), severity(PAN_SEVERITY_INFO), date(0) { }
++ virtual ~Entry () { foreach (std::deque<Entry*>, messages, it) delete *it; }
+ };
+
+ void add_entry(Entry& e, std::deque<Entry>& list);
+@@ -66,6 +68,7 @@ namespace pan
+ };
+
+ typedef std::deque<Entry> entries_t;
++ typedef std::deque<Entry*> entries_p;
+
+ public:
+ void add (Severity, const char *);
diff --git a/news/pan/patches/patch-pan_gui_header-pane.cc b/news/pan/patches/patch-pan_gui_header-pane.cc
new file mode 100644
index 00000000000..873a43476fe
--- /dev/null
+++ b/news/pan/patches/patch-pan_gui_header-pane.cc
@@ -0,0 +1,179 @@
+$NetBSD: patch-pan_gui_header-pane.cc,v 1.3 2014/01/01 12:10:00 wiz Exp $
+
+--- pan/gui/header-pane.cc.orig 2013-12-21 12:40:58.000000000 +0000
++++ pan/gui/header-pane.cc
+@@ -1250,26 +1250,29 @@ HeaderPane :: rebuild_rules (bool enable
+
+ RulesInfo &r (_rules);
+ r.set_type_aggregate_and ();
+- RulesInfo tmp;
++ RulesInfo *tmp;
+
+ std::pair<int,int> res;
+
++ tmp = new RulesInfo;
+ res = get_int_from_rules_str(_prefs.get_string("rules-delete-value", "never"));
+- tmp.set_type_delete_b (res.first, res.second);
++ tmp->set_type_delete_b (res.first, res.second);
+ r._aggregates.push_back (tmp);
+
++ tmp = new RulesInfo;
+ res = get_int_from_rules_str(_prefs.get_string("rules-mark-read-value", "never"));
+- tmp.set_type_mark_read_b (res.first, res.second);
++ tmp->set_type_mark_read_b (res.first, res.second);
+ r._aggregates.push_back (tmp);
+
++ tmp = new RulesInfo;
+ res = get_int_from_rules_str(_prefs.get_string("rules-autocache-value", "never"));
+- tmp.set_type_autocache_b (res.first, res.second);
++ tmp->set_type_autocache_b (res.first, res.second);
+ r._aggregates.push_back (tmp);
+
++ tmp = new RulesInfo;
+ res = get_int_from_rules_str(_prefs.get_string("rules-auto-dl-value", "never"));
+- tmp.set_type_dl_b (res.first, res.second);
+- r._aggregates.push_back (tmp);
+-
++ tmp->set_type_dl_b (res.first, res.second);
++ r._aggregates.push_back (tmp);
+ }
+
+ void
+@@ -1287,56 +1290,56 @@ HeaderPane :: rebuild_filter (const std:
+ f.set_type_aggregate_and ();
+
+ // entry field filter...
+- FilterInfo entry_filter;
+ if (!text.empty())
+ {
++ FilterInfo *entry_filter = new FilterInfo;
+ if (mode == SUBJECT)
+- entry_filter.set_type_text ("Subject", d);
++ entry_filter->set_type_text ("Subject", d);
+ else if (mode == AUTHOR)
+- entry_filter.set_type_text ("From", d);
++ entry_filter->set_type_text ("From", d);
+ else if (mode == MESSAGE_ID)
+- entry_filter.set_type_text ("Message-ID", d);
++ entry_filter->set_type_text ("Message-ID", d);
+ else if (mode == SUBJECT_OR_AUTHOR) {
+- FilterInfo f1, f2;
+- entry_filter.set_type_aggregate_or ();
+- f1.set_type_text ("Subject", d);
+- f2.set_type_text ("From", d);
+- entry_filter._aggregates.push_back (f1);
+- entry_filter._aggregates.push_back (f2);
++ FilterInfo *f1 = new FilterInfo, *f2 = new FilterInfo;
++ entry_filter->set_type_aggregate_or ();
++ f1->set_type_text ("Subject", d);
++ f2->set_type_text ("From", d);
++ entry_filter->_aggregates.push_back (f1);
++ entry_filter->_aggregates.push_back (f2);
+ } else if (mode == SUBJECT_OR_AUTHOR_REGEX) {
+- FilterInfo f1, f2;
+- entry_filter.set_type_aggregate_or ();
++ FilterInfo *f1 = new FilterInfo, *f2 = new FilterInfo;
++ entry_filter->set_type_aggregate_or ();
+ d.type = TextMatch::REGEX;
+- f1.set_type_text ("Subject", d);
+- f2.set_type_text ("From", d);
+- entry_filter._aggregates.push_back (f1);
+- entry_filter._aggregates.push_back (f2);
++ f1->set_type_text ("Subject", d);
++ f2->set_type_text ("From", d);
++ entry_filter->_aggregates.push_back (f1);
++ entry_filter->_aggregates.push_back (f2);
+ }
+ f._aggregates.push_back (entry_filter);
+ }
+
+ if (_action_manager.is_action_active("match-only-unread-articles")) {
+ //std::cerr << LINE_ID << " AND is unread" << std::endl;
+- FilterInfo tmp;
+- tmp.set_type_is_unread ();
++ FilterInfo *tmp = new FilterInfo;
++ tmp->set_type_is_unread ();
+ f._aggregates.push_back (tmp);
+ }
+ if (_action_manager.is_action_active("match-only-cached-articles")) {
+ //std::cerr << LINE_ID << " AND is cached" << std::endl;
+- FilterInfo tmp;
+- tmp.set_type_cached ();
++ FilterInfo *tmp = new FilterInfo;
++ tmp->set_type_cached ();
+ f._aggregates.push_back (tmp);
+ }
+ if (_action_manager.is_action_active("match-only-binary-articles")) {
+ //std::cerr << LINE_ID << " AND has an attachment" << std::endl;
+- FilterInfo tmp;
+- tmp.set_type_binary ();
++ FilterInfo *tmp = new FilterInfo;
++ tmp->set_type_binary ();
+ f._aggregates.push_back (tmp);
+ }
+ if (_action_manager.is_action_active("match-only-my-articles")) {
+ //std::cerr << LINE_ID << " AND was posted by me" << std::endl;
+- FilterInfo tmp;
+- tmp.set_type_posted_by_me ();
++ FilterInfo *tmp = new FilterInfo;
++ tmp->set_type_posted_by_me ();
+ f._aggregates.push_back (tmp);
+ }
+
+@@ -1365,7 +1368,7 @@ HeaderPane :: rebuild_filter (const std:
+
+ //for (size_t i=0; i<ranges.size(); ++i) std::cerr << LINE_ID << " range [" << ranges[i].first << "..." << ranges[i].second << "]" << std::endl;
+
+- std::deque<FilterInfo> filters;
++ FilterInfo::aggregatesp_t filters;
+ for (size_t i=0; i<ranges.size(); ++i) {
+ const range_t& range (ranges[i]);
+ const bool low_bound (range.first == INT_MIN);
+@@ -1373,22 +1376,24 @@ HeaderPane :: rebuild_filter (const std:
+ if (low_bound && hi_bound) {
+ // everything matches -- do nothing
+ } else if (hi_bound) {
+- FilterInfo tmp;
+- tmp.set_type_score_ge (range.first);
++ FilterInfo *tmp = new FilterInfo;
++ tmp->set_type_score_ge (range.first);
+ //std::cerr << LINE_ID << " AND has a score >= " << range.first << std::endl;
+ filters.push_back (tmp);
+ } else if (low_bound) {
+- FilterInfo tmp;
+- tmp.set_type_score_le (range.second);
++ FilterInfo *tmp = new FilterInfo;
++ tmp->set_type_score_le (range.second);
+ //std::cerr << LINE_ID << " AND has a score <= " << range.second << std::endl;
+ filters.push_back (tmp);
+ } else { // not bound on either side; need an aggregate
+- FilterInfo s, tmp;
+- s.set_type_aggregate_and ();
+- tmp.set_type_score_ge (range.first);
+- s._aggregates.push_back (tmp);
+- tmp.set_type_score_le (range.second);
+- s._aggregates.push_back (tmp);
++ FilterInfo *tmp, *s = new FilterInfo;
++ s->set_type_aggregate_and ();
++ tmp = new FilterInfo;
++ tmp->set_type_score_ge (range.first);
++ s->_aggregates.push_back (tmp);
++ tmp = new FilterInfo;
++ tmp->set_type_score_le (range.second);
++ s->_aggregates.push_back (tmp);
+ //std::cerr << LINE_ID << " AND has a in [" << range.first << "..." << range.second << ']' << std::endl;
+ filters.push_back (s);
+ }
+@@ -1396,9 +1401,9 @@ HeaderPane :: rebuild_filter (const std:
+ if (filters.size()==1) // can fit in an `and' parent
+ f._aggregates.push_back (filters[0]);
+ else if (!filters.empty()) { // needs an `or' parent
+- FilterInfo s;
+- s.set_type_aggregate_or ();
+- s._aggregates.swap (filters);
++ FilterInfo *s = new FilterInfo;
++ s->set_type_aggregate_or ();
++ s->_aggregates.swap (filters);
+ f._aggregates.push_back (s);
+ }
+ //std::cerr << LINE_ID << " number of filters: " << f._aggregates.size() << std::endl;
diff --git a/news/pan/patches/patch-pan_gui_log-ui.cc b/news/pan/patches/patch-pan_gui_log-ui.cc
new file mode 100644
index 00000000000..02b6efcd9ac
--- /dev/null
+++ b/news/pan/patches/patch-pan_gui_log-ui.cc
@@ -0,0 +1,40 @@
+$NetBSD: patch-pan_gui_log-ui.cc,v 1.3 2014/01/01 12:10:00 wiz Exp $
+
+--- pan/gui/log-ui.cc.orig 2012-06-29 22:24:54.000000000 +0000
++++ pan/gui/log-ui.cc
+@@ -61,13 +61,14 @@ namespace
+ {
+ GtkTreeIter child;
+
+- foreach_const (Log::entries_t, e.messages, lit)
++ foreach_const (Log::entries_p, e.messages, lit)
+ {
++ Log::Entry entry(**lit);
+ gtk_tree_store_prepend (myStore, &child, &iter );
+ gtk_tree_store_set (myStore, &child,
+ COL_HIDDEN, "",
+- COL_SEVERITY, (lit->severity & Log::PAN_SEVERITY_ERROR),
+- COL_DATE, (unsigned long)lit->date,
++ COL_SEVERITY, (entry.severity & Log::PAN_SEVERITY_ERROR),
++ COL_DATE, (unsigned long)entry.date,
+ COL_MESSAGE, &*lit, -1);
+ }
+ }
+@@ -157,13 +158,14 @@ namespace
+ COL_MESSAGE, &*it, -1);
+ if (!it->messages.empty())
+ {
+- foreach_const (Log::entries_t, it->messages, lit)
++ foreach_const (Log::entries_p, it->messages, lit)
+ {
++ Log::Entry entry (**lit);
+ gtk_tree_store_prepend (store, &child, &top );
+ gtk_tree_store_set (store, &child,
+ COL_HIDDEN, "",
+- COL_SEVERITY, (lit->severity & Log::PAN_SEVERITY_ERROR),
+- COL_DATE, (unsigned long)lit->date,
++ COL_SEVERITY, (entry.severity & Log::PAN_SEVERITY_ERROR),
++ COL_DATE, (unsigned long)entry.date,
+ COL_MESSAGE, &*lit, -1);
+ }
+ }
diff --git a/news/pan/patches/patch-pan_usenet-utils_filter-info.cc b/news/pan/patches/patch-pan_usenet-utils_filter-info.cc
new file mode 100644
index 00000000000..3f0923f4848
--- /dev/null
+++ b/news/pan/patches/patch-pan_usenet-utils_filter-info.cc
@@ -0,0 +1,51 @@
+$NetBSD: patch-pan_usenet-utils_filter-info.cc,v 1.3 2014/01/01 12:10:00 wiz Exp $
+
+--- pan/usenet-utils/filter-info.cc.orig 2013-12-21 12:32:25.000000000 +0000
++++ pan/usenet-utils/filter-info.cc
+@@ -38,6 +38,8 @@ FilterInfo :: clear ()
+ _ge = 0;
+ _header.clear ();
+ _text.clear ();
++ foreach (aggregatesp_t, _aggregates, it)
++ delete *it;
+ _aggregates.clear ();
+ _negate = false;
+ _needs_body = false;
+@@ -284,29 +286,29 @@ FilterInfo :: describe () const
+ {
+ ret = _("Any of these tests fail:");
+ ret += "\n";
+- foreach_const (aggregates_t, _aggregates, it)
+- ret += " " + it->describe() + "\n";
++ foreach_const (aggregatesp_t, _aggregates, it)
++ ret += " " + (*it)->describe() + "\n";
+ }
+ else if (_type==AGGREGATE_AND)
+ {
+ ret = _("All of these tests pass:");
+ ret += "\n";
+- foreach_const (aggregates_t, _aggregates, it)
+- ret += " " + it->describe() + "\n";
++ foreach_const (aggregatesp_t, _aggregates, it)
++ ret += " " + (*it)->describe() + "\n";
+ }
+ else if (_type==AGGREGATE_OR && _negate)
+ {
+ ret = _("None of these tests pass:");
+ ret += "\n";
+- foreach_const (aggregates_t, _aggregates, it)
+- ret += " " + it->describe() + "\n";
++ foreach_const (aggregatesp_t, _aggregates, it)
++ ret += " " + (*it)->describe() + "\n";
+ }
+ else if (_type==AGGREGATE_OR)
+ {
+ ret = _("Any of these tests pass:");
+ ret += "\n";
+- foreach_const (aggregates_t, _aggregates, it)
+- ret += " " + it->describe() + "\n";
++ foreach_const (aggregatesp_t, _aggregates, it)
++ ret += " " + (*it)->describe() + "\n";
+ }
+
+ return ret;
diff --git a/news/pan/patches/patch-pan_usenet-utils_filter-info.h b/news/pan/patches/patch-pan_usenet-utils_filter-info.h
new file mode 100644
index 00000000000..5f95188ce03
--- /dev/null
+++ b/news/pan/patches/patch-pan_usenet-utils_filter-info.h
@@ -0,0 +1,30 @@
+$NetBSD: patch-pan_usenet-utils_filter-info.h,v 1.3 2014/01/01 12:10:00 wiz Exp $
+
+--- pan/usenet-utils/filter-info.h.orig 2013-12-21 12:30:49.000000000 +0000
++++ pan/usenet-utils/filter-info.h
+@@ -55,7 +55,10 @@ namespace pan
+ public:
+ bool empty() const { return _type == TYPE_ERR; }
+ FilterInfo () { clear(); }
+- virtual ~FilterInfo () { }
++ virtual ~FilterInfo () {
++ foreach (aggregatesp_t, _aggregates, it)
++ delete *it;
++ }
+
+ public:
+
+@@ -73,11 +76,11 @@ namespace pan
+ TextMatch _text;
+
+ /** Convenience typedef. */
+- typedef std::deque<FilterInfo> aggregates_t;
++ typedef std::deque<FilterInfo *> aggregatesp_t;
+
+ /** When `_type' is AGGREGATE_OR or AGGREGATE_AND,
+ these are the filters being or'ed or and'ed together. */
+- aggregates_t _aggregates;
++ aggregatesp_t _aggregates;
+
+ /** When this is true, the results of the test should be negated. */
+ bool _negate;
diff --git a/news/pan/patches/patch-pan_usenet-utils_rules-info.h b/news/pan/patches/patch-pan_usenet-utils_rules-info.h
new file mode 100644
index 00000000000..9de90123863
--- /dev/null
+++ b/news/pan/patches/patch-pan_usenet-utils_rules-info.h
@@ -0,0 +1,18 @@
+$NetBSD: patch-pan_usenet-utils_rules-info.h,v 1.3 2014/01/01 12:10:00 wiz Exp $
+
+--- pan/usenet-utils/rules-info.h.orig 2013-12-21 12:31:57.000000000 +0000
++++ pan/usenet-utils/rules-info.h
+@@ -54,11 +54,11 @@ namespace pan
+ virtual ~RulesInfo () { }
+
+ /** Convenience typedef. */
+- typedef std::deque<RulesInfo> aggregates_t;
++ typedef std::deque<RulesInfo *> aggregatesp_t;
+
+ /** When `_type' is AGGREGATE_OR or AGGREGATE_AND,
+ these are the filters being or'ed or and'ed together. */
+- aggregates_t _aggregates;
++ aggregatesp_t _aggregates;
+
+ /** When this is true, the results of the test should be negated. */
+ bool _negate;
diff --git a/news/pan/patches/patch-pan_usenet-utils_scorefile.cc b/news/pan/patches/patch-pan_usenet-utils_scorefile.cc
new file mode 100644
index 00000000000..d5c6959509e
--- /dev/null
+++ b/news/pan/patches/patch-pan_usenet-utils_scorefile.cc
@@ -0,0 +1,96 @@
+$NetBSD: patch-pan_usenet-utils_scorefile.cc,v 1.3 2014/01/01 12:10:00 wiz Exp $
+
+--- pan/usenet-utils/scorefile.cc.orig 2013-12-21 12:33:23.000000000 +0000
++++ pan/usenet-utils/scorefile.cc
+@@ -103,7 +103,7 @@ struct pan::Scorefile::ParseContext
+ test = &item->test;
+ if (test)
+ foreach_const (std::vector<int>, test_offsets, it)
+- test = &test->_aggregates[*it];
++ test = test->_aggregates[*it];
+ return test;
+ }
+
+@@ -258,11 +258,11 @@ Scorefile :: parse_file (ParseContext& c
+
+ line.eat_chars (1); // skip past the '{'
+ const bool only_one_test_must_pass (line.len>=2 && !memcmp(line.str,"::",2));
+- FilterInfo test;
++ FilterInfo *test = new FilterInfo;
+ if (only_one_test_must_pass)
+- test.set_type_aggregate_or ();
++ test->set_type_aggregate_or ();
+ else
+- test.set_type_aggregate_and ();
++ test->set_type_aggregate_and ();
+
+ FilterInfo * parent (context.get_current_test ());
+ context.test_offsets.push_back (parent->_aggregates.size());
+@@ -331,9 +331,9 @@ Scorefile :: parse_file (ParseContext& c
+ StringView val (line.substr (delimiter+1, 0));
+ val.trim ();
+
+- FilterInfo::aggregates_t& aggregates (context.get_current_test()->_aggregates);
++ FilterInfo::aggregatesp_t& aggregates (context.get_current_test()->_aggregates);
+ aggregates.resize (aggregates.size() + 1);
+- FilterInfo& test (aggregates.back());
++ FilterInfo* test (aggregates.back());
+
+ if (!key.strncasecmp ("Lines", 5))
+ {
+@@ -341,26 +341,26 @@ Scorefile :: parse_file (ParseContext& c
+ // "~Lines: 5" matches articles with <= 5 lines.
+ const unsigned long gt = strtoul (val.str, NULL, 10);
+ const unsigned long ge = gt + 1;
+- test.set_type_line_count_ge (ge);
++ test->set_type_line_count_ge (ge);
+ }
+ else if (!key.strncasecmp("Bytes", 5))
+ {
+ // bytes works the same way as lines.
+ const unsigned long gt = strtoul (val.str, NULL, 10);
+ const unsigned long ge = gt + 1;
+- test.set_type_byte_count_ge (ge);
++ test->set_type_byte_count_ge (ge);
+ }
+ else if (!key.strncasecmp ("Age", 3))
+ {
+ // age works differently from Lines and Bytes:
+ // "Age: 7" matches articles <= 7 days old.
+ const unsigned long le = strtoul (val.str, NULL, 10);
+- test.set_type_days_old_le (le);
++ test->set_type_days_old_le (le);
+ negate = !negate; // double negative: le is a negate state
+ }
+ else if (!key.strncasecmp ("Has-Body", 8))
+ {
+- test.set_type_cached ();
++ test->set_type_cached ();
+ if (val == "0")
+ negate = !negate;
+ }
+@@ -370,9 +370,9 @@ Scorefile :: parse_file (ParseContext& c
+ d.type = TextMatch::REGEX;
+ d.case_sensitive = case_sensitive;
+ d.text.assign (val.str, val.len);
+- test.set_type_text (key, d);
++ test->set_type_text (key, d);
+ }
+- test._negate = negate;
++ test->_negate = negate;
+ }
+
+ // error
+@@ -396,9 +396,9 @@ namespace
+ return;
+
+ if (test._aggregates.size() == 1)
+- test = test._aggregates[0];
+- else foreach (FilterInfo::aggregates_t, test._aggregates, it)
+- normalize_test (*it);
++ test = *test._aggregates[0];
++ else foreach (FilterInfo::aggregatesp_t, test._aggregates, it)
++ normalize_test (**it);
+ }
+ }
+